diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go index 26341c43001..4f6ef9a3f26 100644 --- a/src/runtime/export_test.go +++ b/src/runtime/export_test.go @@ -551,8 +551,11 @@ func MapNextArenaHint() (start, end uintptr, ok bool) { return } -func GetNextArenaHint() uintptr { - return mheap_.arenaHints.addr +func NextArenaHint() (uintptr, bool) { + if mheap_.arenaHints == nil { + return 0, false + } + return mheap_.arenaHints.addr, true } type G = g diff --git a/src/runtime/malloc_test.go b/src/runtime/malloc_test.go index 97cf0eed54c..b76b0a02acf 100644 --- a/src/runtime/malloc_test.go +++ b/src/runtime/malloc_test.go @@ -664,10 +664,24 @@ func TestArenaCollision(t *testing.T) { } t.Logf("reserved [%#x, %#x)", start, end) disallowed = append(disallowed, [2]uintptr{start, end}) + + hint, ok := NextArenaHint() + if !ok { + // We're out of arena hints. There's not much we can do now except give up. + // This might happen for a number of reasons, like if there's just something + // else already mapped in the address space where we put our hints. This is + // a bit more common than it used to be thanks to heap base randomization. + t.Skip("ran out of arena hints") + } + // Allocate until the runtime tries to use the hint we // just mapped over. - hint := GetNextArenaHint() - for GetNextArenaHint() == hint { + for { + if next, ok := NextArenaHint(); !ok { + t.Skip("ran out of arena hints") + } else if next != hint { + break + } ac := new(acLink) arenaCollisionSink = append(arenaCollisionSink, ac) // The allocation must not have fallen into