diff options
| author | Austin Clements <austin@google.com> | 2023-03-15 14:27:10 -0400 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2023-03-15 23:53:51 +0000 |
| commit | 5f62ba621e9f1c925912f655901d0550e4a99f39 (patch) | |
| tree | 92ff7f43eb8cf2271b4151e5a3d0a9e74f404724 /src/runtime/stack_test.go | |
| parent | be27fcfd2bfeda927213f334811df794d6a45872 (diff) | |
| download | go-5f62ba621e9f1c925912f655901d0550e4a99f39.tar.xz | |
runtime: fix callee tracking in traceback printing
In CL 466099, we accidentally stopped tracking callees while unwinding
inlined frames during traceback printing. The effect is that if you
have a call stack like:
f -> wrapper -> inlined into wrapper -> panic
when considering whether to print the frame for "wrapper", we'll think
that wrapper called panic, rather than the inlined function.
Fix this in the traceback code and add a test.
Change-Id: I30ec836cc316846ce93de94e28a650e23dca184e
Reviewed-on: https://go-review.googlesource.com/c/go/+/476579
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime/stack_test.go')
| -rw-r--r-- | src/runtime/stack_test.go | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go index 24f8290f67..9a096f5538 100644 --- a/src/runtime/stack_test.go +++ b/src/runtime/stack_test.go @@ -6,6 +6,7 @@ package runtime_test import ( "fmt" + "internal/testenv" "reflect" "regexp" . "runtime" @@ -652,6 +653,8 @@ func (s structWithMethod) stack() string { func (s structWithMethod) nop() {} +func (s structWithMethod) inlinablePanic() { panic("panic") } + func TestStackWrapperCaller(t *testing.T) { var d structWithMethod // Force the compiler to construct a wrapper method. @@ -689,6 +692,33 @@ func TestStackWrapperStack(t *testing.T) { } } +func TestStackWrapperStackInlinePanic(t *testing.T) { + // Test that inline unwinding correctly tracks the callee by creating a + // stack of the form wrapper -> inlined function -> panic. If we mess up + // callee tracking, it will look like the wrapper called panic and we'll see + // the wrapper in the stack trace. + var d structWithMethod + wrapper := (*structWithMethod).inlinablePanic + defer func() { + err := recover() + if err == nil { + t.Fatalf("expected panic") + } + buf := make([]byte, 4<<10) + stk := string(buf[:Stack(buf, false)]) + if strings.Contains(stk, "<autogenerated>") { + t.Fatalf("<autogenerated> appears in stack trace:\n%s", stk) + } + // Self-check: make sure inlinablePanic got inlined. + if !testenv.OptimizationOff() { + if !strings.Contains(stk, "inlinablePanic(...)") { + t.Fatalf("inlinablePanic not inlined") + } + } + }() + wrapper(&d) +} + type I interface { M() } |
