proc: bugfix: race condition between termination and Continue (linux)
resume loops in continueOnce moved to a OS specific resume function, this makes the problem easier to deal with and seems to be more appropriate to a windows port given what transpired from discussion of Pull Request #276
This commit is contained in:
parent
2f9f20188a
commit
5354e462e8
16
proc/proc.go
16
proc/proc.go
@ -389,20 +389,8 @@ func (dbp *Process) runBreakpointConditions() error {
|
|||||||
|
|
||||||
// Resume process, does not evaluate breakpoint conditionals
|
// Resume process, does not evaluate breakpoint conditionals
|
||||||
func (dbp *Process) continueOnce() error {
|
func (dbp *Process) continueOnce() error {
|
||||||
// all threads stopped over a breakpoint are made to step over it
|
if err := dbp.resume(); err != nil {
|
||||||
for _, thread := range dbp.Threads {
|
return err
|
||||||
if thread.CurrentBreakpoint != nil {
|
|
||||||
if err := thread.Step(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
thread.CurrentBreakpoint = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// everything is resumed
|
|
||||||
for _, thread := range dbp.Threads {
|
|
||||||
if err := thread.resume(); err != nil {
|
|
||||||
return dbp.exitGuard(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dbp.run(func() error {
|
return dbp.run(func() error {
|
||||||
thread, err := dbp.trapWait(-1)
|
thread, err := dbp.trapWait(-1)
|
||||||
|
@ -354,3 +354,22 @@ func (dbp *Process) exitGuard(err error) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dbp *Process) resume() error {
|
||||||
|
// all threads stopped over a breakpoint are made to step over it
|
||||||
|
for _, thread := range dbp.Threads {
|
||||||
|
if thread.CurrentBreakpoint != nil {
|
||||||
|
if err := thread.Step(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
thread.CurrentBreakpoint = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// everything is resumed
|
||||||
|
for _, thread := range dbp.Threads {
|
||||||
|
if err := thread.resume(); err != nil {
|
||||||
|
return dbp.exitGuard(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -286,7 +286,9 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
|||||||
return nil, fmt.Errorf("could not continue new thread %d %s", cloned, err)
|
return nil, fmt.Errorf("could not continue new thread %d %s", cloned, err)
|
||||||
}
|
}
|
||||||
if err = dbp.Threads[int(wpid)].Continue(); err != nil {
|
if err = dbp.Threads[int(wpid)].Continue(); err != nil {
|
||||||
return nil, fmt.Errorf("could not continue existing thread %d %s", cloned, err)
|
if err != sys.ESRCH {
|
||||||
|
return nil, fmt.Errorf("could not continue existing thread %d %s", wpid, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -401,3 +403,22 @@ func (dbp *Process) exitGuard(err error) error {
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dbp *Process) resume() error {
|
||||||
|
// all threads stopped over a breakpoint are made to step over it
|
||||||
|
for _, thread := range dbp.Threads {
|
||||||
|
if thread.CurrentBreakpoint != nil {
|
||||||
|
if err := thread.Step(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
thread.CurrentBreakpoint = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// everything is resumed
|
||||||
|
for _, thread := range dbp.Threads {
|
||||||
|
if err := thread.resume(); err != nil && err != sys.ESRCH {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user