service: Make Halt work during tracing (#469)

While tracing delve may spend most of its time outside of
proc.(*Process).Continue, which renders
service/rpc/client.(*Client).Halt ineffective.
This commit changes the implementation of
service/rpc/client.(*Client).Halt to make it capable of stopping traces.
This commit is contained in:
Alessandro Arzilli 2016-04-24 19:30:43 +02:00 committed by Derek Parker
parent 38127e5a00
commit 7820921b7e
2 changed files with 23 additions and 4 deletions

@ -7,6 +7,7 @@ import (
"net/rpc/jsonrpc"
"github.com/derekparker/delve/service/api"
"sync"
)
// Client is a RPC service.Client.
@ -14,6 +15,8 @@ type RPCClient struct {
addr string
processPid int
client *rpc.Client
haltMu sync.Mutex
haltReq bool
}
// NewClient creates a new RPCClient.
@ -50,8 +53,18 @@ func (c *RPCClient) GetState() (*api.DebuggerState, error) {
func (c *RPCClient) Continue() <-chan *api.DebuggerState {
ch := make(chan *api.DebuggerState)
c.haltMu.Lock()
c.haltReq = false
c.haltMu.Unlock()
go func() {
for {
c.haltMu.Lock()
if c.haltReq {
c.haltMu.Unlock()
close(ch)
return
}
c.haltMu.Unlock()
state := new(api.DebuggerState)
err := c.call("Command", &api.DebuggerCommand{Name: api.Continue}, state)
if err != nil {
@ -125,6 +138,9 @@ func (c *RPCClient) SwitchGoroutine(goroutineID int) (*api.DebuggerState, error)
func (c *RPCClient) Halt() (*api.DebuggerState, error) {
state := new(api.DebuggerState)
c.haltMu.Lock()
c.haltReq = true
c.haltMu.Unlock()
err := c.call("Command", &api.DebuggerCommand{Name: api.Halt}, state)
return state, err
}

@ -438,12 +438,14 @@ func restart(t *Term, ctx callContext, args string) error {
func cont(t *Term, ctx callContext, args string) error {
stateChan := t.client.Continue()
for state := range stateChan {
var state *api.DebuggerState
for state = range stateChan {
if state.Err != nil {
return state.Err
}
printcontext(t, state)
}
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
return nil
}
@ -453,6 +455,7 @@ func step(t *Term, ctx callContext, args string) error {
return err
}
printcontext(t, state)
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
return nil
}
@ -462,6 +465,7 @@ func stepInstruction(t *Term, ctx callContext, args string) error {
return err
}
printcontext(t, state)
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
return nil
}
@ -471,6 +475,7 @@ func next(t *Term, ctx callContext, args string) error {
return err
}
printcontext(t, state)
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
return nil
}
@ -836,6 +841,7 @@ func listCommand(t *Term, ctx callContext, args string) error {
return err
}
printcontext(t, state)
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
return nil
}
@ -973,9 +979,6 @@ func printcontext(t *Term, state *api.DebuggerState) error {
printcontextThread(t, state.CurrentThread)
if state.CurrentThread.Breakpoint == nil || !state.CurrentThread.Breakpoint.Tracepoint || state.CurrentThread.BreakpointInfo == nil {
return printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
}
return nil
}