Skip to content

Commit 0c02bc0

Browse files
aclementsrsc
authored andcommitted
runtime: show panics in traceback
We used to include panic calls in tracebacks; however, when runtime.panic was renamed to runtime.gopanic in the conversion of the runtime to Go, we missed the special case in showframe that includes panic calls even though they're in package runtime. Fix the function name check in showframe (and, while we're here, fix the other check for "runtime.panic" in runtime/pprof). Since the "runtime.gopanic" name doesn't match what users call panic and hence isn't very user-friendly, make traceback rewrite it to just "panic". Updates #5832, #13857. Fixes #14315. Change-Id: I8059621b41ec043e63d5cfb4cbee479f47f64973 Reviewed-on: https://go-review.googlesource.com/19492 Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Russ Cox <[email protected]>
1 parent 095c0e5 commit 0c02bc0

File tree

4 files changed

+46
-5
lines changed

4 files changed

+46
-5
lines changed

src/runtime/crash_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,22 @@ func TestNetpollDeadlock(t *testing.T) {
317317
t.Fatalf("output does not start with %q:\n%s", want, output)
318318
}
319319
}
320+
321+
func TestPanicTraceback(t *testing.T) {
322+
output := runTestProg(t, "testprog", "PanicTraceback")
323+
want := "panic: hello"
324+
if !strings.HasPrefix(output, want) {
325+
t.Fatalf("output does not start with %q:\n%s", want, output)
326+
}
327+
328+
// Check functions in the traceback.
329+
fns := []string{"panic", "main.pt1.func1", "panic", "main.pt2.func1", "panic", "main.pt2", "main.pt1"}
330+
for _, fn := range fns {
331+
re := regexp.MustCompile(`(?m)^` + regexp.QuoteMeta(fn) + `\(.*\n`)
332+
idx := re.FindStringIndex(output)
333+
if idx == nil {
334+
t.Fatalf("expected %q function in traceback:\n%s", fn, output)
335+
}
336+
output = output[idx[1]:]
337+
}
338+
}

src/runtime/pprof/pprof.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
346346
name := f.Name()
347347
// Hide runtime.goexit and any runtime functions at the beginning.
348348
// This is useful mainly for allocation traces.
349-
wasPanic = name == "runtime.panic"
349+
wasPanic = name == "runtime.gopanic"
350350
if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") {
351351
continue
352352
}

src/runtime/testdata/testprog/deadlock.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func init() {
2929
register("GoexitInPanic", GoexitInPanic)
3030
register("PanicAfterGoexit", PanicAfterGoexit)
3131
register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit)
32-
32+
register("PanicTraceback", PanicTraceback)
3333
}
3434

3535
func SimpleDeadlock() {
@@ -171,3 +171,21 @@ func RecoveredPanicAfterGoexit() {
171171
}()
172172
runtime.Goexit()
173173
}
174+
175+
func PanicTraceback() {
176+
pt1()
177+
}
178+
179+
func pt1() {
180+
defer func() {
181+
panic("panic pt1")
182+
}()
183+
pt2()
184+
}
185+
186+
func pt2() {
187+
defer func() {
188+
panic("panic pt2")
189+
}()
190+
panic("hello")
191+
}

src/runtime/traceback.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,11 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
380380
if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry && !waspanic {
381381
tracepc--
382382
}
383-
print(funcname(f), "(")
383+
name := funcname(f)
384+
if name == "runtime.gopanic" {
385+
name = "panic"
386+
}
387+
print(name, "(")
384388
argp := (*[100]uintptr)(unsafe.Pointer(frame.argp))
385389
for i := uintptr(0); i < frame.arglen/sys.PtrSize; i++ {
386390
if i >= 10 {
@@ -617,10 +621,10 @@ func showframe(f *_func, gp *g) bool {
617621
level, _, _ := gotraceback()
618622
name := funcname(f)
619623

620-
// Special case: always show runtime.panic frame, so that we can
624+
// Special case: always show runtime.gopanic frame, so that we can
621625
// see where a panic started in the middle of a stack trace.
622626
// See golang.org/issue/5832.
623-
if name == "runtime.panic" {
627+
if name == "runtime.gopanic" {
624628
return true
625629
}
626630

0 commit comments

Comments
 (0)