diff options
Diffstat (limited to 'src/runtime/traceback.go')
| -rw-r--r-- | src/runtime/traceback.go | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index 1c75c447d2..61027ea89a 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -993,12 +993,24 @@ func traceback2(u *unwinder, showRuntime bool, skip, max int) (n, lastN int) { } print(")\n") print("\t", file, ":", line) - if !iu.isInlined(uf) { - if u.frame.pc > f.entry() { - print(" +", hex(u.frame.pc-f.entry())) - } - if gp.m != nil && gp.m.throwing >= throwTypeRuntime && gp == gp.m.curg || level >= 2 { - print(" fp=", hex(u.frame.fp), " sp=", hex(u.frame.sp), " pc=", hex(u.frame.pc)) + // The contract between Callers and CallersFrames uses + // return addresses, which are +1 relative to the CALL + // instruction. Follow that convention. + pc := uf.pc + 1 + if !iu.isInlined(uf) && pc > f.entry() { + // Func-relative PCs make no sense for inlined + // frames because there is no actual entry. + print(" +", hex(pc-f.entry())) + } + if gp.m != nil && gp.m.throwing >= throwTypeRuntime && gp == gp.m.curg || level >= 2 { + if !iu.isInlined(uf) { + // The stack information makes no sense for inline frames. + print(" fp=", hex(u.frame.fp), " sp=", hex(u.frame.sp), " pc=", hex(pc)) + } else { + // The PC for an inlined frame is a special marker NOP, + // but crash monitoring tools may still parse the PCs + // and feed them to CallersFrames. + print(" pc=", hex(pc)) } } print("\n") |
