diff --git a/proctl/proctl.go b/proctl/proctl.go index 0124559b..8a8ac893 100644 --- a/proctl/proctl.go +++ b/proctl/proctl.go @@ -39,21 +39,6 @@ func (mse ManualStopError) Error() string { return "Manual stop requested" } -// ProcessStatus is the result of parsing the data from -// the /proc//stats psuedo file. -type ProcessStatus struct { - pid int - comm string - state rune - ppid int -} - -const ( - STATUS_SLEEPING = 'S' - STATUS_RUNNING = 'R' - STATUS_TRACE_STOP = 't' -) - var ( breakpointIDCounter = 0 ) @@ -215,8 +200,7 @@ func (dbp *DebuggedProcess) FindLocation(str string) (uint64, error) { func (dbp *DebuggedProcess) RequestManualStop() { dbp.halt = true for _, th := range dbp.Threads { - ps, _ := parseProcessStatus(th.Id) - if ps.state == STATUS_TRACE_STOP { + if stopped(th.Id) { continue } syscall.Tgkill(dbp.Pid, th.Id, syscall.SIGSTOP) @@ -493,21 +477,14 @@ func stopTheWorld(dbp *DebuggedProcess) error { // are inactive. We send SIGSTOP and ensure all // threads are in in signal-delivery-stop mode. for _, th := range dbp.Threads { - ps, err := parseProcessStatus(th.Id) - if err != nil { - return err - } - - if ps.state == STATUS_TRACE_STOP { + if stopped(th.Id) { continue } - - err = syscall.Tgkill(dbp.Pid, th.Id, syscall.SIGSTOP) + err := syscall.Tgkill(dbp.Pid, th.Id, syscall.SIGSTOP) if err != nil { return err } - - pid, _, err := wait(th.Id, 0) + pid, _, err := wait(th.Id, syscall.WNOHANG) if err != nil { return fmt.Errorf("wait err %s %d", err, pid) } diff --git a/proctl/proctl_linux_amd64.go b/proctl/proctl_linux_amd64.go index db9a2e93..3575bfa3 100644 --- a/proctl/proctl_linux_amd64.go +++ b/proctl/proctl_linux_amd64.go @@ -11,6 +11,12 @@ import ( "github.com/derekparker/delve/dwarf/frame" ) +const ( + STATUS_SLEEPING = 'S' + STATUS_RUNNING = 'R' + STATUS_TRACE_STOP = 't' +) + func (dbp *DebuggedProcess) addThread(tid int) (*ThreadContext, error) { err := syscall.PtraceSetOptions(tid, syscall.PTRACE_O_TRACECLONE) if err == syscall.ESRCH { @@ -33,18 +39,23 @@ func (dbp *DebuggedProcess) addThread(tid int) (*ThreadContext, error) { return dbp.Threads[tid], nil } -func parseProcessStatus(pid int) (*ProcessStatus, error) { - var ps ProcessStatus - +func stopped(pid int) bool { f, err := os.Open(fmt.Sprintf("/proc/%d/stat", pid)) if err != nil { - return nil, err + return false } defer f.Close() - fmt.Fscanf(f, "%d %s %c %d", &ps.pid, &ps.comm, &ps.state, &ps.ppid) - - return &ps, nil + var ( + p int + comm string + state rune + ) + fmt.Fscanf(f, "%d %s %c", &p, &comm, &state) + if state == STATUS_TRACE_STOP { + return true + } + return false } // Finds the executable from /proc//exe and then