diff options
Diffstat (limited to 'src/pkg/runtime/crash_test.go')
-rw-r--r-- | src/pkg/runtime/crash_test.go | 83 |
1 files changed, 69 insertions, 14 deletions
diff --git a/src/pkg/runtime/crash_test.go b/src/pkg/runtime/crash_test.go index 929d4a963..5476924bb 100644 --- a/src/pkg/runtime/crash_test.go +++ b/src/pkg/runtime/crash_test.go @@ -14,7 +14,7 @@ import ( "text/template" ) -// testEnv excludes GOGCTRACE from the environment +// testEnv excludes GODEBUG from the environment // to prevent its output from breaking tests that // are trying to parse other command output. func testEnv(cmd *exec.Cmd) *exec.Cmd { @@ -22,7 +22,7 @@ func testEnv(cmd *exec.Cmd) *exec.Cmd { panic("environment already set") } for _, env := range os.Environ() { - if strings.HasPrefix(env, "GOGCTRACE=") { + if strings.HasPrefix(env, "GODEBUG=") { continue } cmd.Env = append(cmd.Env, env) @@ -44,14 +44,16 @@ func executeTest(t *testing.T, templ string, data interface{}) string { src := filepath.Join(dir, "main.go") f, err := os.Create(src) if err != nil { - t.Fatalf("failed to create %v: %v", src, err) + t.Fatalf("failed to create file: %v", err) } err = st.Execute(f, data) if err != nil { f.Close() t.Fatalf("failed to execute template: %v", err) } - f.Close() + if err := f.Close(); err != nil { + t.Fatalf("failed to close file: %v", err) + } got, _ := testEnv(exec.Command("go", "run", src)).CombinedOutput() return string(got) @@ -72,10 +74,10 @@ func testCrashHandler(t *testing.T, cgo bool) { type crashTest struct { Cgo bool } - got := executeTest(t, crashSource, &crashTest{Cgo: cgo}) + output := executeTest(t, crashSource, &crashTest{Cgo: cgo}) want := "main: recovered done\nnew-thread: recovered done\nsecond-new-thread: recovered done\nmain-again: recovered done\n" - if got != want { - t.Fatalf("expected %q, but got %q", want, got) + if output != want { + t.Fatalf("output:\n%s\n\nwanted:\n%s", output, want) } } @@ -84,10 +86,10 @@ func TestCrashHandler(t *testing.T) { } func testDeadlock(t *testing.T, source string) { - got := executeTest(t, source, nil) + output := executeTest(t, source, nil) want := "fatal error: all goroutines are asleep - deadlock!\n" - if !strings.HasPrefix(got, want) { - t.Fatalf("expected %q, but got %q", want, got) + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) } } @@ -108,10 +110,25 @@ func TestLockedDeadlock2(t *testing.T) { } func TestGoexitDeadlock(t *testing.T) { - got := executeTest(t, goexitDeadlockSource, nil) - want := "" - if got != want { - t.Fatalf("expected %q, but got %q", want, got) + output := executeTest(t, goexitDeadlockSource, nil) + if output != "" { + t.Fatalf("expected no output, got:\n%s", output) + } +} + +func TestStackOverflow(t *testing.T) { + output := executeTest(t, stackOverflowSource, nil) + want := "runtime: goroutine stack exceeds 4194304-byte limit\nfatal error: stack overflow" + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) + } +} + +func TestThreadExhaustion(t *testing.T) { + output := executeTest(t, threadExhaustionSource, nil) + want := "runtime: program exceeds 10-thread limit\nfatal error: thread exhaustion" + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) } } @@ -217,3 +234,41 @@ func main() { runtime.Goexit() } ` + +const stackOverflowSource = ` +package main + +import "runtime/debug" + +func main() { + debug.SetMaxStack(4<<20) + f(make([]byte, 10)) +} + +func f(x []byte) byte { + var buf [64<<10]byte + return x[0] + f(buf[:]) +} +` + +const threadExhaustionSource = ` +package main + +import ( + "runtime" + "runtime/debug" +) + +func main() { + debug.SetMaxThreads(10) + c := make(chan int) + for i := 0; i < 100; i++ { + go func() { + runtime.LockOSThread() + c <- 0 + select{} + }() + <-c + } +} +` |