Skip to content

Commit

Permalink
proc: fix stacktrace frame after runtime.sigpanic (#3638)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
aarzilli authored Jan 18, 2024
1 parent 8838065 commit 4ed69d0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
8 changes: 8 additions & 0 deletions _fixtures/panicline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package main

import "os"

func main() {
fi, _ := os.Lstat("/this/path/does/not/exist")
fi.Size()
}
25 changes: 25 additions & 0 deletions pkg/proc/proc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
})
}
4 changes: 3 additions & 1 deletion pkg/proc/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ type stackIterator struct {
pc uint64
top bool
atend bool
sigret bool
frame Stackframe
target *Target
bi *BinaryInfo
Expand Down Expand Up @@ -270,6 +271,7 @@ func (it *stackIterator) Next() bool {
return true
}

it.sigret = it.frame.Current.Fn != nil && it.frame.Current.Fn.Name == "runtime.sigpanic"
it.top = false
it.pc = it.frame.Ret
it.regs = callFrameRegs
Expand Down Expand Up @@ -329,7 +331,7 @@ func (it *stackIterator) newStackframe(ret, retaddr uint64) Stackframe {
r.Regs.AddReg(it.regs.PCRegNum, op.DwarfRegisterFromUint64(it.pc))
}
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
// contains it then this is some kind of fake return frame (for example
// runtime.sigreturn) that didn't actually call the current frame,
Expand Down

0 comments on commit 4ed69d0

Please sign in to comment.