Skip to content

Commit 465b85e

Browse files
rolandshoemakergopherbot
authored andcommitted
runtime: fix CheckScavengedBitsCleared with randomized heap base
We cannot easily determine the base address of the arena we added the random padding pages to, which can cause confusing TestScavengedBitsCleared failures when the arena we padded does not have the lowest address of all of the arenas. Instead of attempting to determine the correct arena to ignore when checking the scav and alloc bits, switch to just tolerating _one_ arena having mismatches, which is expected when randomizedHeapBase64 is enabled. Any other number of arenas having mismatches is likely a real error. Fixes golang#75502 Change-Id: Iacc445b2905824f9f71970c7abd33f187793cf39 Reviewed-on: https://go-review.googlesource.com/c/go/+/704855 Reviewed-by: Michael Knyszek <[email protected]> Auto-Submit: Roland Shoemaker <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 909704b commit 465b85e

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

src/runtime/export_test.go

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,8 +1122,6 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
11221122
// Lock so that we can safely access the bitmap.
11231123
lock(&mheap_.lock)
11241124

1125-
heapBase := mheap_.pages.inUse.ranges[0].base.addr()
1126-
secondArenaBase := arenaBase(arenaIndex(heapBase) + 1)
11271125
chunkLoop:
11281126
for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
11291127
chunk := mheap_.pages.tryChunkOf(i)
@@ -1140,14 +1138,6 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
11401138
want := chunk.scavenged[j] &^ chunk.pallocBits[j]
11411139
got := chunk.scavenged[j]
11421140
if want != got {
1143-
// When goexperiment.RandomizedHeapBase64 is set we use a
1144-
// series of padding pages to generate randomized heap base
1145-
// address which have both the alloc and scav bits set. If
1146-
// we see this for a chunk between the address of the heap
1147-
// base, and the address of the second arena continue.
1148-
if goexperiment.RandomizedHeapBase64 && (cb >= heapBase && cb < secondArenaBase) {
1149-
continue
1150-
}
11511141
ok = false
11521142
if n >= len(mismatches) {
11531143
break chunkLoop
@@ -1165,6 +1155,37 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
11651155

11661156
getg().m.mallocing--
11671157
})
1158+
1159+
if goexperiment.RandomizedHeapBase64 && len(mismatches) > 0 {
1160+
// When goexperiment.RandomizedHeapBase64 is set we use a series of
1161+
// padding pages to generate randomized heap base address which have
1162+
// both the alloc and scav bits set. Because of this we expect exactly
1163+
// one arena will have mismatches, so check for that explicitly and
1164+
// remove the mismatches if that property holds. If we see more than one
1165+
// arena with this property, that is an indication something has
1166+
// actually gone wrong, so return the mismatches.
1167+
//
1168+
// We do this, instead of ignoring the mismatches in the chunkLoop, because
1169+
// it's not easy to determine which arena we added the padding pages to
1170+
// programmatically, without explicitly recording the base address somewhere
1171+
// in a global variable (which we'd rather not do as the address of that variable
1172+
// is likely to be somewhat predictable, potentially defeating the purpose
1173+
// of our randomization).
1174+
affectedArenas := map[arenaIdx]bool{}
1175+
for _, mismatch := range mismatches {
1176+
if mismatch.Base > 0 {
1177+
affectedArenas[arenaIndex(mismatch.Base)] = true
1178+
}
1179+
}
1180+
if len(affectedArenas) == 1 {
1181+
ok = true
1182+
// zero the mismatches
1183+
for i := range n {
1184+
mismatches[i] = BitsMismatch{}
1185+
}
1186+
}
1187+
}
1188+
11681189
return
11691190
}
11701191

0 commit comments

Comments
 (0)