proc: Properly close channels upon process exit
Prevents a lot of goroutines hanging around, especially when running tests.
This commit is contained in:
parent
197c165699
commit
d8dd9c8d0e
@ -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")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user