proc: fix stacktrace frame after runtime.sigpanic (#3638)
The first frame after sigpanic didn't execute a call so we shouldn't decrement the PC address to look up its location. Fixes #3634
This commit is contained in:
parent
88380654fe
commit
4ed69d0280
8
_fixtures/panicline.go
Normal file
8
_fixtures/panicline.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fi, _ := os.Lstat("/this/path/does/not/exist")
|
||||||
|
fi.Size()
|
||||||
|
}
|
@ -6121,3 +6121,28 @@ func TestIssue3545(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPanicLine(t *testing.T) {
|
||||||
|
withTestProcess("panicline", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
|
||||||
|
err := grp.Continue()
|
||||||
|
if runtime.GOOS == "darwin" && err != nil && err.Error() == "bad access" {
|
||||||
|
// not supported
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assertNoError(err, t, "Continue()")
|
||||||
|
frames, err := proc.ThreadStacktrace(p, p.CurrentThread(), 20)
|
||||||
|
assertNoError(err, t, "ThreadStacktrace")
|
||||||
|
logStacktrace(t, p, frames)
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, frame := range frames {
|
||||||
|
if strings.HasSuffix(frame.Call.File, "panicline.go") && frame.Call.Line == 7 {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("could not find panicline.go:6")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -180,6 +180,7 @@ type stackIterator struct {
|
|||||||
pc uint64
|
pc uint64
|
||||||
top bool
|
top bool
|
||||||
atend bool
|
atend bool
|
||||||
|
sigret bool
|
||||||
frame Stackframe
|
frame Stackframe
|
||||||
target *Target
|
target *Target
|
||||||
bi *BinaryInfo
|
bi *BinaryInfo
|
||||||
@ -270,6 +271,7 @@ func (it *stackIterator) Next() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it.sigret = it.frame.Current.Fn != nil && it.frame.Current.Fn.Name == "runtime.sigpanic"
|
||||||
it.top = false
|
it.top = false
|
||||||
it.pc = it.frame.Ret
|
it.pc = it.frame.Ret
|
||||||
it.regs = callFrameRegs
|
it.regs = callFrameRegs
|
||||||
@ -329,7 +331,7 @@ func (it *stackIterator) newStackframe(ret, retaddr uint64) Stackframe {
|
|||||||
r.Regs.AddReg(it.regs.PCRegNum, op.DwarfRegisterFromUint64(it.pc))
|
r.Regs.AddReg(it.regs.PCRegNum, op.DwarfRegisterFromUint64(it.pc))
|
||||||
}
|
}
|
||||||
r.Call = r.Current
|
r.Call = r.Current
|
||||||
if !it.top && r.Current.Fn != nil && it.pc != r.Current.Fn.Entry {
|
if !it.top && r.Current.Fn != nil && it.pc != r.Current.Fn.Entry && !it.sigret {
|
||||||
// if the return address is the entry point of the function that
|
// 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
|
// contains it then this is some kind of fake return frame (for example
|
||||||
// runtime.sigreturn) that didn't actually call the current frame,
|
// runtime.sigreturn) that didn't actually call the current frame,
|
||||||
|
Loading…
Reference in New Issue
Block a user