提交 450e5c48 编写于 作者: D Derek Parker

Fix linux compile errors

上级 35a0471f
...@@ -52,6 +52,7 @@ func Attach(pid int) (*DebuggedProcess, error) { ...@@ -52,6 +52,7 @@ func Attach(pid int) (*DebuggedProcess, error) {
return nil, err return nil, err
} }
// Attach to all currently active threads. // Attach to all currently active threads.
// TODO(dp) doing this in newDebugProcess already for mach
if err := dbp.updateThreadList(); err != nil { if err := dbp.updateThreadList(); err != nil {
return nil, err return nil, err
} }
...@@ -289,6 +290,44 @@ func (dbp *DebuggedProcess) DwarfReader() *reader.Reader { ...@@ -289,6 +290,44 @@ func (dbp *DebuggedProcess) DwarfReader() *reader.Reader {
return reader.New(dbp.Dwarf) return reader.New(dbp.Dwarf)
} }
// Returns a new DebuggedProcess struct.
func newDebugProcess(pid int, attach bool) (*DebuggedProcess, error) {
dbp := DebuggedProcess{
Pid: pid,
Threads: make(map[int]*ThreadContext),
BreakPoints: make(map[uint64]*BreakPoint),
os: new(OSProcessDetails),
}
if attach {
err := sys.PtraceAttach(pid)
if err != nil {
return nil, err
}
_, _, err = wait(pid, 0)
if err != nil {
return nil, err
}
}
proc, err := os.FindProcess(pid)
if err != nil {
return nil, err
}
dbp.Process = proc
err = dbp.LoadInformation()
if err != nil {
return nil, err
}
if err := dbp.updateThreadList(); err != nil {
return nil, err
}
return &dbp, nil
}
func (dbp *DebuggedProcess) run(fn func() error) error { func (dbp *DebuggedProcess) run(fn func() error) error {
dbp.running = true dbp.running = true
dbp.halt = false dbp.halt = false
......
...@@ -62,33 +62,6 @@ func (dbp *DebuggedProcess) LoadInformation() error { ...@@ -62,33 +62,6 @@ func (dbp *DebuggedProcess) LoadInformation() error {
return nil return nil
} }
// Returns a new DebuggedProcess struct.
func newDebugProcess(pid int, attach bool) (*DebuggedProcess, error) {
dbp := DebuggedProcess{
Pid: pid,
Threads: make(map[int]*ThreadContext),
BreakPoints: make(map[uint64]*BreakPoint),
os: new(OSProcessDetails),
}
proc, err := os.FindProcess(pid)
if err != nil {
return nil, err
}
dbp.Process = proc
err = dbp.LoadInformation()
if err != nil {
return nil, err
}
if err := dbp.updateThreadList(); err != nil {
return nil, err
}
return &dbp, nil
}
func (dbp *DebuggedProcess) updateThreadList() error { func (dbp *DebuggedProcess) updateThreadList() error {
var ( var (
err error err error
......
...@@ -33,44 +33,6 @@ func (dbp *DebuggedProcess) Halt() (err error) { ...@@ -33,44 +33,6 @@ func (dbp *DebuggedProcess) Halt() (err error) {
return nil return nil
} }
// Steps through process.
func (dbp *DebuggedProcess) Step() (err error) {
var (
th *ThreadContext
ok bool
)
allm, err := dbp.CurrentThread.AllM()
if err != nil {
return err
}
fn := func() error {
for _, m := range allm {
th, ok = dbp.Threads[m.procid]
fmt.Println(ok, m.procid)
if !ok {
if m.procid == 0 {
// TODO(dp) might not work for linux
th = dbp.Threads[dbp.CurrentThread.Id]
}
return fmt.Errorf("m->procid is invalid port")
}
if m.blocked == 0 {
err := th.Step()
if err != nil {
return err
}
}
}
return nil
}
return dbp.run(fn)
}
// Finds the executable from /proc/<pid>/exe and then // Finds the executable from /proc/<pid>/exe and then
// uses that to parse the following information: // uses that to parse the following information:
// * Dwarf .debug_frame section // * Dwarf .debug_frame section
...@@ -144,19 +106,21 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err ...@@ -144,19 +106,21 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
return dbp.Threads[tid], nil return dbp.Threads[tid], nil
} }
func (dbp *DebuggedProcess) refreshThreadList() error { func (dbp *DebuggedProcess) updateThreadList() error {
allm, err := dbp.CurrentThread.AllM() allm, err := dbp.CurrentThread.AllM()
if err != nil { if err != nil {
return err return err
} }
// TODO(dp) user /proc/<pid>/task to remove reliance on allm
for _, m := range allm { for _, m := range allm {
if tid == 0 { if m.procid == 0 {
continue continue
} }
if _, err := dbp.addThread(m.procid, false); err != nil { if _, err := dbp.addThread(m.procid, false); err != nil {
return err return err
} }
} }
return nil
} }
func (dbp *DebuggedProcess) findExecutable() (*elf.File, error) { func (dbp *DebuggedProcess) findExecutable() (*elf.File, error) {
...@@ -232,46 +196,11 @@ func (dbp *DebuggedProcess) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) { ...@@ -232,46 +196,11 @@ func (dbp *DebuggedProcess) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) {
dbp.GoSymTable = tab dbp.GoSymTable = tab
} }
func newDebugProcess(pid int, attach bool) (*DebuggedProcess, error) { // TODO(dp) seems like it could be unneccessary
dbp := DebuggedProcess{
Pid: pid,
Threads: make(map[int]*ThreadContext),
BreakPoints: make(map[uint64]*BreakPoint),
os: new(OSProcessDetails),
}
if attach {
thread, err := dbp.AttachThread(pid)
if err != nil {
return nil, err
}
dbp.CurrentThread = thread
} else {
thread, err := dbp.addThread(pid)
if err != nil {
return nil, err
}
dbp.CurrentThread = thread
}
proc, err := os.FindProcess(pid)
if err != nil {
return nil, err
}
dbp.Process = proc
err = dbp.LoadInformation()
if err != nil {
return nil, err
}
return &dbp, nil
}
func addNewThread(dbp *DebuggedProcess, cloner, cloned int) error { func addNewThread(dbp *DebuggedProcess, cloner, cloned int) error {
fmt.Println("new thread spawned", cloned) fmt.Println("new thread spawned", cloned)
th, err := dbp.addThread(cloned) th, err := dbp.addThread(cloned, false)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -14,14 +14,14 @@ func (r *Regs) SP() uint64 { ...@@ -14,14 +14,14 @@ func (r *Regs) SP() uint64 {
return r.regs.Rsp return r.regs.Rsp
} }
func (r *Regs) SetPC(tid int, pc uint64) error { func (r *Regs) SetPC(thread *ThreadContext, pc uint64) error {
r.regs.SetPC(pc) r.regs.SetPC(pc)
return sys.PtraceSetRegs(tid, r.regs) return sys.PtraceSetRegs(thread.Id, r.regs)
} }
func registers(tid int) (Registers, error) { func registers(thread *ThreadContext) (Registers, error) {
var regs sys.PtraceRegs var regs sys.PtraceRegs
err := sys.PtraceGetRegs(tid, &regs) err := sys.PtraceGetRegs(thread.Id, &regs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -16,32 +16,43 @@ func (t *ThreadContext) Halt() error { ...@@ -16,32 +16,43 @@ func (t *ThreadContext) Halt() error {
} }
err := sys.Tgkill(t.Process.Pid, t.Id, sys.SIGSTOP) err := sys.Tgkill(t.Process.Pid, t.Id, sys.SIGSTOP)
if err != nil { if err != nil {
return fmt.Errorf("Halt err %s %d", err, pid) return fmt.Errorf("Halt err %s %d", err, t.Id)
} }
pid, _, err := wait(th.Id, sys.WNOHANG) _, _, err = wait(t.Id, sys.WNOHANG)
if err != nil { if err != nil {
return fmt.Errorf("wait err %s %d", err, pid) return fmt.Errorf("wait err %s %d", err, t.Id)
} }
return nil return nil
} }
func (t *ThreadContext) cont() error { func (t *ThreadContext) cont() error {
return PtraceCont(thread.Id, 0) return PtraceCont(t.Id, 0)
} }
func (t *ThreadContext) singleStep() error { func (t *ThreadContext) singleStep() error {
err := sys.PtraceSingleStep(t.Id) err := sys.PtraceSingleStep(t.Id)
if err != nill { if err != nil {
return err return err
} }
_, _, err = wait(thread.Id, 0) _, _, err = wait(t.Id, 0)
return err return err
} }
func writeMemory(tid int, addr uintptr, data []byte) (int, error) { func (t *ThreadContext) blocked() bool {
return sys.PtracePokeData(tid, addr, data) // TODO(dp) cache the func pc to remove this lookup
// TODO(dp) check err
pc, _ := t.CurrentPC()
fn := t.Process.GoSymTable.PCToFunc(pc)
if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep")) {
return true
}
return false
}
func writeMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
return sys.PtracePokeData(thread.Id, addr, data)
} }
func readMemory(tid int, addr uintptr, data []byte) (int, error) { func readMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
return sys.PtracePeekData(tid, addr, data) return sys.PtracePeekData(thread.Id, addr, data)
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册