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:
parent
d2904322fa
commit
b59032516e
@ -14,6 +14,7 @@ Command | Description
|
|||||||
[condition](#condition) | Set breakpoint condition.
|
[condition](#condition) | Set breakpoint condition.
|
||||||
[config](#config) | Changes configuration parameters.
|
[config](#config) | Changes configuration parameters.
|
||||||
[continue](#continue) | Run until breakpoint or program termination.
|
[continue](#continue) | Run until breakpoint or program termination.
|
||||||
|
[deferred](#deferred) | Executes command in the context of a deferred call.
|
||||||
[disassemble](#disassemble) | Disassembler.
|
[disassemble](#disassemble) | Disassembler.
|
||||||
[down](#down) | Move the current frame down.
|
[down](#down) | Move the current frame down.
|
||||||
[edit](#edit) | Open where you are in $DELVE_EDITOR or $EDITOR
|
[edit](#edit) | Open where you are in $DELVE_EDITOR or $EDITOR
|
||||||
@ -161,6 +162,14 @@ Run until breakpoint or program termination.
|
|||||||
|
|
||||||
Aliases: c
|
Aliases: c
|
||||||
|
|
||||||
|
## deferred
|
||||||
|
Executes command in the context of a deferred call.
|
||||||
|
|
||||||
|
deferred <n> <command>
|
||||||
|
|
||||||
|
Executes the specified command (print, args, locals) in the context of the n-th deferred call in the current frame.
|
||||||
|
|
||||||
|
|
||||||
## disassemble
|
## disassemble
|
||||||
Disassembler.
|
Disassembler.
|
||||||
|
|
||||||
@ -341,10 +350,11 @@ If regex is specified only the source files matching it will be returned.
|
|||||||
## stack
|
## stack
|
||||||
Print stack trace.
|
Print stack trace.
|
||||||
|
|
||||||
[goroutine <n>] [frame <m>] stack [<depth>] [-full] [-g] [-s] [-offsets]
|
[goroutine <n>] [frame <m>] stack [<depth>] [-full] [-offsets] [-defer]
|
||||||
|
|
||||||
-full every stackframe is decorated with the value of its local variables and arguments.
|
-full every stackframe is decorated with the value of its local variables and arguments.
|
||||||
-offsets prints frame offset of each frame
|
-offsets prints frame offset of each frame.
|
||||||
|
-defer prints deferred function call stack for each frame.
|
||||||
|
|
||||||
|
|
||||||
Aliases: bt
|
Aliases: bt
|
||||||
|
@ -5,21 +5,21 @@ import "runtime"
|
|||||||
func f1() {
|
func f1() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func f2() {
|
func f2(a int8, b int32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func f3() {
|
func f3() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func call1() {
|
func call1() {
|
||||||
defer f2()
|
defer f2(1, -1)
|
||||||
defer f1()
|
defer f1()
|
||||||
call2()
|
call2()
|
||||||
}
|
}
|
||||||
|
|
||||||
func call2() {
|
func call2() {
|
||||||
defer f3()
|
defer f3()
|
||||||
defer f2()
|
defer f2(42, 61)
|
||||||
call3()
|
call3()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +544,8 @@ func FindGoroutine(dbp Process, gid int) (*G, error) {
|
|||||||
|
|
||||||
// ConvertEvalScope returns a new EvalScope in the context of the
|
// ConvertEvalScope returns a new EvalScope in the context of the
|
||||||
// specified goroutine ID and stack frame.
|
// 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 {
|
if _, err := dbp.Valid(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -564,7 +565,7 @@ func ConvertEvalScope(dbp Process, gid, frame int) (*EvalScope, error) {
|
|||||||
thread = g.Thread
|
thread = g.Thread
|
||||||
}
|
}
|
||||||
|
|
||||||
locs, err := g.Stacktrace(frame+1, false)
|
locs, err := g.Stacktrace(frame+1, deferCall > 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
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
|
return FrameToScope(dbp.BinInfo(), thread, g, locs[frame:]...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1263,7 +1263,7 @@ func TestFrameEvaluation(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
scope, err := proc.ConvertEvalScope(p, g.ID, frame)
|
scope, err := proc.ConvertEvalScope(p, g.ID, frame, 0)
|
||||||
assertNoError(err, t, "ConvertEvalScope()")
|
assertNoError(err, t, "ConvertEvalScope()")
|
||||||
t.Logf("scope = %v", scope)
|
t.Logf("scope = %v", scope)
|
||||||
v, err := scope.EvalVariable("i", normalLoadConfig)
|
v, err := scope.EvalVariable("i", normalLoadConfig)
|
||||||
@ -1288,7 +1288,7 @@ func TestFrameEvaluation(t *testing.T) {
|
|||||||
assertNoError(err, t, "GetG()")
|
assertNoError(err, t, "GetG()")
|
||||||
|
|
||||||
for i := 0; i <= 3; i++ {
|
for i := 0; i <= 3; i++ {
|
||||||
scope, err := proc.ConvertEvalScope(p, g.ID, i+1)
|
scope, err := proc.ConvertEvalScope(p, g.ID, i+1, 0)
|
||||||
assertNoError(err, t, fmt.Sprintf("ConvertEvalScope() on frame %d", i+1))
|
assertNoError(err, t, fmt.Sprintf("ConvertEvalScope() on frame %d", i+1))
|
||||||
v, err := scope.EvalVariable("n", normalLoadConfig)
|
v, err := scope.EvalVariable("n", normalLoadConfig)
|
||||||
assertNoError(err, t, fmt.Sprintf("EvalVariable() on frame %d", i+1))
|
assertNoError(err, t, fmt.Sprintf("EvalVariable() on frame %d", i+1))
|
||||||
@ -4041,3 +4041,46 @@ func TestNextUnknownInstr(t *testing.T) {
|
|||||||
assertNoError(proc.Next(p), t, "Next()")
|
assertNoError(proc.Next(p), t, "Next()")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadDeferArgs(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
frame, deferCall int
|
||||||
|
a, b int64
|
||||||
|
}{
|
||||||
|
{1, 1, 42, 61},
|
||||||
|
{2, 2, 1, -1},
|
||||||
|
}
|
||||||
|
|
||||||
|
withTestProcess("deferstack", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
scope, err := proc.ConvertEvalScope(p, -1, test.frame, test.deferCall)
|
||||||
|
assertNoError(err, t, fmt.Sprintf("ConvertEvalScope(-1, %d, %d)", test.frame, test.deferCall))
|
||||||
|
|
||||||
|
if scope.Fn.Name != "main.f2" {
|
||||||
|
t.Fatalf("expected function \"main.f2\" got %q", scope.Fn.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
avar, err := scope.EvalVariable("a", normalLoadConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
bvar, err := scope.EvalVariable("b", normalLoadConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
a, _ := constant.Int64Val(avar.Value)
|
||||||
|
b, _ := constant.Int64Val(bvar.Value)
|
||||||
|
|
||||||
|
if a != test.a {
|
||||||
|
t.Errorf("value of argument 'a' at frame %d, deferred call %d: %d (expected %d)", test.frame, test.deferCall, a, test.a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b != test.b {
|
||||||
|
t.Errorf("value of argument 'b' at frame %d, deferred call %d: %d (expected %d)", test.frame, test.deferCall, b, test.b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -594,6 +594,7 @@ type Defer struct {
|
|||||||
DeferPC uint64 // PC address of instruction that added this defer
|
DeferPC uint64 // PC address of instruction that added this defer
|
||||||
SP uint64 // Value of SP register when this function was deferred (this field gets adjusted when the stack is moved to match the new stack space)
|
SP uint64 // Value of SP register when this function was deferred (this field gets adjusted when the stack is moved to match the new stack space)
|
||||||
link *Defer // Next deferred function
|
link *Defer // Next deferred function
|
||||||
|
argSz int64
|
||||||
|
|
||||||
variable *Variable
|
variable *Variable
|
||||||
Unreadable error
|
Unreadable error
|
||||||
@ -660,6 +661,7 @@ func (d *Defer) load() {
|
|||||||
|
|
||||||
d.DeferPC, _ = constant.Uint64Val(d.variable.fieldVariable("pc").Value)
|
d.DeferPC, _ = constant.Uint64Val(d.variable.fieldVariable("pc").Value)
|
||||||
d.SP, _ = constant.Uint64Val(d.variable.fieldVariable("sp").Value)
|
d.SP, _ = constant.Uint64Val(d.variable.fieldVariable("sp").Value)
|
||||||
|
d.argSz, _ = constant.Int64Val(d.variable.fieldVariable("siz").Value)
|
||||||
|
|
||||||
linkvar := d.variable.fieldVariable("link").maybeDereference()
|
linkvar := d.variable.fieldVariable("link").maybeDereference()
|
||||||
if linkvar.Addr != 0 {
|
if linkvar.Addr != 0 {
|
||||||
@ -685,3 +687,40 @@ func (d *Defer) Next() *Defer {
|
|||||||
}
|
}
|
||||||
return d.link
|
return d.link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EvalScope returns an EvalScope relative to the argument frame of this deferred call.
|
||||||
|
// The argument frame of a deferred call is stored in memory immediately
|
||||||
|
// after the deferred header.
|
||||||
|
func (d *Defer) EvalScope(thread Thread) (*EvalScope, error) {
|
||||||
|
scope, err := GoroutineScope(thread)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not get scope: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bi := thread.BinInfo()
|
||||||
|
scope.PC = d.DeferredPC
|
||||||
|
scope.File, scope.Line, scope.Fn = bi.PCToLine(d.DeferredPC)
|
||||||
|
|
||||||
|
if scope.Fn == nil {
|
||||||
|
return nil, fmt.Errorf("could not find function at %#x", d.DeferredPC)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The arguments are stored immediately after the defer header struct, i.e.
|
||||||
|
// addr+sizeof(_defer). Since CFA in go is always the address of the first
|
||||||
|
// argument, that's what we use for the value of CFA.
|
||||||
|
// For SP we use CFA minus the size of one pointer because that would be
|
||||||
|
// the space occupied by pushing the return address on the stack during the
|
||||||
|
// CALL.
|
||||||
|
scope.Regs.CFA = (int64(d.variable.Addr) + d.variable.RealType.Common().ByteSize)
|
||||||
|
scope.Regs.Regs[scope.Regs.SPRegNum].Uint64Val = uint64(scope.Regs.CFA - int64(bi.Arch.PtrSize()))
|
||||||
|
|
||||||
|
bi.dwarfReader.Seek(scope.Fn.offset)
|
||||||
|
e, err := bi.dwarfReader.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not read DWARF function entry: %v", err)
|
||||||
|
}
|
||||||
|
scope.Regs.FrameBase, _, _, _ = bi.Location(e, dwarf.AttrFrameBase, scope.PC, scope.Regs)
|
||||||
|
scope.Mem = cacheMemory(scope.Mem, uintptr(scope.Regs.CFA), int(d.argSz))
|
||||||
|
|
||||||
|
return scope, nil
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@ type cmdPrefix int
|
|||||||
const (
|
const (
|
||||||
noPrefix = cmdPrefix(0)
|
noPrefix = cmdPrefix(0)
|
||||||
onPrefix = cmdPrefix(1 << iota)
|
onPrefix = cmdPrefix(1 << iota)
|
||||||
|
deferredPrefix
|
||||||
)
|
)
|
||||||
|
|
||||||
type callContext struct {
|
type callContext struct {
|
||||||
@ -188,7 +189,7 @@ Called without arguments it will show information about the current goroutine.
|
|||||||
Called with a single argument it will switch to the specified goroutine.
|
Called with a single argument it will switch to the specified goroutine.
|
||||||
Called with more arguments it will execute a command on the specified goroutine.`},
|
Called with more arguments it will execute a command on the specified goroutine.`},
|
||||||
{aliases: []string{"breakpoints", "bp"}, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."},
|
{aliases: []string{"breakpoints", "bp"}, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."},
|
||||||
{aliases: []string{"print", "p"}, allowedPrefixes: onPrefix, cmdFn: printVar, helpMsg: `Evaluate an expression.
|
{aliases: []string{"print", "p"}, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: printVar, helpMsg: `Evaluate an expression.
|
||||||
|
|
||||||
[goroutine <n>] [frame <m>] print <expression>
|
[goroutine <n>] [frame <m>] print <expression>
|
||||||
|
|
||||||
@ -216,12 +217,12 @@ If regex is specified only the functions matching it will be returned.`},
|
|||||||
types [<regex>]
|
types [<regex>]
|
||||||
|
|
||||||
If regex is specified only the types matching it will be returned.`},
|
If regex is specified only the types matching it will be returned.`},
|
||||||
{aliases: []string{"args"}, allowedPrefixes: onPrefix, cmdFn: args, helpMsg: `Print function arguments.
|
{aliases: []string{"args"}, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: args, helpMsg: `Print function arguments.
|
||||||
|
|
||||||
[goroutine <n>] [frame <m>] args [-v] [<regex>]
|
[goroutine <n>] [frame <m>] args [-v] [<regex>]
|
||||||
|
|
||||||
If regex is specified only function arguments with a name matching it will be returned. If -v is specified more information about each function argument will be shown.`},
|
If regex is specified only function arguments with a name matching it will be returned. If -v is specified more information about each function argument will be shown.`},
|
||||||
{aliases: []string{"locals"}, allowedPrefixes: onPrefix, cmdFn: locals, helpMsg: `Print local variables.
|
{aliases: []string{"locals"}, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: locals, helpMsg: `Print local variables.
|
||||||
|
|
||||||
[goroutine <n>] [frame <m>] locals [-v] [<regex>]
|
[goroutine <n>] [frame <m>] locals [-v] [<regex>]
|
||||||
|
|
||||||
@ -250,10 +251,11 @@ When connected to a headless instance started with the --accept-multiclient, pas
|
|||||||
Show source around current point or provided linespec.`},
|
Show source around current point or provided linespec.`},
|
||||||
{aliases: []string{"stack", "bt"}, allowedPrefixes: onPrefix, cmdFn: stackCommand, helpMsg: `Print stack trace.
|
{aliases: []string{"stack", "bt"}, allowedPrefixes: onPrefix, cmdFn: stackCommand, helpMsg: `Print stack trace.
|
||||||
|
|
||||||
[goroutine <n>] [frame <m>] stack [<depth>] [-full] [-g] [-s] [-offsets]
|
[goroutine <n>] [frame <m>] stack [<depth>] [-full] [-offsets] [-defer]
|
||||||
|
|
||||||
-full every stackframe is decorated with the value of its local variables and arguments.
|
-full every stackframe is decorated with the value of its local variables and arguments.
|
||||||
-offsets prints frame offset of each frame
|
-offsets prints frame offset of each frame.
|
||||||
|
-defer prints deferred function call stack for each frame.
|
||||||
`},
|
`},
|
||||||
{aliases: []string{"frame"},
|
{aliases: []string{"frame"},
|
||||||
cmdFn: func(t *Term, ctx callContext, arg string) error {
|
cmdFn: func(t *Term, ctx callContext, arg string) error {
|
||||||
@ -286,6 +288,11 @@ Move the current frame up by <m>. The second form runs the command on the given
|
|||||||
down [<m>] <command>
|
down [<m>] <command>
|
||||||
|
|
||||||
Move the current frame down by <m>. The second form runs the command on the given frame.`},
|
Move the current frame down by <m>. The second form runs the command on the given frame.`},
|
||||||
|
{aliases: []string{"deferred"}, cmdFn: c.deferredCommand, helpMsg: `Executes command in the context of a deferred call.
|
||||||
|
|
||||||
|
deferred <n> <command>
|
||||||
|
|
||||||
|
Executes the specified command (print, args, locals) in the context of the n-th deferred call in the current frame.`},
|
||||||
{aliases: []string{"source"}, cmdFn: c.sourceCommand, helpMsg: `Executes a file containing a list of delve commands
|
{aliases: []string{"source"}, cmdFn: c.sourceCommand, helpMsg: `Executes a file containing a list of delve commands
|
||||||
|
|
||||||
source <path>`},
|
source <path>`},
|
||||||
@ -428,7 +435,7 @@ func (c *Commands) CallWithContext(cmdstr string, t *Term, ctx callContext) erro
|
|||||||
|
|
||||||
// Call takes a command to execute.
|
// Call takes a command to execute.
|
||||||
func (c *Commands) Call(cmdstr string, t *Term) error {
|
func (c *Commands) Call(cmdstr string, t *Term) error {
|
||||||
ctx := callContext{Prefix: noPrefix, Scope: api.EvalScope{GoroutineID: -1, Frame: c.frame}}
|
ctx := callContext{Prefix: noPrefix, Scope: api.EvalScope{GoroutineID: -1, Frame: c.frame, DeferredCall: 0}}
|
||||||
return c.CallWithContext(cmdstr, t, ctx)
|
return c.CallWithContext(cmdstr, t, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,6 +723,22 @@ func (c *Commands) frameCommand(t *Term, ctx callContext, argstr string, directi
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) deferredCommand(t *Term, ctx callContext, argstr string) error {
|
||||||
|
ctx.Prefix = deferredPrefix
|
||||||
|
|
||||||
|
space := strings.Index(argstr, " ")
|
||||||
|
|
||||||
|
var err error
|
||||||
|
ctx.Scope.DeferredCall, err = strconv.Atoi(argstr[:space])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ctx.Scope.DeferredCall <= 0 {
|
||||||
|
return errors.New("argument of deferred must be a number greater than 0 (use 'stack -defer' to see the list of deferred calls)")
|
||||||
|
}
|
||||||
|
return c.CallWithContext(argstr[space:], t, ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func printscope(t *Term) error {
|
func printscope(t *Term) error {
|
||||||
state, err := t.client.GetState()
|
state, err := t.client.GetState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1573,7 +1596,7 @@ func printStack(stack []api.Stackframe, ind string, offsets bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for j, d := range stack[i].Defers {
|
for j, d := range stack[i].Defers {
|
||||||
deferHeader := fmt.Sprintf("%s defer %d: ", s, j)
|
deferHeader := fmt.Sprintf("%s defer %d: ", s, j+1)
|
||||||
s2 := strings.Repeat(" ", len(deferHeader))
|
s2 := strings.Repeat(" ", len(deferHeader))
|
||||||
if d.Unreadable != "" {
|
if d.Unreadable != "" {
|
||||||
fmt.Printf("%s(unreadable defer: %s)\n", deferHeader, d.Unreadable)
|
fmt.Printf("%s(unreadable defer: %s)\n", deferHeader, d.Unreadable)
|
||||||
|
@ -324,8 +324,9 @@ type BreakpointInfo struct {
|
|||||||
// EvalScope is the scope a command should
|
// EvalScope is the scope a command should
|
||||||
// be evaluated in. Describes the goroutine and frame number.
|
// be evaluated in. Describes the goroutine and frame number.
|
||||||
type EvalScope struct {
|
type EvalScope struct {
|
||||||
GoroutineID int
|
GoroutineID int
|
||||||
Frame int
|
Frame int
|
||||||
|
DeferredCall int // when DeferredCall is n > 0 this eval scope is relative to the n-th deferred call in the current frame
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -825,7 +825,7 @@ func (d *Debugger) LocalVariables(scope api.EvalScope, cfg proc.LoadConfig) ([]a
|
|||||||
d.processMutex.Lock()
|
d.processMutex.Lock()
|
||||||
defer d.processMutex.Unlock()
|
defer d.processMutex.Unlock()
|
||||||
|
|
||||||
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame)
|
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame, scope.DeferredCall)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -841,7 +841,7 @@ func (d *Debugger) FunctionArguments(scope api.EvalScope, cfg proc.LoadConfig) (
|
|||||||
d.processMutex.Lock()
|
d.processMutex.Lock()
|
||||||
defer d.processMutex.Unlock()
|
defer d.processMutex.Unlock()
|
||||||
|
|
||||||
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame)
|
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame, scope.DeferredCall)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -858,7 +858,7 @@ func (d *Debugger) EvalVariableInScope(scope api.EvalScope, symbol string, cfg p
|
|||||||
d.processMutex.Lock()
|
d.processMutex.Lock()
|
||||||
defer d.processMutex.Unlock()
|
defer d.processMutex.Unlock()
|
||||||
|
|
||||||
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame)
|
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame, scope.DeferredCall)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -875,7 +875,7 @@ func (d *Debugger) SetVariableInScope(scope api.EvalScope, symbol, value string)
|
|||||||
d.processMutex.Lock()
|
d.processMutex.Lock()
|
||||||
defer d.processMutex.Unlock()
|
defer d.processMutex.Unlock()
|
||||||
|
|
||||||
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame)
|
s, err := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame, scope.DeferredCall)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1009,7 +1009,7 @@ func (d *Debugger) FindLocation(scope api.EvalScope, locStr string) ([]api.Locat
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s, _ := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame)
|
s, _ := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame, scope.DeferredCall)
|
||||||
|
|
||||||
locs, err := loc.Find(d, s, locStr)
|
locs, err := loc.Find(d, s, locStr)
|
||||||
for i := range locs {
|
for i := range locs {
|
||||||
|
@ -76,7 +76,7 @@ type LocationFinder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func findLocationHelper(t *testing.T, c LocationFinder, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 {
|
func findLocationHelper(t *testing.T, c LocationFinder, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 {
|
||||||
locs, err := c.FindLocation(api.EvalScope{-1, 0}, loc)
|
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, loc)
|
||||||
t.Logf("FindLocation(\"%s\") → %v\n", loc, locs)
|
t.Logf("FindLocation(\"%s\") → %v\n", loc, locs)
|
||||||
|
|
||||||
if shouldErr {
|
if shouldErr {
|
||||||
|
@ -433,7 +433,7 @@ func Test1ClientServer_infoLocals(t *testing.T) {
|
|||||||
if state.Err != nil {
|
if state.Err != nil {
|
||||||
t.Fatalf("Unexpected error: %v, state: %#v", state.Err, state)
|
t.Fatalf("Unexpected error: %v, state: %#v", state.Err, state)
|
||||||
}
|
}
|
||||||
locals, err := c.ListLocalVariables(api.EvalScope{-1, 0})
|
locals, err := c.ListLocalVariables(api.EvalScope{-1, 0, 0})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -461,7 +461,7 @@ func Test1ClientServer_infoArgs(t *testing.T) {
|
|||||||
if regs == "" {
|
if regs == "" {
|
||||||
t.Fatal("Expected string showing registers values, got empty string")
|
t.Fatal("Expected string showing registers values, got empty string")
|
||||||
}
|
}
|
||||||
locals, err := c.ListFunctionArgs(api.EvalScope{-1, 0})
|
locals, err := c.ListFunctionArgs(api.EvalScope{-1, 0, 0})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -687,7 +687,7 @@ func Test1ClientServer_EvalVariable(t *testing.T) {
|
|||||||
t.Fatalf("Continue(): %v\n", state.Err)
|
t.Fatalf("Continue(): %v\n", state.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var1, err := c.EvalVariable(api.EvalScope{-1, 0}, "a1")
|
var1, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "a1")
|
||||||
assertNoError(err, t, "EvalVariable")
|
assertNoError(err, t, "EvalVariable")
|
||||||
|
|
||||||
t.Logf("var1: %s", var1.SinglelineString())
|
t.Logf("var1: %s", var1.SinglelineString())
|
||||||
@ -706,9 +706,9 @@ func Test1ClientServer_SetVariable(t *testing.T) {
|
|||||||
t.Fatalf("Continue(): %v\n", state.Err)
|
t.Fatalf("Continue(): %v\n", state.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNoError(c.SetVariable(api.EvalScope{-1, 0}, "a2", "8"), t, "SetVariable()")
|
assertNoError(c.SetVariable(api.EvalScope{-1, 0, 0}, "a2", "8"), t, "SetVariable()")
|
||||||
|
|
||||||
a2, err := c.EvalVariable(api.EvalScope{-1, 0}, "a2")
|
a2, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "a2")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not evaluate variable: %v", err)
|
t.Fatalf("Could not evaluate variable: %v", err)
|
||||||
}
|
}
|
||||||
@ -835,10 +835,10 @@ func Test1Issue355(t *testing.T) {
|
|||||||
assertError(err, t, "ListThreads()")
|
assertError(err, t, "ListThreads()")
|
||||||
_, err = c.GetThread(tid)
|
_, err = c.GetThread(tid)
|
||||||
assertError(err, t, "GetThread()")
|
assertError(err, t, "GetThread()")
|
||||||
assertError(c.SetVariable(api.EvalScope{gid, 0}, "a", "10"), t, "SetVariable()")
|
assertError(c.SetVariable(api.EvalScope{gid, 0, 0}, "a", "10"), t, "SetVariable()")
|
||||||
_, err = c.ListLocalVariables(api.EvalScope{gid, 0})
|
_, err = c.ListLocalVariables(api.EvalScope{gid, 0, 0})
|
||||||
assertError(err, t, "ListLocalVariables()")
|
assertError(err, t, "ListLocalVariables()")
|
||||||
_, err = c.ListFunctionArgs(api.EvalScope{gid, 0})
|
_, err = c.ListFunctionArgs(api.EvalScope{gid, 0, 0})
|
||||||
assertError(err, t, "ListFunctionArgs()")
|
assertError(err, t, "ListFunctionArgs()")
|
||||||
_, err = c.ListRegisters()
|
_, err = c.ListRegisters()
|
||||||
assertError(err, t, "ListRegisters()")
|
assertError(err, t, "ListRegisters()")
|
||||||
@ -846,9 +846,9 @@ func Test1Issue355(t *testing.T) {
|
|||||||
assertError(err, t, "ListGoroutines()")
|
assertError(err, t, "ListGoroutines()")
|
||||||
_, err = c.Stacktrace(gid, 10, false)
|
_, err = c.Stacktrace(gid, 10, false)
|
||||||
assertError(err, t, "Stacktrace()")
|
assertError(err, t, "Stacktrace()")
|
||||||
_, err = c.FindLocation(api.EvalScope{gid, 0}, "+1")
|
_, err = c.FindLocation(api.EvalScope{gid, 0, 0}, "+1")
|
||||||
assertError(err, t, "FindLocation()")
|
assertError(err, t, "FindLocation()")
|
||||||
_, err = c.DisassemblePC(api.EvalScope{-1, 0}, 0x40100, api.IntelFlavour)
|
_, err = c.DisassemblePC(api.EvalScope{-1, 0, 0}, 0x40100, api.IntelFlavour)
|
||||||
assertError(err, t, "DisassemblePC()")
|
assertError(err, t, "DisassemblePC()")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -863,12 +863,12 @@ func Test1Disasm(t *testing.T) {
|
|||||||
state := <-ch
|
state := <-ch
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
|
|
||||||
locs, err := c.FindLocation(api.EvalScope{-1, 0}, "main.main")
|
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "main.main")
|
||||||
assertNoError(err, t, "FindLocation()")
|
assertNoError(err, t, "FindLocation()")
|
||||||
if len(locs) != 1 {
|
if len(locs) != 1 {
|
||||||
t.Fatalf("wrong number of locations for main.main: %d", len(locs))
|
t.Fatalf("wrong number of locations for main.main: %d", len(locs))
|
||||||
}
|
}
|
||||||
d1, err := c.DisassemblePC(api.EvalScope{-1, 0}, locs[0].PC, api.IntelFlavour)
|
d1, err := c.DisassemblePC(api.EvalScope{-1, 0, 0}, locs[0].PC, api.IntelFlavour)
|
||||||
assertNoError(err, t, "DisassemblePC()")
|
assertNoError(err, t, "DisassemblePC()")
|
||||||
if len(d1) < 2 {
|
if len(d1) < 2 {
|
||||||
t.Fatalf("wrong size of disassembly: %d", len(d1))
|
t.Fatalf("wrong size of disassembly: %d", len(d1))
|
||||||
@ -876,7 +876,7 @@ func Test1Disasm(t *testing.T) {
|
|||||||
|
|
||||||
pcstart := d1[0].Loc.PC
|
pcstart := d1[0].Loc.PC
|
||||||
pcend := d1[len(d1)-1].Loc.PC + uint64(len(d1[len(d1)-1].Bytes))
|
pcend := d1[len(d1)-1].Loc.PC + uint64(len(d1[len(d1)-1].Bytes))
|
||||||
d2, err := c.DisassembleRange(api.EvalScope{-1, 0}, pcstart, pcend, api.IntelFlavour)
|
d2, err := c.DisassembleRange(api.EvalScope{-1, 0, 0}, pcstart, pcend, api.IntelFlavour)
|
||||||
assertNoError(err, t, "DisassembleRange()")
|
assertNoError(err, t, "DisassembleRange()")
|
||||||
|
|
||||||
if len(d1) != len(d2) {
|
if len(d1) != len(d2) {
|
||||||
@ -885,7 +885,7 @@ func Test1Disasm(t *testing.T) {
|
|||||||
t.Fatal("mismatched length between disassemble pc and disassemble range")
|
t.Fatal("mismatched length between disassemble pc and disassemble range")
|
||||||
}
|
}
|
||||||
|
|
||||||
d3, err := c.DisassemblePC(api.EvalScope{-1, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
d3, err := c.DisassemblePC(api.EvalScope{-1, 0, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
||||||
assertNoError(err, t, "DisassemblePC() - second call")
|
assertNoError(err, t, "DisassemblePC() - second call")
|
||||||
|
|
||||||
if len(d1) != len(d3) {
|
if len(d1) != len(d3) {
|
||||||
@ -929,7 +929,7 @@ func Test1Disasm(t *testing.T) {
|
|||||||
state, err := c.StepInstruction()
|
state, err := c.StepInstruction()
|
||||||
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
||||||
|
|
||||||
d3, err = c.DisassemblePC(api.EvalScope{-1, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
d3, err = c.DisassemblePC(api.EvalScope{-1, 0, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
||||||
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
||||||
|
|
||||||
curinstr := getCurinstr(d3)
|
curinstr := getCurinstr(d3)
|
||||||
@ -992,7 +992,7 @@ func Test1ClientServer_CondBreakpoint(t *testing.T) {
|
|||||||
state := <-c.Continue()
|
state := <-c.Continue()
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
|
|
||||||
nvar, err := c.EvalVariable(api.EvalScope{-1, 0}, "n")
|
nvar, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "n")
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
|
|
||||||
if nvar.SinglelineString() != "7" {
|
if nvar.SinglelineString() != "7" {
|
||||||
@ -1096,14 +1096,14 @@ func Test1TypesCommand(t *testing.T) {
|
|||||||
|
|
||||||
func Test1Issue406(t *testing.T) {
|
func Test1Issue406(t *testing.T) {
|
||||||
withTestClient1("issue406", t, func(c *rpc1.RPCClient) {
|
withTestClient1("issue406", t, func(c *rpc1.RPCClient) {
|
||||||
locs, err := c.FindLocation(api.EvalScope{-1, 0}, "issue406.go:146")
|
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "issue406.go:146")
|
||||||
assertNoError(err, t, "FindLocation()")
|
assertNoError(err, t, "FindLocation()")
|
||||||
_, err = c.CreateBreakpoint(&api.Breakpoint{Addr: locs[0].PC})
|
_, err = c.CreateBreakpoint(&api.Breakpoint{Addr: locs[0].PC})
|
||||||
assertNoError(err, t, "CreateBreakpoint()")
|
assertNoError(err, t, "CreateBreakpoint()")
|
||||||
ch := c.Continue()
|
ch := c.Continue()
|
||||||
state := <-ch
|
state := <-ch
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
v, err := c.EvalVariable(api.EvalScope{-1, 0}, "cfgtree")
|
v, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "cfgtree")
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
vs := v.MultilineString("")
|
vs := v.MultilineString("")
|
||||||
t.Logf("cfgtree formats to: %s\n", vs)
|
t.Logf("cfgtree formats to: %s\n", vs)
|
||||||
|
@ -484,7 +484,7 @@ func TestClientServer_infoLocals(t *testing.T) {
|
|||||||
if state.Err != nil {
|
if state.Err != nil {
|
||||||
t.Fatalf("Unexpected error: %v, state: %#v", state.Err, state)
|
t.Fatalf("Unexpected error: %v, state: %#v", state.Err, state)
|
||||||
}
|
}
|
||||||
locals, err := c.ListLocalVariables(api.EvalScope{-1, 0}, normalLoadConfig)
|
locals, err := c.ListLocalVariables(api.EvalScope{-1, 0, 0}, normalLoadConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -513,7 +513,7 @@ func TestClientServer_infoArgs(t *testing.T) {
|
|||||||
if len(regs) == 0 {
|
if len(regs) == 0 {
|
||||||
t.Fatal("Expected string showing registers values, got empty string")
|
t.Fatal("Expected string showing registers values, got empty string")
|
||||||
}
|
}
|
||||||
locals, err := c.ListFunctionArgs(api.EvalScope{-1, 0}, normalLoadConfig)
|
locals, err := c.ListFunctionArgs(api.EvalScope{-1, 0, 0}, normalLoadConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -755,7 +755,7 @@ func TestClientServer_EvalVariable(t *testing.T) {
|
|||||||
t.Fatalf("Continue(): %v\n", state.Err)
|
t.Fatalf("Continue(): %v\n", state.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var1, err := c.EvalVariable(api.EvalScope{-1, 0}, "a1", normalLoadConfig)
|
var1, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "a1", normalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable")
|
assertNoError(err, t, "EvalVariable")
|
||||||
|
|
||||||
t.Logf("var1: %s", var1.SinglelineString())
|
t.Logf("var1: %s", var1.SinglelineString())
|
||||||
@ -774,9 +774,9 @@ func TestClientServer_SetVariable(t *testing.T) {
|
|||||||
t.Fatalf("Continue(): %v\n", state.Err)
|
t.Fatalf("Continue(): %v\n", state.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNoError(c.SetVariable(api.EvalScope{-1, 0}, "a2", "8"), t, "SetVariable()")
|
assertNoError(c.SetVariable(api.EvalScope{-1, 0, 0}, "a2", "8"), t, "SetVariable()")
|
||||||
|
|
||||||
a2, err := c.EvalVariable(api.EvalScope{-1, 0}, "a2", normalLoadConfig)
|
a2, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "a2", normalLoadConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not evaluate variable: %v", err)
|
t.Fatalf("Could not evaluate variable: %v", err)
|
||||||
}
|
}
|
||||||
@ -909,10 +909,10 @@ func TestIssue355(t *testing.T) {
|
|||||||
assertError(err, t, "ListThreads()")
|
assertError(err, t, "ListThreads()")
|
||||||
_, err = c.GetThread(tid)
|
_, err = c.GetThread(tid)
|
||||||
assertError(err, t, "GetThread()")
|
assertError(err, t, "GetThread()")
|
||||||
assertError(c.SetVariable(api.EvalScope{gid, 0}, "a", "10"), t, "SetVariable()")
|
assertError(c.SetVariable(api.EvalScope{gid, 0, 0}, "a", "10"), t, "SetVariable()")
|
||||||
_, err = c.ListLocalVariables(api.EvalScope{gid, 0}, normalLoadConfig)
|
_, err = c.ListLocalVariables(api.EvalScope{gid, 0, 0}, normalLoadConfig)
|
||||||
assertError(err, t, "ListLocalVariables()")
|
assertError(err, t, "ListLocalVariables()")
|
||||||
_, err = c.ListFunctionArgs(api.EvalScope{gid, 0}, normalLoadConfig)
|
_, err = c.ListFunctionArgs(api.EvalScope{gid, 0, 0}, normalLoadConfig)
|
||||||
assertError(err, t, "ListFunctionArgs()")
|
assertError(err, t, "ListFunctionArgs()")
|
||||||
_, err = c.ListRegisters(0, false)
|
_, err = c.ListRegisters(0, false)
|
||||||
assertError(err, t, "ListRegisters()")
|
assertError(err, t, "ListRegisters()")
|
||||||
@ -920,9 +920,9 @@ func TestIssue355(t *testing.T) {
|
|||||||
assertError(err, t, "ListGoroutines()")
|
assertError(err, t, "ListGoroutines()")
|
||||||
_, err = c.Stacktrace(gid, 10, false, &normalLoadConfig)
|
_, err = c.Stacktrace(gid, 10, false, &normalLoadConfig)
|
||||||
assertError(err, t, "Stacktrace()")
|
assertError(err, t, "Stacktrace()")
|
||||||
_, err = c.FindLocation(api.EvalScope{gid, 0}, "+1")
|
_, err = c.FindLocation(api.EvalScope{gid, 0, 0}, "+1")
|
||||||
assertError(err, t, "FindLocation()")
|
assertError(err, t, "FindLocation()")
|
||||||
_, err = c.DisassemblePC(api.EvalScope{-1, 0}, 0x40100, api.IntelFlavour)
|
_, err = c.DisassemblePC(api.EvalScope{-1, 0, 0}, 0x40100, api.IntelFlavour)
|
||||||
assertError(err, t, "DisassemblePC()")
|
assertError(err, t, "DisassemblePC()")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -937,12 +937,12 @@ func TestDisasm(t *testing.T) {
|
|||||||
state := <-ch
|
state := <-ch
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
|
|
||||||
locs, err := c.FindLocation(api.EvalScope{-1, 0}, "main.main")
|
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "main.main")
|
||||||
assertNoError(err, t, "FindLocation()")
|
assertNoError(err, t, "FindLocation()")
|
||||||
if len(locs) != 1 {
|
if len(locs) != 1 {
|
||||||
t.Fatalf("wrong number of locations for main.main: %d", len(locs))
|
t.Fatalf("wrong number of locations for main.main: %d", len(locs))
|
||||||
}
|
}
|
||||||
d1, err := c.DisassemblePC(api.EvalScope{-1, 0}, locs[0].PC, api.IntelFlavour)
|
d1, err := c.DisassemblePC(api.EvalScope{-1, 0, 0}, locs[0].PC, api.IntelFlavour)
|
||||||
assertNoError(err, t, "DisassemblePC()")
|
assertNoError(err, t, "DisassemblePC()")
|
||||||
if len(d1) < 2 {
|
if len(d1) < 2 {
|
||||||
t.Fatalf("wrong size of disassembly: %d", len(d1))
|
t.Fatalf("wrong size of disassembly: %d", len(d1))
|
||||||
@ -950,7 +950,7 @@ func TestDisasm(t *testing.T) {
|
|||||||
|
|
||||||
pcstart := d1[0].Loc.PC
|
pcstart := d1[0].Loc.PC
|
||||||
pcend := d1[len(d1)-1].Loc.PC + uint64(len(d1[len(d1)-1].Bytes))
|
pcend := d1[len(d1)-1].Loc.PC + uint64(len(d1[len(d1)-1].Bytes))
|
||||||
d2, err := c.DisassembleRange(api.EvalScope{-1, 0}, pcstart, pcend, api.IntelFlavour)
|
d2, err := c.DisassembleRange(api.EvalScope{-1, 0, 0}, pcstart, pcend, api.IntelFlavour)
|
||||||
assertNoError(err, t, "DisassembleRange()")
|
assertNoError(err, t, "DisassembleRange()")
|
||||||
|
|
||||||
if len(d1) != len(d2) {
|
if len(d1) != len(d2) {
|
||||||
@ -959,7 +959,7 @@ func TestDisasm(t *testing.T) {
|
|||||||
t.Fatal("mismatched length between disassemble pc and disassemble range")
|
t.Fatal("mismatched length between disassemble pc and disassemble range")
|
||||||
}
|
}
|
||||||
|
|
||||||
d3, err := c.DisassemblePC(api.EvalScope{-1, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
d3, err := c.DisassemblePC(api.EvalScope{-1, 0, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
||||||
assertNoError(err, t, "DisassemblePC() - second call")
|
assertNoError(err, t, "DisassemblePC() - second call")
|
||||||
|
|
||||||
if len(d1) != len(d3) {
|
if len(d1) != len(d3) {
|
||||||
@ -1003,7 +1003,7 @@ func TestDisasm(t *testing.T) {
|
|||||||
state, err := c.StepInstruction()
|
state, err := c.StepInstruction()
|
||||||
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
||||||
|
|
||||||
d3, err = c.DisassemblePC(api.EvalScope{-1, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
d3, err = c.DisassemblePC(api.EvalScope{-1, 0, 0}, state.CurrentThread.PC, api.IntelFlavour)
|
||||||
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
assertNoError(err, t, fmt.Sprintf("StepInstruction() %d", count))
|
||||||
|
|
||||||
curinstr := getCurinstr(d3)
|
curinstr := getCurinstr(d3)
|
||||||
@ -1068,7 +1068,7 @@ func TestClientServer_CondBreakpoint(t *testing.T) {
|
|||||||
state := <-c.Continue()
|
state := <-c.Continue()
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
|
|
||||||
nvar, err := c.EvalVariable(api.EvalScope{-1, 0}, "n", normalLoadConfig)
|
nvar, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "n", normalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
|
|
||||||
if nvar.SinglelineString() != "7" {
|
if nvar.SinglelineString() != "7" {
|
||||||
@ -1174,14 +1174,14 @@ func TestTypesCommand(t *testing.T) {
|
|||||||
func TestIssue406(t *testing.T) {
|
func TestIssue406(t *testing.T) {
|
||||||
protest.AllowRecording(t)
|
protest.AllowRecording(t)
|
||||||
withTestClient2("issue406", t, func(c service.Client) {
|
withTestClient2("issue406", t, func(c service.Client) {
|
||||||
locs, err := c.FindLocation(api.EvalScope{-1, 0}, "issue406.go:146")
|
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "issue406.go:146")
|
||||||
assertNoError(err, t, "FindLocation()")
|
assertNoError(err, t, "FindLocation()")
|
||||||
_, err = c.CreateBreakpoint(&api.Breakpoint{Addr: locs[0].PC})
|
_, err = c.CreateBreakpoint(&api.Breakpoint{Addr: locs[0].PC})
|
||||||
assertNoError(err, t, "CreateBreakpoint()")
|
assertNoError(err, t, "CreateBreakpoint()")
|
||||||
ch := c.Continue()
|
ch := c.Continue()
|
||||||
state := <-ch
|
state := <-ch
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
v, err := c.EvalVariable(api.EvalScope{-1, 0}, "cfgtree", normalLoadConfig)
|
v, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "cfgtree", normalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
vs := v.MultilineString("")
|
vs := v.MultilineString("")
|
||||||
t.Logf("cfgtree formats to: %s\n", vs)
|
t.Logf("cfgtree formats to: %s\n", vs)
|
||||||
@ -1193,7 +1193,7 @@ func TestEvalExprName(t *testing.T) {
|
|||||||
state := <-c.Continue()
|
state := <-c.Continue()
|
||||||
assertNoError(state.Err, t, "Continue()")
|
assertNoError(state.Err, t, "Continue()")
|
||||||
|
|
||||||
var1, err := c.EvalVariable(api.EvalScope{-1, 0}, "i1+1", normalLoadConfig)
|
var1, err := c.EvalVariable(api.EvalScope{-1, 0, 0}, "i1+1", normalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable")
|
assertNoError(err, t, "EvalVariable")
|
||||||
|
|
||||||
const name = "i1+1"
|
const name = "i1+1"
|
||||||
@ -1511,7 +1511,7 @@ func TestAcceptMulticlient(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mustHaveDebugCalls(t *testing.T, c service.Client) {
|
func mustHaveDebugCalls(t *testing.T, c service.Client) {
|
||||||
locs, err := c.FindLocation(api.EvalScope{-1, 0}, "runtime.debugCallV1")
|
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "runtime.debugCallV1")
|
||||||
if len(locs) == 0 || err != nil {
|
if len(locs) == 0 || err != nil {
|
||||||
t.Skip("function calls not supported on this version of go")
|
t.Skip("function calls not supported on this version of go")
|
||||||
}
|
}
|
||||||
@ -1552,7 +1552,7 @@ func TestClientServerFunctionCallBadPos(t *testing.T) {
|
|||||||
protest.MustSupportFunctionCalls(t, testBackend)
|
protest.MustSupportFunctionCalls(t, testBackend)
|
||||||
withTestClient2("fncall", t, func(c service.Client) {
|
withTestClient2("fncall", t, func(c service.Client) {
|
||||||
mustHaveDebugCalls(t, c)
|
mustHaveDebugCalls(t, c)
|
||||||
loc, err := c.FindLocation(api.EvalScope{-1, 0}, "fmt/print.go:649")
|
loc, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "fmt/print.go:649")
|
||||||
assertNoError(err, t, "could not find location")
|
assertNoError(err, t, "could not find location")
|
||||||
|
|
||||||
_, err = c.CreateBreakpoint(&api.Breakpoint{File: loc[0].File, Line: loc[0].Line})
|
_, err = c.CreateBreakpoint(&api.Breakpoint{File: loc[0].File, Line: loc[0].Line})
|
||||||
|
Loading…
Reference in New Issue
Block a user