diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index 8f71359f..5de27fc8 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -375,36 +375,21 @@ func (it *stackIterator) newStackframe(ret, retaddr uint64) Stackframe { it.regs.FrameBase = it.frameBase(fn) } r := Stackframe{Current: Location{PC: it.pc, File: f, Line: l, Fn: fn}, Regs: it.regs, Ret: ret, addrret: retaddr, stackHi: it.stackhi, SystemStack: it.systemstack, lastpc: it.pc} - if !it.top { - fnname := "" - if r.Current.Fn != nil { - fnname = r.Current.Fn.Name - } - switch fnname { + r.Call = r.Current + if !it.top && r.Current.Fn != nil && it.pc != r.Current.Fn.Entry { + // if the return address is the entry point of the function that + // contains it then this is some kind of fake return frame (for example + // runtime.sigreturn) that didn't actually call the current frame, + // attempting to get the location of the CALL instruction would just + // obfuscate what's going on, since there is no CALL instruction. + switch r.Current.Fn.Name { case "runtime.mstart", "runtime.systemstack_switch": // these frames are inserted by runtime.systemstack and there is no CALL // instruction to look for at pc - 1 - r.Call = r.Current default: - if r.Current.Fn != nil && it.pc == r.Current.Fn.Entry { - // if the return address is the entry point of the function that - // contains it then this is some kind of fake return frame (for example - // runtime.sigreturn) that didn't actually call the current frame, - // attempting to get the location of the CALL instruction would just - // obfuscate what's going on, since there is no CALL instruction. - r.Call = r.Current - } else { - r.lastpc = it.pc - 1 - r.Call.File, r.Call.Line, r.Call.Fn = it.bi.PCToLine(it.pc - 1) - if r.Call.Fn == nil { - r.Call.File = "?" - r.Call.Line = -1 - } - r.Call.PC = r.Current.PC - } + r.lastpc = it.pc - 1 + r.Call.File, r.Call.Line = r.Current.Fn.cu.lineInfo.PCToLine(r.Current.Fn.Entry, it.pc-1) } - } else { - r.Call = r.Current } return r }