Skip to content

Commit

Permalink
proc/native: race between RequestManualStop and trapWait
Browse files Browse the repository at this point in the history
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 go-delve#830
  • Loading branch information
aarzilli committed Jun 13, 2017
1 parent 640dedb commit 98142c6
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
3 changes: 3 additions & 0 deletions pkg/proc/native/proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Process struct {
breakpointIDCounter int
internalBreakpointIDCounter int
firstStart bool
haltMu sync.Mutex
halt bool
exited bool
ptraceChan chan func()
Expand Down Expand Up @@ -187,6 +188,8 @@ func (dbp *Process) RequestManualStop() error {
if dbp.exited {
return &proc.ProcessExitedError{}
}
dbp.haltMu.Lock()
defer dbp.haltMu.Unlock()
dbp.halt = true
return dbp.requestManualStop()
}
Expand Down
10 changes: 8 additions & 2 deletions pkg/proc/native/proc_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
return nil, proc.ProcessExitedError{Pid: dbp.pid, Status: status.ExitStatus()}

case C.MACH_RCV_INTERRUPTED:
if !dbp.halt {
dbp.haltMu.Lock()
halt := dbp.halt
dbp.haltMu.Unlock()
if !halt {
// Call trapWait again, it seems
// MACH_RCV_INTERRUPTED is emitted before
// process natural death _sometimes_.
Expand Down Expand Up @@ -319,7 +322,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
dbp.updateThreadList()
th, ok := dbp.threads[int(port)]
if !ok {
if dbp.halt {
dbp.haltMu.Lock()
halt := dbp.halt
dbp.haltMu.Unlock()
if halt {
dbp.halt = false
return th, nil
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/proc/native/proc_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,10 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
// Sometimes we get an unknown thread, ignore it?
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
dbp.halt = false
return th, nil
Expand Down

0 comments on commit 98142c6

Please sign in to comment.