]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/pprof: adjust reported line numbers to show call sites
authorRuss Cox <rsc@golang.org>
Fri, 15 Feb 2013 19:27:16 +0000 (14:27 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 15 Feb 2013 19:27:16 +0000 (14:27 -0500)
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

index ee81c94a25b0049aeb7b3a922feebf2f0e3d26c5..32c1098b9945b0e830ca81ef14a30b328d1ca005 100644 (file)
@@ -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 {