2014-05-21 15:23:14 +00:00
|
|
|
// Package proctl provides functions for attaching to and manipulating
|
|
|
|
// a process during the debug session.
|
2014-05-20 18:23:35 +00:00
|
|
|
package proctl
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"syscall"
|
|
|
|
)
|
|
|
|
|
2014-05-21 15:23:14 +00:00
|
|
|
// Struct representing a debugged process. Holds onto pid, register values,
|
|
|
|
// process struct and process state.
|
2014-05-20 18:23:35 +00:00
|
|
|
type DebuggedProcess struct {
|
2014-05-20 18:23:36 +00:00
|
|
|
Pid int
|
|
|
|
Regs *syscall.PtraceRegs
|
|
|
|
Process *os.Process
|
|
|
|
ProcessState *os.ProcessState
|
2014-05-20 18:23:35 +00:00
|
|
|
}
|
|
|
|
|
2014-05-21 15:23:14 +00:00
|
|
|
// Returns a new DebuggedProcess struct with sensible defaults.
|
2014-05-20 18:23:35 +00:00
|
|
|
func NewDebugProcess(pid int) (*DebuggedProcess, error) {
|
|
|
|
err := syscall.PtraceAttach(pid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
proc, err := os.FindProcess(pid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-05-20 18:23:36 +00:00
|
|
|
ps, err := proc.Wait()
|
2014-05-20 18:23:35 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-05-20 18:23:36 +00:00
|
|
|
debuggedProc := DebuggedProcess{
|
|
|
|
Pid: pid,
|
|
|
|
Regs: &syscall.PtraceRegs{},
|
|
|
|
Process: proc,
|
|
|
|
ProcessState: ps,
|
|
|
|
}
|
|
|
|
|
2014-05-20 18:23:35 +00:00
|
|
|
return &debuggedProc, nil
|
|
|
|
}
|
|
|
|
|
2014-05-21 15:23:14 +00:00
|
|
|
// Obtains register values from the debugged process.
|
2014-05-20 18:23:35 +00:00
|
|
|
func (dbp *DebuggedProcess) Registers() (*syscall.PtraceRegs, error) {
|
|
|
|
err := syscall.PtraceGetRegs(dbp.Pid, dbp.Regs)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Registers():", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return dbp.Regs, nil
|
|
|
|
}
|
|
|
|
|
2014-05-21 15:23:14 +00:00
|
|
|
// Steps through process.
|
2014-05-20 18:23:35 +00:00
|
|
|
func (dbp *DebuggedProcess) Step() error {
|
2014-05-21 15:23:45 +00:00
|
|
|
return dbp.handleResult(syscall.PtraceSingleStep(dbp.Pid))
|
2014-05-20 18:23:35 +00:00
|
|
|
}
|
2014-05-20 18:23:36 +00:00
|
|
|
|
2014-05-21 15:23:14 +00:00
|
|
|
// Continue process until next breakpoint.
|
2014-05-20 18:23:36 +00:00
|
|
|
func (dbp *DebuggedProcess) Continue() error {
|
2014-05-21 15:23:45 +00:00
|
|
|
return dbp.handleResult(syscall.PtraceCont(dbp.Pid, 0))
|
2014-05-20 20:15:52 +00:00
|
|
|
}
|
|
|
|
|
2014-05-21 15:23:45 +00:00
|
|
|
func (dbp *DebuggedProcess) handleResult(err error) error {
|
2014-05-20 18:23:36 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ps, err := dbp.Process.Wait()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
dbp.ProcessState = ps
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|