mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 17:56:45 +08:00
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:
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) })
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user