1
0
mirror of https://github.com/golang/go synced 2024-11-12 09:20:22 -07:00

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
This commit is contained in:
Russ Cox 2013-02-15 14:27:16 -05:00
parent 8a6ff3ab34
commit 318309a51f

View 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 {