mirror of
https://github.com/go-delve/delve.git
synced 2025-11-02 21:40:22 +08:00
proc, terminal: stepout command
Command to step out of the currently executing function. Implements #358
This commit is contained in:
@ -237,6 +237,8 @@ const (
|
||||
Continue = "continue"
|
||||
// Step continues to next source line, entering function calls.
|
||||
Step = "step"
|
||||
// StepOut continues to the return address of the current function
|
||||
StepOut = "stepOut"
|
||||
// SingleStep continues for exactly 1 cpu instruction.
|
||||
StepInstruction = "stepInstruction"
|
||||
// Next continues to the next source line, not entering function calls.
|
||||
|
||||
@ -25,6 +25,9 @@ type Client interface {
|
||||
Next() (*api.DebuggerState, error)
|
||||
// Step continues to the next source line, entering function calls.
|
||||
Step() (*api.DebuggerState, error)
|
||||
// StepOut continues to the return address of the current function
|
||||
StepOut() (*api.DebuggerState, error)
|
||||
|
||||
// SingleStep will step a single cpu instruction.
|
||||
StepInstruction() (*api.DebuggerState, error)
|
||||
// SwitchThread switches the current thread context.
|
||||
|
||||
@ -418,6 +418,9 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
|
||||
case api.StepInstruction:
|
||||
log.Print("single stepping")
|
||||
err = d.process.StepInstruction()
|
||||
case api.StepOut:
|
||||
log.Print("step out")
|
||||
err = d.process.StepOut()
|
||||
case api.SwitchThread:
|
||||
log.Printf("switching to thread %d", command.ThreadID)
|
||||
err = d.process.SwitchThread(command.ThreadID)
|
||||
|
||||
@ -103,6 +103,12 @@ func (c *RPCClient) Step() (*api.DebuggerState, error) {
|
||||
return &out.State, err
|
||||
}
|
||||
|
||||
func (c *RPCClient) StepOut() (*api.DebuggerState, error) {
|
||||
var out CommandOut
|
||||
err := c.call("Command", &api.DebuggerCommand{ Name: api.StepOut}, &out)
|
||||
return &out.State, err
|
||||
}
|
||||
|
||||
func (c *RPCClient) StepInstruction() (*api.DebuggerState, error) {
|
||||
var out CommandOut
|
||||
err := c.call("Command", api.DebuggerCommand{Name: api.StepInstruction}, &out)
|
||||
|
||||
@ -199,6 +199,23 @@ func TestClientServer_step(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestClientServer_stepout(t *testing.T) {
|
||||
withTestClient2("testnextprog", t, func(c service.Client) {
|
||||
_, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: "main.helloworld", Line: -1})
|
||||
assertNoError(err, t, "CreateBreakpoint()")
|
||||
stateBefore := <-c.Continue()
|
||||
assertNoError(stateBefore.Err, t, "Continue()")
|
||||
if stateBefore.CurrentThread.Line != 13 {
|
||||
t.Fatalf("wrong line number %s:%d, expected %d", stateBefore.CurrentThread.File, stateBefore.CurrentThread.Line, 13)
|
||||
}
|
||||
stateAfter, err := c.StepOut()
|
||||
assertNoError(err, t, "StepOut()")
|
||||
if stateAfter.CurrentThread.Line != 35 {
|
||||
t.Fatalf("wrong line number %s:%d, expected %d", stateAfter.CurrentThread.File, stateAfter.CurrentThread.Line, 13)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func testnext2(testcases []nextTest, initialLocation string, t *testing.T) {
|
||||
withTestClient2("testnextprog", t, func(c service.Client) {
|
||||
bp, err := c.CreateBreakpoint(&api.Breakpoint{FunctionName: initialLocation, Line: -1})
|
||||
@ -278,7 +295,7 @@ func TestNextGeneral(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
testnext(testcases, "main.testnext", t)
|
||||
testnext2(testcases, "main.testnext", t)
|
||||
}
|
||||
|
||||
func TestNextFunctionReturn(t *testing.T) {
|
||||
@ -287,7 +304,7 @@ func TestNextFunctionReturn(t *testing.T) {
|
||||
{14, 15},
|
||||
{15, 35},
|
||||
}
|
||||
testnext(testcases, "main.helloworld", t)
|
||||
testnext2(testcases, "main.helloworld", t)
|
||||
}
|
||||
|
||||
func TestClientServer_breakpointInMainThread(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user