From 6f1216234003a549e71103ab9794c4630f52aafd Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 14 Mar 2024 16:40:34 -0400 Subject: [PATCH] runtime: fixes to traceback_system_test.go Minor cleanups to CL 561635's test for better debuggability when it crashes. In a separate CL so that it's clear this CL is not changing the code under test. Change-Id: I12b72ae538f8454b5c382127eafd766c22c69b67 Reviewed-on: https://go-review.googlesource.com/c/go/+/571799 Reviewed-by: Cherry Mui Reviewed-by: Alan Donovan LUCI-TryBot-Result: Go LUCI --- src/runtime/traceback_system_test.go | 64 +++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/src/runtime/traceback_system_test.go b/src/runtime/traceback_system_test.go index 223d78a808..5131e44e64 100644 --- a/src/runtime/traceback_system_test.go +++ b/src/runtime/traceback_system_test.go @@ -32,19 +32,53 @@ func crash() { go func() { // This call is typically inlined. - child() + child1() }() select {} } -func child() { - grandchild() +func child1() { + child2() } -func grandchild() { +func child2() { + child3() +} + +func child3() { + child4() +} + +func child4() { + child5() +} + +//go:noinline +func child5() { // test trace through second of two call instructions + child6bad() + child6() // appears in stack trace +} + +//go:noinline +func child6bad() { +} + +//go:noinline +func child6() { // test trace through first of two call instructions + child7() // appears in stack trace + child7bad() +} + +//go:noinline +func child7bad() { +} + +//go:noinline +func child7() { // Write runtime.Caller's view of the stack to stderr, for debugging. var pcs [16]uintptr n := runtime.Callers(1, pcs[:]) + fmt.Fprintf(os.Stderr, "Callers: %#x\n", pcs[:n]) io.WriteString(os.Stderr, formatStack(pcs[:n])) // Cause the crash report to be written to stdout. @@ -73,10 +107,12 @@ func TestTracebackSystem(t *testing.T) { } cmd := testenv.Command(t, exe) cmd.Env = append(cmd.Environ(), entrypointVar+"=crash") - cmd.Stdout = new(strings.Builder) - // cmd.Stderr = os.Stderr // uncomment to debug, e.g. to see runtime.Caller's view + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr cmd.Run() // expected to crash - crash := cmd.Stdout.(*strings.Builder).String() + t.Logf("stderr:\n%s\nstdout: %s\n", stderr.Bytes(), stdout.Bytes()) + crash := stdout.String() // If the only line is the sentinel, it wasn't a crash. if strings.Count(crash, "\n") < 2 { @@ -92,10 +128,16 @@ func TestTracebackSystem(t *testing.T) { // Unwind the stack using this executable's symbol table. got := formatStack(pcs) want := `redacted.go:0: runtime.gopanic -traceback_system_test.go:51: runtime_test.grandchild: panic("oops") -traceback_system_test.go:41: runtime_test.child: grandchild() -traceback_system_test.go:35: runtime_test.crash.func1: child() -redacted.go:0: runtime.goexit` +traceback_system_test.go:85: runtime_test.child7: panic("oops") +traceback_system_test.go:68: runtime_test.child6: child7() // appears in stack trace +traceback_system_test.go:59: runtime_test.child5: child6() // appears in stack trace +traceback_system_test.go:53: runtime_test.child4: child5() +traceback_system_test.go:49: runtime_test.child3: child4() +traceback_system_test.go:45: runtime_test.child2: child3() +traceback_system_test.go:41: runtime_test.child1: child2() +traceback_system_test.go:35: runtime_test.crash.func1: child1() +redacted.go:0: runtime.goexit +` if strings.TrimSpace(got) != strings.TrimSpace(want) { t.Errorf("got:\n%swant:\n%s", got, want) } -- 2.50.0