mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 #75502 Change-Id: Iacc445b2905824f9f71970c7abd33f187793cf39 Reviewed-on: https://go-review.googlesource.com/c/go/+/704855 Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Roland Shoemaker <roland@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
909704b85e
commit
465b85eb76
1 changed files with 31 additions and 10 deletions
|
|
@ -1122,8 +1122,6 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
|
|||
// Lock so that we can safely access the bitmap.
|
||||
lock(&mheap_.lock)
|
||||
|
||||
heapBase := mheap_.pages.inUse.ranges[0].base.addr()
|
||||
secondArenaBase := arenaBase(arenaIndex(heapBase) + 1)
|
||||
chunkLoop:
|
||||
for i := mheap_.pages.start; i < mheap_.pages.end; i++ {
|
||||
chunk := mheap_.pages.tryChunkOf(i)
|
||||
|
|
@ -1140,14 +1138,6 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
|
|||
want := chunk.scavenged[j] &^ chunk.pallocBits[j]
|
||||
got := chunk.scavenged[j]
|
||||
if want != got {
|
||||
// When goexperiment.RandomizedHeapBase64 is set we use a
|
||||
// series of padding pages to generate randomized heap base
|
||||
// address which have both the alloc and scav bits set. If
|
||||
// we see this for a chunk between the address of the heap
|
||||
// base, and the address of the second arena continue.
|
||||
if goexperiment.RandomizedHeapBase64 && (cb >= heapBase && cb < secondArenaBase) {
|
||||
continue
|
||||
}
|
||||
ok = false
|
||||
if n >= len(mismatches) {
|
||||
break chunkLoop
|
||||
|
|
@ -1165,6 +1155,37 @@ func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) {
|
|||
|
||||
getg().m.mallocing--
|
||||
})
|
||||
|
||||
if goexperiment.RandomizedHeapBase64 && len(mismatches) > 0 {
|
||||
// When goexperiment.RandomizedHeapBase64 is set we use a series of
|
||||
// padding pages to generate randomized heap base address which have
|
||||
// both the alloc and scav bits set. Because of this we expect exactly
|
||||
// one arena will have mismatches, so check for that explicitly and
|
||||
// remove the mismatches if that property holds. If we see more than one
|
||||
// arena with this property, that is an indication something has
|
||||
// actually gone wrong, so return the mismatches.
|
||||
//
|
||||
// We do this, instead of ignoring the mismatches in the chunkLoop, because
|
||||
// it's not easy to determine which arena we added the padding pages to
|
||||
// programmatically, without explicitly recording the base address somewhere
|
||||
// in a global variable (which we'd rather not do as the address of that variable
|
||||
// is likely to be somewhat predictable, potentially defeating the purpose
|
||||
// of our randomization).
|
||||
affectedArenas := map[arenaIdx]bool{}
|
||||
for _, mismatch := range mismatches {
|
||||
if mismatch.Base > 0 {
|
||||
affectedArenas[arenaIndex(mismatch.Base)] = true
|
||||
}
|
||||
}
|
||||
if len(affectedArenas) == 1 {
|
||||
ok = true
|
||||
// zero the mismatches
|
||||
for i := range n {
|
||||
mismatches[i] = BitsMismatch{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue