diff --git a/proc/breakpoints.go b/proc/breakpoints.go index 3acf51f0..ae51d364 100644 --- a/proc/breakpoints.go +++ b/proc/breakpoints.go @@ -90,8 +90,15 @@ func (dbp *Process) setBreakpoint(tid int, addr uint64, temp bool) (*Breakpoint, if used { continue } - for t, _ := range dbp.Threads { - if err := dbp.setHardwareBreakpoint(i, t, addr); err != nil { + for tid, t := range dbp.Threads { + if t.running { + err := t.Halt() + if err != nil { + return nil, err + } + defer t.Continue() + } + if err := dbp.setHardwareBreakpoint(i, tid, addr); err != nil { return nil, fmt.Errorf("could not set hardware breakpoint on thread %d: %s", t, err) } } diff --git a/proc/proc_linux.go b/proc/proc_linux.go index 53414d32..90b47225 100644 --- a/proc/proc_linux.go +++ b/proc/proc_linux.go @@ -271,12 +271,15 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { continue } if status.StopSignal() == sys.SIGTRAP { + th.running = false return dbp.handleBreakpointOnThread(wpid) } if status.StopSignal() == sys.SIGTRAP && dbp.halt { + th.running = false return th, nil } if status.StopSignal() == sys.SIGSTOP && dbp.halt { + th.running = false return nil, ManualStopError{} } if th != nil { diff --git a/proc/threads.go b/proc/threads.go index 859d6ddb..ed15714e 100644 --- a/proc/threads.go +++ b/proc/threads.go @@ -65,7 +65,11 @@ func (thread *Thread) Continue() error { // Otherwise we simply execute the next instruction. func (thread *Thread) Step() (err error) { thread.singleStepping = true - defer func() { thread.singleStepping = false }() + thread.running = true + defer func() { + thread.singleStepping = false + thread.running = false + }() pc, err := thread.PC() if err != nil { return err diff --git a/proc/threads_darwin.go b/proc/threads_darwin.go index 7ef1e154..40a1271a 100644 --- a/proc/threads_darwin.go +++ b/proc/threads_darwin.go @@ -18,6 +18,7 @@ func (t *Thread) Halt() error { if kret != C.KERN_SUCCESS { return fmt.Errorf("could not suspend thread %d", t.Id) } + t.running = false return nil } @@ -35,6 +36,7 @@ func (t *Thread) singleStep() error { } func (t *Thread) resume() error { + t.running = true // TODO(dp) set flag for ptrace stops var err error t.dbp.execPtraceFunc(func() { err = PtraceCont(t.dbp.Pid, 0) }) diff --git a/proc/threads_linux.go b/proc/threads_linux.go index 28572b07..e737463a 100644 --- a/proc/threads_linux.go +++ b/proc/threads_linux.go @@ -18,16 +18,18 @@ func (t *Thread) Halt() error { } err := sys.Tgkill(t.dbp.Pid, t.Id, sys.SIGSTOP) if err != nil { - return fmt.Errorf("Halt err %s %d", err, t.Id) + return fmt.Errorf("halt err %s on thread %d", err, t.Id) } _, _, err = wait(t.Id, 0) if err != nil { - return fmt.Errorf("wait err %s %d", err, t.Id) + return fmt.Errorf("wait err %s on thread %d", err, t.Id) } + t.running = false return nil } func (t *Thread) resume() (err error) { + t.running = true t.dbp.execPtraceFunc(func() { err = PtraceCont(t.Id, 0) }) return }