aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/stack_test.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2023-03-15 14:27:10 -0400
committerAustin Clements <austin@google.com>2023-03-15 23:53:51 +0000
commit5f62ba621e9f1c925912f655901d0550e4a99f39 (patch)
tree92ff7f43eb8cf2271b4151e5a3d0a9e74f404724 /src/runtime/stack_test.go
parentbe27fcfd2bfeda927213f334811df794d6a45872 (diff)
downloadgo-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.go30
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()
}