]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: skip TestArenaCollision on failed reservation
authorAustin Clements <austin@google.com>
Tue, 1 Nov 2022 14:00:25 +0000 (10:00 -0400)
committerAustin Clements <austin@google.com>
Tue, 1 Nov 2022 17:06:23 +0000 (17:06 +0000)
If TestArenaCollision cannot reserve the address range it expects to
reserve, it currently fails somewhat mysteriously. Detect this case
and skip the test. This could lead to test rot if we wind up always
skipping this test, but it's not clear that there's a better answer.
If the test does fail, we now also log what it thinks it reserved so
the failure message is more useful in debugging any issues.

Fixes #49415
Fixes #54597

Change-Id: I05cf27258c1c0a7a3ac8d147f36bf8890820d59b
Reviewed-on: https://go-review.googlesource.com/c/go/+/446877
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/runtime/export_test.go
src/runtime/malloc_test.go

index 8e0a57987fb38e1da8f369941aacfe44ff7ed013..bc1b3353e5add8af8fb99ab1b1547bbb22f49270 100644 (file)
@@ -503,7 +503,10 @@ func KeepNArenaHints(n int) {
 // MapNextArenaHint reserves a page at the next arena growth hint,
 // preventing the arena from growing there, and returns the range of
 // addresses that are no longer viable.
-func MapNextArenaHint() (start, end uintptr) {
+//
+// This may fail to reserve memory. If it fails, it still returns the
+// address range it attempted to reserve.
+func MapNextArenaHint() (start, end uintptr, ok bool) {
        hint := mheap_.arenaHints
        addr := hint.addr
        if hint.down {
@@ -512,7 +515,13 @@ func MapNextArenaHint() (start, end uintptr) {
        } else {
                start, end = addr, addr+heapArenaBytes
        }
-       sysReserve(unsafe.Pointer(addr), physPageSize)
+       got := sysReserve(unsafe.Pointer(addr), physPageSize)
+       ok = (addr == uintptr(got))
+       if !ok {
+               // We were unable to get the requested reservation.
+               // Release what we did get and fail.
+               sysFreeOS(got, physPageSize)
+       }
        return
 }
 
index cc2007604ddb6f5ea42c2b32071ee67094e36842..a13f382172132a46d9ca89add21b84554fcbb5d6 100644 (file)
@@ -294,7 +294,11 @@ func TestArenaCollision(t *testing.T) {
        for i := 0; i < 5; i++ {
                // Reserve memory at the next hint so it can't be used
                // for the heap.
-               start, end := MapNextArenaHint()
+               start, end, ok := MapNextArenaHint()
+               if !ok {
+                       t.Skipf("failed to reserve memory at next arena hint [%#x, %#x)", start, end)
+               }
+               t.Logf("reserved [%#x, %#x)", start, end)
                disallowed = append(disallowed, [2]uintptr{start, end})
                // Allocate until the runtime tries to use the hint we
                // just mapped over.