]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: stop when we run out of hints in race mode
authorAustin Clements <austin@google.com>
Wed, 4 Apr 2018 16:54:47 +0000 (12:54 -0400)
committerAustin Clements <austin@google.com>
Wed, 4 Apr 2018 18:08:04 +0000 (18:08 +0000)
Currently, the runtime falls back to asking for any address the OS can
offer for the heap when it runs out of hint addresses. However, the
race detector assumes the heap lives in [0x00c000000000,
0x00e000000000), and will fail in a non-obvious way if we go outside
this region.

Fix this by actively throwing a useful error if we run out of heap
hints in race mode.

This problem is currently being triggered by TestArenaCollision, which
intentionally triggers this fallback behavior. Fix the test to look
for the new panic message in race mode.

Fixes #24670.
Updates #24133.

Change-Id: I57de6d17a3495dc1f1f84afc382cd18a6efc2bf7
Reviewed-on: https://go-review.googlesource.com/104717
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/malloc.go
src/runtime/malloc_test.go

index 6e04f50e1d96f271f41c185e2ead7dd44b25794f..5738a96a87969352d37b47888d7c4f4996a23802 100644 (file)
@@ -557,6 +557,14 @@ func (h *mheap) sysAlloc(n uintptr) (v unsafe.Pointer, size uintptr) {
        }
 
        if size == 0 {
+               if raceenabled {
+                       // The race detector assumes the heap lives in
+                       // [0x00c000000000, 0x00e000000000), but we
+                       // just ran out of hints in this region. Give
+                       // a nice failure.
+                       throw("too many address space collisions for -race mode")
+               }
+
                // All of the hints failed, so we'll take any
                // (sufficiently aligned) address the kernel will give
                // us.
index 854533f2380241231dcc31bf5473058e27828320..0bce059f7f7d25cea411ebc5c370fda1a8c84357 100644 (file)
@@ -7,6 +7,7 @@ package runtime_test
 import (
        "flag"
        "fmt"
+       "internal/race"
        "internal/testenv"
        "os"
        "os/exec"
@@ -170,7 +171,17 @@ func TestArenaCollision(t *testing.T) {
        if os.Getenv("TEST_ARENA_COLLISION") != "1" {
                cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestArenaCollision", "-test.v"))
                cmd.Env = append(cmd.Env, "TEST_ARENA_COLLISION=1")
-               if out, err := cmd.CombinedOutput(); !strings.Contains(string(out), "PASS\n") || err != nil {
+               out, err := cmd.CombinedOutput()
+               if race.Enabled {
+                       // This test runs the runtime out of hint
+                       // addresses, so it will start mapping the
+                       // heap wherever it can. The race detector
+                       // doesn't support this, so look for the
+                       // expected failure.
+                       if want := "too many address space collisions"; !strings.Contains(string(out), want) {
+                               t.Fatalf("want %q, got:\n%s", want, string(out))
+                       }
+               } else if !strings.Contains(string(out), "PASS\n") || err != nil {
                        t.Fatalf("%s\n(exit status %v)", string(out), err)
                }
                return