proc,service,terminal: eval expressions in the scope of a deferred call

Add ability to evaluate variables on the scope of a deferred call's
argument frame.
This commit is contained in:
aarzilli
2018-07-10 12:15:11 +02:00
committed by Derek Parker
parent d2904322fa
commit b59032516e
11 changed files with 193 additions and 63 deletions

View File

@ -544,7 +544,8 @@ func FindGoroutine(dbp Process, gid int) (*G, error) {
// ConvertEvalScope returns a new EvalScope in the context of the
// specified goroutine ID and stack frame.
func ConvertEvalScope(dbp Process, gid, frame int) (*EvalScope, error) {
// If deferCall is > 0 the eval scope will be relative to the specified deferred call.
func ConvertEvalScope(dbp Process, gid, frame, deferCall int) (*EvalScope, error) {
if _, err := dbp.Valid(); err != nil {
return nil, err
}
@ -564,7 +565,7 @@ func ConvertEvalScope(dbp Process, gid, frame int) (*EvalScope, error) {
thread = g.Thread
}
locs, err := g.Stacktrace(frame+1, false)
locs, err := g.Stacktrace(frame+1, deferCall > 0)
if err != nil {
return nil, err
}
@ -573,6 +574,19 @@ func ConvertEvalScope(dbp Process, gid, frame int) (*EvalScope, error) {
return nil, fmt.Errorf("Frame %d does not exist in goroutine %d", frame, gid)
}
if deferCall > 0 {
if deferCall-1 >= len(locs[frame].Defers) {
return nil, fmt.Errorf("Frame %d only has %d deferred calls", frame, len(locs[frame].Defers))
}
d := locs[frame].Defers[deferCall-1]
if d.Unreadable != nil {
return nil, d.Unreadable
}
return d.EvalScope(ct)
}
return FrameToScope(dbp.BinInfo(), thread, g, locs[frame:]...), nil
}