提交 a7718bd3 编写于 作者: A aarzilli 提交者: Derek Parker

proc: tolerate memory read errors during stacktrace

When there's a error reading the stack trace the call stack itself
could be corrupted and we should return the partial stacktrace that we
have.

Fixes #868
上级 d4364d04
......@@ -38,6 +38,8 @@ type Stackframe struct {
Ret uint64
// Address to the memory location containing the return address
addrret uint64
// Err is set if an error occoured during stacktrace
Err error
}
// Stacktrace returns the stack trace for thread.
......@@ -207,7 +209,7 @@ func (it *stackIterator) newStackframe(pc uint64, cfa int64, retaddr uintptr, fd
f, l, fn := it.bi.PCToLine(pc)
ret, err := readUintRaw(it.mem, retaddr, int64(it.bi.Arch.PtrSize()))
if err != nil {
return Stackframe{}, err
it.err = err
}
r := Stackframe{Current: Location{PC: pc, File: f, Line: l, Fn: fn}, CFA: cfa, FDE: fde, Ret: ret, addrret: uint64(retaddr), StackHi: it.stackhi}
if !top {
......@@ -231,7 +233,10 @@ func (it *stackIterator) stacktrace(depth int) ([]Stackframe, error) {
}
}
if err := it.Err(); err != nil {
return nil, err
if len(frames) == 0 {
return nil, err
}
frames = append(frames, Stackframe{Err: err})
}
return frames, nil
}
......@@ -1210,6 +1210,10 @@ func printStack(stack []api.Stackframe, ind string) {
s := ind + strings.Repeat(" ", d+2+len(ind))
for i := range stack {
if stack[i].Err != "" {
fmt.Printf("%serror: %s\n", s, stack[i].Err)
continue
}
name := "(nil)"
if stack[i].Function != nil {
name = stack[i].Function.Name
......
......@@ -216,7 +216,7 @@ func TestExecuteFile(t *testing.T) {
func TestIssue354(t *testing.T) {
printStack([]api.Stackframe{}, "")
printStack([]api.Stackframe{{api.Location{PC: 0, File: "irrelevant.go", Line: 10, Function: nil}, nil, nil, 0}}, "")
printStack([]api.Stackframe{{api.Location{PC: 0, File: "irrelevant.go", Line: 10, Function: nil}, nil, nil, 0, nil}}, "")
}
func TestIssue411(t *testing.T) {
......
......@@ -121,6 +121,7 @@ type Stackframe struct {
Locals []Variable
Arguments []Variable
FrameOffset int64
Err string
}
func (frame *Stackframe) Var(name string) *Variable {
......
......@@ -857,6 +857,9 @@ func (d *Debugger) convertStacktrace(rawlocs []proc.Stackframe, cfg *proc.LoadCo
Location: api.ConvertLocation(rawlocs[i].Call),
FrameOffset: rawlocs[i].CFA - int64(rawlocs[i].StackHi),
}
if rawlocs[i].Err != nil {
frame.Err = rawlocs[i].Err.Error()
}
if cfg != nil && rawlocs[i].Current.Fn != nil {
var err error
scope := proc.FrameToScope(d.target, rawlocs[i])
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册