aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/crash_test.go30
-rw-r--r--src/runtime/panic.go2
2 files changed, 29 insertions, 3 deletions
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index 69e1034ff8..52d33b8f58 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -621,7 +621,7 @@ func TestConcurrentMapWrites(t *testing.T) {
}
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapWrites")
- want := "fatal error: concurrent map writes"
+ want := "fatal error: concurrent map writes\n"
if !strings.HasPrefix(output, want) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
@@ -632,7 +632,7 @@ func TestConcurrentMapReadWrite(t *testing.T) {
}
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapReadWrite")
- want := "fatal error: concurrent map read and map write"
+ want := "fatal error: concurrent map read and map write\n"
if !strings.HasPrefix(output, want) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
@@ -643,12 +643,36 @@ func TestConcurrentMapIterateWrite(t *testing.T) {
}
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapIterateWrite")
- want := "fatal error: concurrent map iteration and map write"
+ want := "fatal error: concurrent map iteration and map write\n"
if !strings.HasPrefix(output, want) {
t.Fatalf("output does not start with %q:\n%s", want, output)
}
}
+func TestConcurrentMapWritesIssue69447(t *testing.T) {
+ testenv.MustHaveGoRun(t)
+ exe, err := buildTestProg(t, "testprog")
+ if err != nil {
+ t.Fatal(err)
+ }
+ for i := 0; i < 200; i++ {
+ output := runBuiltTestProg(t, exe, "concurrentMapWrites")
+ if output == "" {
+ // If we didn't detect an error, that's ok.
+ // This case makes this test not flaky like
+ // the other ones above.
+ // (More correctly, this case makes this test flaky
+ // in the other direction, in that it might not
+ // detect a problem even if there is one.)
+ continue
+ }
+ want := "fatal error: concurrent map writes\n"
+ if !strings.HasPrefix(output, want) {
+ t.Fatalf("output does not start with %q:\n%s", want, output)
+ }
+ }
+}
+
type point struct {
x, y *int
}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 5b62e019d9..d70d567912 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -1081,6 +1081,7 @@ func throw(s string) {
func fatal(s string) {
// Everything fatal does should be recursively nosplit so it
// can be called even when it's unsafe to grow the stack.
+ printlock() // Prevent multiple interleaved fatal reports. See issue 69447.
systemstack(func() {
print("fatal error: ")
printindented(s) // logically printpanicval(s), but avoids convTstring write barrier
@@ -1088,6 +1089,7 @@ func fatal(s string) {
})
fatalthrow(throwTypeUser)
+ printunlock()
}
// runningPanicDefers is non-zero while running deferred functions for panic.