Ensure thread is stopped before setting breakpoint

For hardware breakpoints we have to set them on every thread. It could
be the case that another thread is running. Stop it first, set the
breakpoint, then continue it.
This commit is contained in:
Derek Parker
2015-06-24 09:29:16 -05:00
parent 7c8fd02685
commit b35a743a3c
5 changed files with 23 additions and 5 deletions

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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) })

View File

@ -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
}