]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: skip TestArenaCollision if we run out of hints
authorMichael Anthony Knyszek <mknyszek@google.com>
Wed, 3 Dec 2025 23:22:18 +0000 (23:22 +0000)
committerMichael Knyszek <mknyszek@google.com>
Fri, 5 Dec 2025 19:37:02 +0000 (11:37 -0800)
This seems failure mode seems to have become more common on Windows. I
suspect the randomized heap base address has something to do with it,
but I'm not 100% sure.

What's definitely certain is that we're running out of hints, since
we're seeing failures that mheap_.arenaHints is nil and GetNextArenaHint
doesn't actually check that.

At the very least we can check that and skip. We know that in this case
there's not that much we can do.

Fixes #76566.

Change-Id: I8ccc8994806b6c95e3157eb296b09705637564b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/726527
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/runtime/export_test.go
src/runtime/malloc_test.go

index 26341c43001689ad25c15323261bf0acf04b908a..4f6ef9a3f262c4289b1f6dd9b62f94a50727381a 100644 (file)
@@ -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
index 97cf0eed54c77ceac805b00ee942f13389e69a1f..b76b0a02acf2c04b11daff19fca0dbfc3bdb09d3 100644 (file)
@@ -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