From 318309a51f40d31568bd2c9131d1cd25c2ca0214 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 15 Feb 2013 14:27:16 -0500 Subject: [PATCH] runtime/pprof: adjust reported line numbers to show call sites This is the same logic used in the standard tracebacks. The caller pc is the pc after the call, so except in the fake "call" caused by a panic, back up the pc enough that the lookup will use the previous instruction. Fixes #4150. Fixes #4151. R=golang-dev, iant CC=golang-dev https://golang.org/cl/7317047 --- src/pkg/runtime/pprof/pprof.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/pkg/runtime/pprof/pprof.go b/src/pkg/runtime/pprof/pprof.go index ee81c94a25..32c1098b99 100644 --- a/src/pkg/runtime/pprof/pprof.go +++ b/src/pkg/runtime/pprof/pprof.go @@ -318,21 +318,33 @@ func printCountProfile(w io.Writer, debug int, name string, p countProfile) erro // for a single stack trace. func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) { show := allFrames - for _, pc := range stk { + wasPanic := false + for i, pc := range stk { f := runtime.FuncForPC(pc) if f == nil { show = true fmt.Fprintf(w, "#\t%#x\n", pc) + wasPanic = false } else { - file, line := f.FileLine(pc) + tracepc := pc + // Back up to call instruction. + if i > 0 && pc > f.Entry() && !wasPanic { + if runtime.GOARCH == "386" || runtime.GOARCH == "amd64" { + tracepc-- + } else { + tracepc -= 4 // arm, etc + } + } + file, line := f.FileLine(tracepc) name := f.Name() // Hide runtime.goexit and any runtime functions at the beginning. // This is useful mainly for allocation traces. + wasPanic = name == "runtime.panic" if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") { continue } show = true - fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, f.Name(), pc-f.Entry(), file, line) + fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, name, pc-f.Entry(), file, line) } } if !show { -- 2.48.1