diff --git a/proc/breakpoints.go b/proc/breakpoints.go index c67dce3e..7a49d4ee 100644 --- a/proc/breakpoints.go +++ b/proc/breakpoints.go @@ -43,7 +43,7 @@ func (bp *Breakpoint) Clear(thread *Thread) (*Breakpoint, error) { } return bp, nil } - if _, err := writeMemory(thread, uintptr(bp.Addr), bp.OriginalData); err != nil { + if _, err := thread.writeMemory(uintptr(bp.Addr), bp.OriginalData); err != nil { return nil, fmt.Errorf("could not clear breakpoint %s", err) } return bp, nil @@ -126,8 +126,8 @@ func (dbp *Process) setBreakpoint(tid int, addr uint64, temp bool) (*Breakpoint, // Fall back to software breakpoint. thread := dbp.Threads[tid] - originalData := make([]byte, dbp.arch.BreakpointSize()) - if _, err := readMemory(thread, uintptr(addr), originalData); err != nil { + originalData, err := thread.readMemory(uintptr(addr), dbp.arch.BreakpointSize()) + if err != nil { return nil, err } if err := dbp.writeSoftwareBreakpoint(thread, addr); err != nil { @@ -140,7 +140,7 @@ func (dbp *Process) setBreakpoint(tid int, addr uint64, temp bool) (*Breakpoint, } func (dbp *Process) writeSoftwareBreakpoint(thread *Thread, addr uint64) error { - _, err := writeMemory(thread, uintptr(addr), dbp.arch.BreakpointInstruction()) + _, err := thread.writeMemory(uintptr(addr), dbp.arch.BreakpointInstruction()) return err } diff --git a/proc/proc_test.go b/proc/proc_test.go index ffc02a34..9381b465 100644 --- a/proc/proc_test.go +++ b/proc/proc_test.go @@ -50,13 +50,7 @@ func getRegisters(p *Process, t *testing.T) Registers { } func dataAtAddr(thread *Thread, addr uint64) ([]byte, error) { - data := make([]byte, 1) - _, err := readMemory(thread, uintptr(addr), data) - if err != nil { - return nil, err - } - - return data, nil + return thread.readMemory(uintptr(addr), 1) } func assertNoError(err error, t *testing.T, s string) { @@ -413,9 +407,10 @@ func TestFindReturnAddress(t *testing.T) { } addr := uint64(int64(regs.SP()) + ret) - data := make([]byte, 8) - - readMemory(p.CurrentThread, uintptr(addr), data) + data, err := p.CurrentThread.readMemory(uintptr(addr), 8) + if err != nil { + t.Fatal(err) + } addr = binary.LittleEndian.Uint64(data) _, l, _ := p.goSymTable.PCToLine(addr) diff --git a/proc/stack.go b/proc/stack.go index 1dfc3e2c..05ed9cd6 100644 --- a/proc/stack.go +++ b/proc/stack.go @@ -46,7 +46,6 @@ func (n NullAddrError) Error() string { func (dbp *Process) stacktrace(pc, sp uint64, depth int) ([]Location, error) { var ( ret = pc - data = make([]byte, dbp.arch.PtrSize()) btoffset int64 locations []Location retaddr uintptr @@ -63,7 +62,7 @@ func (dbp *Process) stacktrace(pc, sp uint64, depth int) ([]Location, error) { if retaddr == 0 { return nil, NullAddrError{} } - _, err = readMemory(dbp.CurrentThread, retaddr, data) + data, err := dbp.CurrentThread.readMemory(retaddr, dbp.arch.PtrSize()) if err != nil { return nil, err } diff --git a/proc/threads.go b/proc/threads.go index 68ba135c..11982209 100644 --- a/proc/threads.go +++ b/proc/threads.go @@ -266,8 +266,7 @@ func (thread *Thread) GetG() (g *G, err error) { return nil, err } - gaddrbs := make([]byte, 8) - _, err = readMemory(thread, uintptr(regs.TLS()+thread.dbp.arch.GStructOffset()), gaddrbs) + gaddrbs, err := thread.readMemory(uintptr(regs.TLS()+thread.dbp.arch.GStructOffset()), thread.dbp.arch.PtrSize()) if err != nil { return nil, err } diff --git a/proc/threads_darwin.go b/proc/threads_darwin.go index ce57b980..c41c4fa5 100644 --- a/proc/threads_darwin.go +++ b/proc/threads_darwin.go @@ -65,7 +65,7 @@ func (t *Thread) blocked() bool { } } -func writeMemory(thread *Thread, addr uintptr, data []byte) (int, error) { +func (thread *Thread) writeMemory(addr uintptr, data []byte) (int, error) { if len(data) == 0 { return 0, nil } @@ -80,19 +80,20 @@ func writeMemory(thread *Thread, addr uintptr, data []byte) (int, error) { return len(data), nil } -func readMemory(thread *Thread, addr uintptr, data []byte) (int, error) { - if len(data) == 0 { - return 0, nil +func (thread *Thread) readMemory(addr uintptr, size int) ([]byte, error) { + if size == 0 { + return nil, nil } var ( - vm_data = unsafe.Pointer(&data[0]) + buf = make([]byte, size) + vm_data = unsafe.Pointer(&buf[0]) vm_addr = C.mach_vm_address_t(addr) - length = C.mach_msg_type_number_t(len(data)) + length = C.mach_msg_type_number_t(size) ) ret := C.read_memory(thread.dbp.os.task, vm_addr, vm_data, length) if ret < 0 { - return 0, fmt.Errorf("could not read memory") + return nil, fmt.Errorf("could not read memory") } - return len(data), nil + return buf, nil } diff --git a/proc/threads_linux.go b/proc/threads_linux.go index 4dc20b66..5ad2c2b5 100644 --- a/proc/threads_linux.go +++ b/proc/threads_linux.go @@ -67,7 +67,7 @@ func (thread *Thread) restoreRegisters() (err error) { return } -func writeMemory(thread *Thread, addr uintptr, data []byte) (written int, err error) { +func (thread *Thread) writeMemory(addr uintptr, data []byte) (written int, err error) { if len(data) == 0 { return } @@ -75,10 +75,11 @@ func writeMemory(thread *Thread, addr uintptr, data []byte) (written int, err er return } -func readMemory(thread *Thread, addr uintptr, data []byte) (read int, err error) { - if len(data) == 0 { - return +func (thread *Thread) readMemory(addr uintptr, size int) (data []byte, err error) { + if size == 0 { + return nil, nil } + data = make([]byte, size) thread.dbp.execPtraceFunc(func() { read, err = sys.PtracePeekData(thread.Id, addr, data) }) return } diff --git a/proc/variables.go b/proc/variables.go index 1d90d291..c5171997 100644 --- a/proc/variables.go +++ b/proc/variables.go @@ -810,18 +810,6 @@ func (thread *Thread) readFunctionPtr(addr uintptr) (string, error) { return fn.Name, nil } -func (thread *Thread) readMemory(addr uintptr, size int) ([]byte, error) { - if size == 0 { - return nil, nil - } - buf := make([]byte, size) - _, err := readMemory(thread, addr, buf) - if err != nil { - return nil, err - } - return buf, nil -} - // Fetches all variables of a specific type in the current function scope func (thread *Thread) variablesByTag(tag dwarf.Tag) ([]*Variable, error) { pc, err := thread.PC()