proc/native: race between RequestManualStop and trapWait
RequestManualStop will run concurrently with trapWait, since one writes dbp.halt and the other reads it dbp.halt should be protected by a mutex. Updates #830
This commit is contained in:
parent
640dedb479
commit
98142c695b
@ -37,6 +37,7 @@ type Process struct {
|
|||||||
breakpointIDCounter int
|
breakpointIDCounter int
|
||||||
internalBreakpointIDCounter int
|
internalBreakpointIDCounter int
|
||||||
firstStart bool
|
firstStart bool
|
||||||
|
haltMu sync.Mutex
|
||||||
halt bool
|
halt bool
|
||||||
exited bool
|
exited bool
|
||||||
ptraceChan chan func()
|
ptraceChan chan func()
|
||||||
@ -187,6 +188,8 @@ func (dbp *Process) RequestManualStop() error {
|
|||||||
if dbp.exited {
|
if dbp.exited {
|
||||||
return &proc.ProcessExitedError{}
|
return &proc.ProcessExitedError{}
|
||||||
}
|
}
|
||||||
|
dbp.haltMu.Lock()
|
||||||
|
defer dbp.haltMu.Unlock()
|
||||||
dbp.halt = true
|
dbp.halt = true
|
||||||
return dbp.requestManualStop()
|
return dbp.requestManualStop()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -291,7 +291,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
|||||||
return nil, proc.ProcessExitedError{Pid: dbp.pid, Status: status.ExitStatus()}
|
return nil, proc.ProcessExitedError{Pid: dbp.pid, Status: status.ExitStatus()}
|
||||||
|
|
||||||
case C.MACH_RCV_INTERRUPTED:
|
case C.MACH_RCV_INTERRUPTED:
|
||||||
if !dbp.halt {
|
dbp.haltMu.Lock()
|
||||||
|
halt := dbp.halt
|
||||||
|
dbp.haltMu.Unlock()
|
||||||
|
if !halt {
|
||||||
// Call trapWait again, it seems
|
// Call trapWait again, it seems
|
||||||
// MACH_RCV_INTERRUPTED is emitted before
|
// MACH_RCV_INTERRUPTED is emitted before
|
||||||
// process natural death _sometimes_.
|
// process natural death _sometimes_.
|
||||||
@ -319,7 +322,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
|||||||
dbp.updateThreadList()
|
dbp.updateThreadList()
|
||||||
th, ok := dbp.threads[int(port)]
|
th, ok := dbp.threads[int(port)]
|
||||||
if !ok {
|
if !ok {
|
||||||
if dbp.halt {
|
dbp.haltMu.Lock()
|
||||||
|
halt := dbp.halt
|
||||||
|
dbp.haltMu.Unlock()
|
||||||
|
if halt {
|
||||||
dbp.halt = false
|
dbp.halt = false
|
||||||
return th, nil
|
return th, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -236,7 +236,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
|
|||||||
// Sometimes we get an unknown thread, ignore it?
|
// Sometimes we get an unknown thread, ignore it?
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if status.StopSignal() == sys.SIGTRAP && dbp.halt {
|
dbp.haltMu.Lock()
|
||||||
|
halt := dbp.halt
|
||||||
|
dbp.haltMu.Unlock()
|
||||||
|
if status.StopSignal() == sys.SIGTRAP && halt {
|
||||||
th.running = false
|
th.running = false
|
||||||
dbp.halt = false
|
dbp.halt = false
|
||||||
return th, nil
|
return th, nil
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user