From e5a4a5ae9be3ba975ee98b7f101c1a5c0cef0a24 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Thu, 9 Apr 2015 10:01:58 -0500 Subject: [PATCH] Set CurrentBreakpoint on DebuggedProcess --- proctl/proctl.go | 28 ++++++++++++++++------------ proctl/proctl_darwin.go | 10 +++++----- proctl/proctl_linux.go | 16 ++++++++-------- proctl/threads.go | 2 +- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/proctl/proctl.go b/proctl/proctl.go index 4f7f9b99..da2e4be8 100644 --- a/proctl/proctl.go +++ b/proctl/proctl.go @@ -31,6 +31,7 @@ type DebuggedProcess struct { HWBreakPoints [4]*BreakPoint BreakPoints map[uint64]*BreakPoint Threads map[int]*ThreadContext + CurrentBreakpoint *BreakPoint CurrentThread *ThreadContext dwarf *dwarf.Data goSymTable *gosym.Table @@ -280,13 +281,13 @@ func (dbp *DebuggedProcess) next() error { } for { - thread, breakpoint, err := trapWait(dbp, -1) + thread, err := trapWait(dbp, -1) if err != nil { return err } // Check if we've hit a breakpoint. - if breakpoint != nil { - if err = thread.clearTempBreakpoint(breakpoint.Addr); err != nil { + if dbp.CurrentBreakpoint != nil { + if err = thread.clearTempBreakpoint(dbp.CurrentBreakpoint.Addr); err != nil { return err } } @@ -319,7 +320,7 @@ func (dbp *DebuggedProcess) Continue() error { } func (dbp *DebuggedProcess) resume() error { - thread, breakpoint, err := trapWait(dbp, -1) + thread, err := trapWait(dbp, -1) if err != nil { return err } @@ -330,8 +331,8 @@ func (dbp *DebuggedProcess) resume() error { if err != nil { return err } - if breakpoint != nil { - if !breakpoint.Temp { + if dbp.CurrentBreakpoint != nil { + if !dbp.CurrentBreakpoint.Temp { return dbp.Halt() } } @@ -512,26 +513,28 @@ func (dbp *DebuggedProcess) clearTempBreakpoints() error { } return nil } -func (dbp *DebuggedProcess) handleBreakpointOnThread(id int) (*ThreadContext, *BreakPoint, error) { +func (dbp *DebuggedProcess) handleBreakpointOnThread(id int) (*ThreadContext, error) { thread, ok := dbp.Threads[id] if !ok { - return nil, nil, fmt.Errorf("could not find thread for %d", id) + return nil, fmt.Errorf("could not find thread for %d", id) } pc, err := thread.CurrentPC() if err != nil { - return nil, nil, err + return nil, err } // Check for hardware breakpoint for _, bp := range dbp.HWBreakPoints { if bp != nil && bp.Addr == pc { - return thread, bp, nil + dbp.CurrentBreakpoint = bp + return thread, nil } } // Check to see if we have hit a software breakpoint. if bp, ok := dbp.BreakPoints[pc-1]; ok { - return thread, bp, nil + dbp.CurrentBreakpoint = bp + return thread, nil } - return thread, nil, nil + return thread, nil } func (dbp *DebuggedProcess) run(fn func() error) error { @@ -540,6 +543,7 @@ func (dbp *DebuggedProcess) run(fn func() error) error { } dbp.running = true dbp.halt = false + dbp.CurrentBreakpoint = nil defer func() { dbp.running = false }() if err := fn(); err != nil { if _, ok := err.(ManualStopError); !ok { diff --git a/proctl/proctl_darwin.go b/proctl/proctl_darwin.go index 845e8261..881d55b7 100644 --- a/proctl/proctl_darwin.go +++ b/proctl/proctl_darwin.go @@ -171,17 +171,17 @@ func (dbp *DebuggedProcess) findExecutable() (*macho.File, error) { return exe, nil } -func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, *BreakPoint, error) { +func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, error) { port := C.mach_port_wait(dbp.os.portSet) switch port { case dbp.os.notificationPort: _, status, err := wait(dbp.Pid, 0) if err != nil { - return nil, nil, err + return nil, err } dbp.exited = true - return nil, nil, ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()} + return nil, ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()} case C.MACH_RCV_INTERRUPTED: if !dbp.halt { // Call trapWait again, it seems @@ -189,9 +189,9 @@ func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, *BreakPoint, error // process natural death _sometimes_. return trapWait(dbp, pid) } - return nil, nil, ManualStopError{} + return nil, ManualStopError{} case 0: - return nil, nil, 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 diff --git a/proctl/proctl_linux.go b/proctl/proctl_linux.go index 832a5ab1..e3503f41 100644 --- a/proctl/proctl_linux.go +++ b/proctl/proctl_linux.go @@ -216,11 +216,11 @@ func stopped(pid int) bool { return false } -func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, *BreakPoint, error) { +func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, error) { for { wpid, status, err := wait(pid, 0) if err != nil { - return nil, nil, fmt.Errorf("wait err %s %d", err, pid) + return nil, fmt.Errorf("wait err %s %d", err, pid) } if wpid == 0 { continue @@ -231,29 +231,29 @@ func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, *BreakPoint, error if status.Exited() && wpid == dbp.Pid { dbp.exited = true - return nil, nil, 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 { // A traced thread has cloned a new thread, grab the pid and // add it to our list of traced threads. cloned, err := sys.PtraceGetEventMsg(wpid) if err != nil { - return nil, nil, 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) if err != nil { - return nil, nil, err + return nil, err } err = th.Continue() if err != nil { - return nil, nil, 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() if err != nil { - return nil, nil, 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 } @@ -261,7 +261,7 @@ func trapWait(dbp *DebuggedProcess, pid int) (*ThreadContext, *BreakPoint, error return dbp.handleBreakpointOnThread(wpid) } if status.StopSignal() == sys.SIGSTOP && dbp.halt { - return nil, nil, ManualStopError{} + return nil, ManualStopError{} } } } diff --git a/proctl/threads.go b/proctl/threads.go index 7c54a2f4..7b8d0828 100644 --- a/proctl/threads.go +++ b/proctl/threads.go @@ -131,7 +131,7 @@ func (thread *ThreadContext) CallFn(name string, fn func(*ThreadContext) error) if err := thread.Continue(); err != nil { return err } - if _, _, err = trapWait(thread.Process, -1); err != nil { + if _, err = trapWait(thread.Process, -1); err != nil { return err } return fn(thread) -- GitLab