proc: Properly close channels upon process exit

Prevents a lot of goroutines hanging around, especially when running
tests.
This commit is contained in:
Derek Parker 2015-10-09 16:30:28 -07:00
parent 197c165699
commit d8dd9c8d0e
5 changed files with 21 additions and 16 deletions

@ -772,3 +772,9 @@ func (dbp *Process) ConvertEvalScope(gid, frame int) (*EvalScope, error) {
return &out, nil
}
func (dbp *Process) postExit() {
dbp.exited = true
close(dbp.ptraceChan)
close(dbp.ptraceDoneChan)
}

@ -116,7 +116,7 @@ func (dbp *Process) Kill() (err error) {
break
}
}
dbp.exited = true
dbp.postExit()
return
}
@ -276,7 +276,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
if err != nil {
return nil, err
}
dbp.exited = true
dbp.postExit()
return nil, ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()}
case C.MACH_RCV_INTERRUPTED:

@ -78,7 +78,7 @@ func (dbp *Process) Kill() (err error) {
if _, _, err = dbp.wait(dbp.Pid, 0); err != nil {
return
}
dbp.exited = true
dbp.postExit()
return
}
@ -254,7 +254,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
}
if status.Exited() {
if wpid == dbp.Pid {
dbp.exited = true
dbp.postExit()
return nil, ProcessExitedError{Pid: wpid, Status: status.ExitStatus()}
}
delete(dbp.Threads, wpid)

@ -105,6 +105,10 @@ func (d *Debugger) Restart() error {
}
func (d *Debugger) State() (*api.DebuggerState, error) {
if d.process.Exited() {
return nil, proc.ProcessExitedError{Pid: d.ProcessPid()}
}
var (
state *api.DebuggerState
thread *api.Thread
@ -226,12 +230,9 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
case api.Continue:
log.Print("continuing")
err = d.process.Continue()
state, stateErr := d.State()
if stateErr != nil {
return state, stateErr
}
if err != nil {
if exitedErr, exited := err.(proc.ProcessExitedError); exited {
state := &api.DebuggerState{}
state.Exited = true
state.ExitStatus = exitedErr.Status
state.Err = errors.New(exitedErr.Error())
@ -239,6 +240,10 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
}
return nil, err
}
state, stateErr := d.State()
if stateErr != nil {
return state, stateErr
}
err = d.collectBreakpointInformation(state)
return state, err

@ -144,14 +144,8 @@ func TestClientServer_exit(t *testing.T) {
t.Fatalf("Expected exit after continue: %v", state)
}
state, err = c.GetState()
if err != nil {
t.Fatal(err)
}
if state.CurrentThread == nil {
t.Fatalf("Expected CurrentThread")
}
if e, a := true, state.Exited; e != a {
t.Fatalf("Expected exited %v, got %v", e, a)
if err == nil {
t.Fatal("Expected error on querying state from exited process")
}
})
}