提交 e7a9daf2 编写于 作者: D Derek Parker

Return thread directly from trapWait

上级 c6d9b0e6
...@@ -279,32 +279,28 @@ func (dbp *DebuggedProcess) next() error { ...@@ -279,32 +279,28 @@ func (dbp *DebuggedProcess) next() error {
} }
for { for {
tid, err := trapWait(dbp, -1) thread, err := trapWait(dbp, -1)
if err != nil { if err != nil {
return err return err
} }
th, ok := dbp.Threads[tid] pc, err := thread.CurrentPC()
if !ok {
return fmt.Errorf("unknown thread %d", tid)
}
pc, err := th.CurrentPC()
if err != nil { if err != nil {
return err return err
} }
// Check if we've hit a software breakpoint. If so, reset PC. // Check if we've hit a software breakpoint. If so, reset PC.
if err = th.clearTempBreakpoint(pc - 1); err != nil { if err = thread.clearTempBreakpoint(pc - 1); err != nil {
return err return err
} }
// Grab the current goroutine for this thread. // Grab the current goroutine for this thread.
tg, err := th.curG() tg, err := thread.curG()
if err != nil { if err != nil {
return err return err
} }
// Make sure we're on the same goroutine. // Make sure we're on the same goroutine.
// TODO(dp) take into account goroutine exit. // TODO(dp) take into account goroutine exit.
if tg.id == curg.id { if tg.id == curg.id {
if dbp.CurrentThread.Id != tid { if dbp.CurrentThread != thread {
dbp.SwitchThread(tid) dbp.SwitchThread(thread.Id)
} }
break break
} }
...@@ -322,20 +318,13 @@ func (dbp *DebuggedProcess) Continue() error { ...@@ -322,20 +318,13 @@ func (dbp *DebuggedProcess) Continue() error {
} }
fn := func() error { fn := func() error {
wpid, err := trapWait(dbp, -1) thread, err := trapWait(dbp, -1)
if err != nil { if err != nil {
return err return err
} }
if dbp.CurrentThread != thread {
thread, ok := dbp.Threads[wpid] dbp.SwitchThread(thread.Id)
if !ok {
return fmt.Errorf("could not find thread for %d", wpid)
}
if wpid != dbp.CurrentThread.Id {
dbp.SwitchThread(wpid)
} }
pc, err := thread.CurrentPC() pc, err := thread.CurrentPC()
if err != nil { if err != nil {
return err return err
......
...@@ -171,17 +171,17 @@ func (dbp *DebuggedProcess) findExecutable() (*macho.File, error) { ...@@ -171,17 +171,17 @@ func (dbp *DebuggedProcess) findExecutable() (*macho.File, error) {
return exe, nil return exe, nil
} }
func trapWait(dbp *DebuggedProcess, pid int) (int, error) { func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, error) {
port := C.mach_port_wait(dbp.os.portSet) port := C.mach_port_wait(dbp.os.portSet)
switch port { switch port {
case dbp.os.notificationPort: case dbp.os.notificationPort:
_, status, err := wait(dbp.Pid, 0) _, status, err := wait(dbp.Pid, 0)
if err != nil { if err != nil {
return -1, err return nil, err
} }
dbp.exited = true dbp.exited = true
return -1, ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()} return nil, ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()}
case C.MACH_RCV_INTERRUPTED: case C.MACH_RCV_INTERRUPTED:
if !dbp.halt { if !dbp.halt {
// Call trapWait again, it seems // Call trapWait again, it seems
...@@ -189,16 +189,19 @@ func trapWait(dbp *DebuggedProcess, pid int) (int, error) { ...@@ -189,16 +189,19 @@ func trapWait(dbp *DebuggedProcess, pid int) (int, error) {
// process natural death _sometimes_. // process natural death _sometimes_.
return trapWait(dbp, pid) return trapWait(dbp, pid)
} }
return -1, ManualStopError{} return nil, ManualStopError{}
case 0: case 0:
return -1, fmt.Errorf("error while waiting for task") return nil, fmt.Errorf("error while waiting for task")
} }
// Since we cannot be notified of new threads on OS X // Since we cannot be notified of new threads on OS X
// this is as good a time as any to check for them. // this is as good a time as any to check for them.
dbp.updateThreadList() dbp.updateThreadList()
thread, ok := dbp.Threads[int(port)]
return int(port), nil if !ok {
return nil, fmt.Errorf("could not find thread for %d", port)
}
return thread, nil
} }
func wait(pid, options int) (int, *sys.WaitStatus, error) { func wait(pid, options int) (int, *sys.WaitStatus, error) {
......
...@@ -216,11 +216,11 @@ func stopped(pid int) bool { ...@@ -216,11 +216,11 @@ func stopped(pid int) bool {
return false return false
} }
func trapWait(dbp *DebuggedProcess, pid int) (int, error) { func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, error) {
for { for {
wpid, status, err := wait(pid, 0) wpid, status, err := wait(pid, 0)
if err != nil { if err != nil {
return -1, fmt.Errorf("wait err %s %d", err, pid) return nil, fmt.Errorf("wait err %s %d", err, pid)
} }
if wpid == 0 { if wpid == 0 {
continue continue
...@@ -231,37 +231,41 @@ func trapWait(dbp *DebuggedProcess, pid int) (int, error) { ...@@ -231,37 +231,41 @@ func trapWait(dbp *DebuggedProcess, pid int) (int, error) {
if status.Exited() && wpid == dbp.Pid { if status.Exited() && wpid == dbp.Pid {
dbp.exited = true dbp.exited = true
return -1, ProcessExitedError{Pid: wpid, Status: status.ExitStatus()} return nil, ProcessExitedError{Pid: wpid, Status: status.ExitStatus()}
} }
if status.StopSignal() == sys.SIGTRAP && status.TrapCause() == sys.PTRACE_EVENT_CLONE { if status.StopSignal() == sys.SIGTRAP && status.TrapCause() == sys.PTRACE_EVENT_CLONE {
// A traced thread has cloned a new thread, grab the pid and // A traced thread has cloned a new thread, grab the pid and
// add it to our list of traced threads. // add it to our list of traced threads.
cloned, err := sys.PtraceGetEventMsg(wpid) cloned, err := sys.PtraceGetEventMsg(wpid)
if err != nil { if err != nil {
return -1, fmt.Errorf("could not get event message: %s", err) return nil, fmt.Errorf("could not get event message: %s", err)
} }
th, err := dbp.addThread(int(cloned), false) th, err := dbp.addThread(int(cloned), false)
if err != nil { if err != nil {
return -1, err return nil, err
} }
err = th.Continue() err = th.Continue()
if err != nil { if err != nil {
return -1, fmt.Errorf("could not continue new thread %d %s", cloned, err) return nil, fmt.Errorf("could not continue new thread %d %s", cloned, err)
} }
err = dbp.Threads[int(wpid)].Continue() err = dbp.Threads[int(wpid)].Continue()
if err != nil { if err != nil {
return -1, fmt.Errorf("could not continue new thread %d %s", cloned, err) return nil, fmt.Errorf("could not continue new thread %d %s", cloned, err)
} }
continue continue
} }
if status.StopSignal() == sys.SIGTRAP { if status.StopSignal() == sys.SIGTRAP {
return wpid, nil thread, ok := dbp.Threads[wpid]
if !ok {
return nil, fmt.Errorf("could not find thread for %d", wpid)
}
return thread, nil
} }
if status.StopSignal() == sys.SIGSTOP && dbp.halt { if status.StopSignal() == sys.SIGSTOP && dbp.halt {
return -1, ManualStopError{} return nil, ManualStopError{}
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册