diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go index ed06c70001a38f42f69c96c2a5e48cccabb202e1..0709c1ff40dccf844657f02f89195b28bcc1cf29 100644 --- a/pkg/proc/stack.go +++ b/pkg/proc/stack.go @@ -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 } diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 133275909c01a3c375e4b529c84f1e41ccdc8518..3c77f4634ff57da52eb2d2a572426b86ac935db5 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -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 diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index 786d4c957156a4477cbf084e62501002ba58a26b..66aeaa9349c846782b5b47442dfb183fcdafa5e6 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -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) { diff --git a/service/api/types.go b/service/api/types.go index 489b3309e1768c5f14b5ff49ca0b7b0060d0b19d..188d9f27db88ee6de2a10c338dbe77005dba2556 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -121,6 +121,7 @@ type Stackframe struct { Locals []Variable Arguments []Variable FrameOffset int64 + Err string } func (frame *Stackframe) Var(name string) *Variable { diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index e88a7f0c0b6f725fe5bd4dd97608fc0c999337f5..877217ccb6d5d9663e1281e303ea0a5e16ad9b98 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -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])