summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-02-15 14:27:16 -0500
committerRuss Cox <rsc@golang.org>2013-02-15 14:27:16 -0500
commit095f80182deb851e1518b31d742ee8a267e6d6c3 (patch)
treec44e31815cf3faca2f7248595343f7af2be05244
parent5c398dfc0a24bac9b6da6b50909f587d0e068ad1 (diff)
downloadgo-095f80182deb851e1518b31d742ee8a267e6d6c3.tar.gz
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 issue 4150. Fixes issue 4151. R=golang-dev, iant CC=golang-dev https://codereview.appspot.com/7317047
-rw-r--r--src/pkg/runtime/pprof/pprof.go18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/pkg/runtime/pprof/pprof.go b/src/pkg/runtime/pprof/pprof.go
index ee81c94a2..32c1098b9 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 {