Rename thread.Process -> thread.dbp

Process is an incorrect name for the DebuggedProcess struct that the
thread is "a part" of. Also, no need to export that field.
This commit is contained in:
Derek Parker
2015-05-27 12:16:45 -05:00
parent 8f4f54d22a
commit 49667f2302
10 changed files with 95 additions and 72 deletions

View File

@ -124,15 +124,14 @@ func threads(p *proctl.DebuggedProcess, args ...string) error {
if th == p.CurrentThread { if th == p.CurrentThread {
prefix = "* " prefix = "* "
} }
pc, err := th.PC() loc, err := th.Location()
if err != nil { if err != nil {
return err return err
} }
f, l, fn := th.Process.PCToLine(pc) if loc.Fn != nil {
if fn != nil { fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, loc.PC, loc.File, loc.Line, loc.Fn.Name)
fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, pc, f, l, fn.Name)
} else { } else {
fmt.Printf("%sThread %d at %#v\n", prefix, th.Id, pc) fmt.Printf("%sThread %d at %#v\n", prefix, th.Id, loc.PC)
} }
} }
return nil return nil

View File

@ -122,7 +122,7 @@ func (dbp *DebuggedProcess) addThread(port int, attach bool) (*ThreadContext, er
} }
thread := &ThreadContext{ thread := &ThreadContext{
Id: port, Id: port,
Process: dbp, dbp: dbp,
os: new(OSSpecificDetails), os: new(OSSpecificDetails),
} }
dbp.Threads[port] = thread dbp.Threads[port] = thread

View File

@ -101,7 +101,7 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
dbp.Threads[tid] = &ThreadContext{ dbp.Threads[tid] = &ThreadContext{
Id: tid, Id: tid,
Process: dbp, dbp: dbp,
os: new(OSSpecificDetails), os: new(OSSpecificDetails),
} }

View File

@ -443,7 +443,7 @@ func TestFunctionCall(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
f := th.Process.goSymTable.LookupFunc("runtime.getg") f := th.dbp.goSymTable.LookupFunc("runtime.getg")
if f == nil { if f == nil {
t.Fatalf("could not find function %s", "runtime.getg") t.Fatalf("could not find function %s", "runtime.getg")
} }

View File

@ -19,7 +19,7 @@ func (thread *ThreadContext) ReturnAddress() (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
locations, err := thread.Process.stacktrace(regs.PC(), regs.SP(), 1) locations, err := thread.dbp.stacktrace(regs.PC(), regs.SP(), 1)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -1,6 +1,7 @@
package proctl package proctl
import ( import (
"debug/gosym"
"fmt" "fmt"
"path/filepath" "path/filepath"
@ -16,14 +17,21 @@ import (
// on this thread. // on this thread.
type ThreadContext struct { type ThreadContext struct {
Id int Id int
Process *DebuggedProcess
Status *sys.WaitStatus Status *sys.WaitStatus
CurrentBreakpoint *BreakPoint CurrentBreakpoint *BreakPoint
dbp *DebuggedProcess
singleStepping bool singleStepping bool
running bool running bool
os *OSSpecificDetails os *OSSpecificDetails
} }
type Location struct {
PC uint64
File string
Line int
Fn *gosym.Func
}
// Continue the execution of this thread. This method takes // Continue the execution of this thread. This method takes
// software breakpoints into consideration and ensures that // software breakpoints into consideration and ensures that
// we step over any breakpoints. It will restore the instruction, // we step over any breakpoints. It will restore the instruction,
@ -36,7 +44,7 @@ func (thread *ThreadContext) Continue() error {
// Check whether we are stopped at a breakpoint, and // Check whether we are stopped at a breakpoint, and
// if so, single step over it before continuing. // if so, single step over it before continuing.
if _, ok := thread.Process.BreakPoints[pc]; ok { if _, ok := thread.dbp.BreakPoints[pc]; ok {
if err := thread.Step(); err != nil { if err := thread.Step(); err != nil {
return err return err
} }
@ -54,10 +62,10 @@ func (thread *ThreadContext) Step() (err error) {
return err return err
} }
bp, ok := thread.Process.BreakPoints[pc] bp, ok := thread.dbp.BreakPoints[pc]
if ok { if ok {
// Clear the breakpoint so that we can continue execution. // Clear the breakpoint so that we can continue execution.
_, err = thread.Process.Clear(bp.Addr) _, err = thread.dbp.Clear(bp.Addr)
if err != nil { if err != nil {
return err return err
} }
@ -65,7 +73,7 @@ func (thread *ThreadContext) Step() (err error) {
// Restore breakpoint now that we have passed it. // Restore breakpoint now that we have passed it.
defer func() { defer func() {
var nbp *BreakPoint var nbp *BreakPoint
nbp, err = thread.Process.Break(bp.Addr) nbp, err = thread.dbp.Break(bp.Addr)
nbp.Temp = bp.Temp nbp.Temp = bp.Temp
}() }()
} }
@ -79,7 +87,7 @@ func (thread *ThreadContext) Step() (err error) {
// Call a function named `name`. This is currently _NOT_ safe. // Call a function named `name`. This is currently _NOT_ safe.
func (thread *ThreadContext) CallFn(name string, fn func() error) error { func (thread *ThreadContext) CallFn(name string, fn func() error) error {
f := thread.Process.goSymTable.LookupFunc(name) f := thread.dbp.goSymTable.LookupFunc(name)
if f == nil { if f == nil {
return fmt.Errorf("could not find function %s", name) return fmt.Errorf("could not find function %s", name)
} }
@ -89,7 +97,7 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
if err != nil { if err != nil {
return err return err
} }
defer thread.Process.Clear(bp.Addr) defer thread.dbp.Clear(bp.Addr)
regs, err := thread.saveRegisters() regs, err := thread.saveRegisters()
if err != nil { if err != nil {
@ -110,7 +118,7 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
if err = thread.Continue(); err != nil { if err = thread.Continue(); err != nil {
return err return err
} }
th, err := thread.Process.trapWait(-1) th, err := thread.dbp.trapWait(-1)
if err != nil { if err != nil {
return err return err
} }
@ -120,17 +128,26 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
// Set breakpoint using this thread. // Set breakpoint using this thread.
func (thread *ThreadContext) Break(addr uint64) (*BreakPoint, error) { func (thread *ThreadContext) Break(addr uint64) (*BreakPoint, error) {
return thread.Process.setBreakpoint(thread.Id, addr, false) return thread.dbp.setBreakpoint(thread.Id, addr, false)
} }
// Set breakpoint using this thread. // Set breakpoint using this thread.
func (thread *ThreadContext) TempBreak(addr uint64) (*BreakPoint, error) { func (thread *ThreadContext) TempBreak(addr uint64) (*BreakPoint, error) {
return thread.Process.setBreakpoint(thread.Id, addr, true) return thread.dbp.setBreakpoint(thread.Id, addr, true)
} }
// Clear breakpoint using this thread. // Clear breakpoint using this thread.
func (thread *ThreadContext) Clear(addr uint64) (*BreakPoint, error) { func (thread *ThreadContext) Clear(addr uint64) (*BreakPoint, error) {
return thread.Process.clearBreakpoint(thread.Id, addr) return thread.dbp.clearBreakpoint(thread.Id, addr)
}
func (thread *ThreadContext) Location() (*Location, error) {
pc, err := thread.PC()
if err != nil {
return nil, err
}
f, l, fn := thread.dbp.PCToLine(pc)
return &Location{PC: pc, File: f, Line: l, Fn: fn}, nil
} }
// Step to next source line. // Step to next source line.
@ -149,15 +166,18 @@ func (thread *ThreadContext) Next() (err error) {
// Grab info on our current stack frame. Used to determine // Grab info on our current stack frame. Used to determine
// whether we may be stepping outside of the current function. // whether we may be stepping outside of the current function.
fde, err := thread.Process.frameEntries.FDEForPC(curpc) fde, err := thread.dbp.frameEntries.FDEForPC(curpc)
if err != nil { if err != nil {
return err return err
} }
// Get current file/line. // Get current file/line.
f, l, _ := thread.Process.goSymTable.PCToLine(curpc) loc, err := thread.Location()
if filepath.Ext(f) == ".go" { if err != nil {
if err = thread.next(curpc, fde, f, l); err != nil { return err
}
if filepath.Ext(loc.File) == ".go" {
if err = thread.next(curpc, fde, loc.File, loc.Line); err != nil {
return err return err
} }
} else { } else {
@ -180,7 +200,7 @@ func (ge GoroutineExitingError) Error() string {
// This version of next uses the AST from the current source file to figure out all of the potential source lines // This version of next uses the AST from the current source file to figure out all of the potential source lines
// we could end up at. // we could end up at.
func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry, file string, line int) error { func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry, file string, line int) error {
lines, err := thread.Process.ast.NextLines(file, line) lines, err := thread.dbp.ast.NextLines(file, line)
if err != nil { if err != nil {
if _, ok := err.(source.NoNodeError); !ok { if _, ok := err.(source.NoNodeError); !ok {
return err return err
@ -194,7 +214,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
pcs := make([]uint64, 0, len(lines)) pcs := make([]uint64, 0, len(lines))
for i := range lines { for i := range lines {
pcs = append(pcs, thread.Process.lineInfo.AllPCsForFileLine(file, lines[i])...) pcs = append(pcs, thread.dbp.lineInfo.AllPCsForFileLine(file, lines[i])...)
} }
var covered bool var covered bool
@ -206,7 +226,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
} }
if !covered { if !covered {
fn := thread.Process.goSymTable.PCToFunc(ret) fn := thread.dbp.goSymTable.PCToFunc(ret)
if fn != nil && fn.Name == "runtime.goexit" { if fn != nil && fn.Name == "runtime.goexit" {
g, err := thread.curG() g, err := thread.curG()
if err != nil { if err != nil {
@ -223,7 +243,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
// the benefit of an AST we can't be sure we're not at a branching statement and thus // the benefit of an AST we can't be sure we're not at a branching statement and thus
// cannot accurately predict where we may end up. // cannot accurately predict where we may end up.
func (thread *ThreadContext) cnext(curpc uint64, fde *frame.FrameDescriptionEntry) error { func (thread *ThreadContext) cnext(curpc uint64, fde *frame.FrameDescriptionEntry) error {
pcs := thread.Process.lineInfo.AllPCsBetween(fde.Begin(), fde.End()) pcs := thread.dbp.lineInfo.AllPCsBetween(fde.Begin(), fde.End())
ret, err := thread.ReturnAddress() ret, err := thread.ReturnAddress()
if err != nil { if err != nil {
return err return err
@ -237,7 +257,7 @@ func (thread *ThreadContext) setNextTempBreakpoints(curpc uint64, pcs []uint64)
if pcs[i] == curpc || pcs[i] == curpc-1 { if pcs[i] == curpc || pcs[i] == curpc-1 {
continue continue
} }
if _, err := thread.Process.TempBreak(pcs[i]); err != nil { if _, err := thread.dbp.TempBreak(pcs[i]); err != nil {
if err, ok := err.(BreakPointExistsError); !ok { if err, ok := err.(BreakPointExistsError); !ok {
return err return err
} }
@ -262,7 +282,7 @@ func (thread *ThreadContext) curG() (*G, error) {
if err != nil { if err != nil {
return err return err
} }
g, err = parseG(thread, regs.SP()+uint64(thread.Process.arch.PtrSize())) g, err = parseG(thread, regs.SP()+uint64(thread.dbp.arch.PtrSize()))
return err return err
}) })
return g, err return g, err

View File

@ -26,7 +26,7 @@ func (t *ThreadContext) singleStep() error {
if kret != C.KERN_SUCCESS { if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not single step") return fmt.Errorf("could not single step")
} }
t.Process.trapWait(0) t.dbp.trapWait(0)
kret = C.clear_trap_flag(t.os.thread_act) kret = C.clear_trap_flag(t.os.thread_act)
if kret != C.KERN_SUCCESS { if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not clear CPU trap flag") return fmt.Errorf("could not clear CPU trap flag")
@ -36,7 +36,7 @@ func (t *ThreadContext) singleStep() error {
func (t *ThreadContext) resume() error { func (t *ThreadContext) resume() error {
// TODO(dp) set flag for ptrace stops // TODO(dp) set flag for ptrace stops
if PtraceCont(t.Process.Pid, 0) == nil { if PtraceCont(t.dbp.Pid, 0) == nil {
return nil return nil
} }
kret := C.resume_thread(t.os.thread_act) kret := C.resume_thread(t.os.thread_act)
@ -49,7 +49,7 @@ func (t *ThreadContext) resume() error {
func (t *ThreadContext) blocked() bool { func (t *ThreadContext) blocked() bool {
// TODO(dp) cache the func pc to remove this lookup // TODO(dp) cache the func pc to remove this lookup
pc, _ := t.PC() pc, _ := t.PC()
fn := t.Process.goSymTable.PCToFunc(pc) fn := t.dbp.goSymTable.PCToFunc(pc)
if fn != nil && (fn.Name == "runtime.mach_semaphore_wait" || fn.Name == "runtime.usleep") { if fn != nil && (fn.Name == "runtime.mach_semaphore_wait" || fn.Name == "runtime.usleep") {
return true return true
} }
@ -63,7 +63,7 @@ func writeMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error)
length = C.mach_msg_type_number_t(len(data)) length = C.mach_msg_type_number_t(len(data))
) )
if ret := C.write_memory(thread.Process.os.task, vm_addr, vm_data, length); ret < 0 { if ret := C.write_memory(thread.dbp.os.task, vm_addr, vm_data, length); ret < 0 {
return 0, fmt.Errorf("could not write memory") return 0, fmt.Errorf("could not write memory")
} }
return len(data), nil return len(data), nil
@ -76,7 +76,7 @@ func readMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
length = C.mach_msg_type_number_t(len(data)) length = C.mach_msg_type_number_t(len(data))
) )
ret := C.read_memory(thread.Process.os.task, vm_addr, vm_data, length) ret := C.read_memory(thread.dbp.os.task, vm_addr, vm_data, length)
if ret < 0 { if ret < 0 {
return 0, fmt.Errorf("could not read memory") return 0, fmt.Errorf("could not read memory")
} }

View File

@ -16,7 +16,7 @@ func (t *ThreadContext) Halt() error {
if stopped(t.Id) { if stopped(t.Id) {
return nil return nil
} }
err := sys.Tgkill(t.Process.Pid, t.Id, sys.SIGSTOP) err := sys.Tgkill(t.dbp.Pid, t.Id, sys.SIGSTOP)
if err != nil { if err != nil {
return fmt.Errorf("Halt err %s %d", err, t.Id) return fmt.Errorf("Halt err %s %d", err, t.Id)
} }
@ -43,7 +43,7 @@ func (t *ThreadContext) singleStep() error {
func (t *ThreadContext) blocked() bool { func (t *ThreadContext) blocked() bool {
// TODO(dp) cache the func pc to remove this lookup // TODO(dp) cache the func pc to remove this lookup
pc, _ := t.PC() pc, _ := t.PC()
fn := t.Process.goSymTable.PCToFunc(pc) fn := t.dbp.goSymTable.PCToFunc(pc)
if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) { if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) {
return true return true
} }

View File

@ -80,7 +80,7 @@ func (ng NoGError) Error() string {
} }
func parseG(thread *ThreadContext, addr uint64) (*G, error) { func parseG(thread *ThreadContext, addr uint64) (*G, error) {
gaddrbytes, err := thread.readMemory(uintptr(addr), thread.Process.arch.PtrSize()) gaddrbytes, err := thread.readMemory(uintptr(addr), thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return nil, fmt.Errorf("error derefing *G %s", err) return nil, fmt.Errorf("error derefing *G %s", err)
} }
@ -90,7 +90,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
return nil, NoGError{tid: thread.Id} return nil, NoGError{tid: thread.Id}
} }
rdr := thread.Process.DwarfReader() rdr := thread.dbp.DwarfReader()
rdr.Seek(0) rdr.Seek(0)
entry, err := rdr.SeekToTypeNamed("runtime.g") entry, err := rdr.SeekToTypeNamed("runtime.g")
if err != nil { if err != nil {
@ -107,7 +107,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
} }
var deferPC uint64 var deferPC uint64
// Dereference *defer pointer // Dereference *defer pointer
deferAddrBytes, err := thread.readMemory(uintptr(deferAddr), thread.Process.arch.PtrSize()) deferAddrBytes, err := thread.readMemory(uintptr(deferAddr), thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return nil, fmt.Errorf("error derefing *G %s", err) return nil, fmt.Errorf("error derefing *G %s", err)
} }
@ -141,7 +141,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
pc, err := thread.readUintRaw(uintptr(schedAddr+uint64(thread.Process.arch.PtrSize())), 8) pc, err := thread.readUintRaw(uintptr(schedAddr+uint64(thread.dbp.arch.PtrSize())), 8)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -173,7 +173,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
return nil, err return nil, err
} }
f, l, fn := thread.Process.goSymTable.PCToLine(gopc) f, l, fn := thread.dbp.goSymTable.PCToLine(gopc)
g := &G{ g := &G{
Id: int(goid), Id: int(goid),
GoPC: gopc, GoPC: gopc,
@ -195,7 +195,7 @@ func (thread *ThreadContext) EvalSymbol(name string) (*Variable, error) {
return nil, err return nil, err
} }
reader := thread.Process.DwarfReader() reader := thread.dbp.DwarfReader()
_, err = reader.SeekToFunction(pc) _, err = reader.SeekToFunction(pc)
if err != nil { if err != nil {
@ -243,7 +243,7 @@ func (thread *ThreadContext) FunctionArguments() ([]*Variable, error) {
// PackageVariables returns the name, value, and type of all package variables in the application. // PackageVariables returns the name, value, and type of all package variables in the application.
func (thread *ThreadContext) PackageVariables() ([]*Variable, error) { func (thread *ThreadContext) PackageVariables() ([]*Variable, error) {
reader := thread.Process.DwarfReader() reader := thread.dbp.DwarfReader()
vars := make([]*Variable, 0) vars := make([]*Variable, 0)
@ -308,7 +308,7 @@ func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, rdr
return nil, fmt.Errorf("type assertion failed") return nil, fmt.Errorf("type assertion failed")
} }
data := thread.Process.dwarf data := thread.dbp.dwarf
t, err := data.Type(offset) t, err := data.Type(offset)
if err != nil { if err != nil {
return nil, err return nil, err
@ -349,7 +349,7 @@ func (thread *ThreadContext) extractVariableFromEntry(entry *dwarf.Entry) (*Vari
return nil, fmt.Errorf("type assertion failed") return nil, fmt.Errorf("type assertion failed")
} }
data := thread.Process.dwarf data := thread.dbp.dwarf
t, err := data.Type(offset) t, err := data.Type(offset)
if err != nil { if err != nil {
return nil, err return nil, err
@ -375,7 +375,7 @@ func (thread *ThreadContext) executeStackProgram(instructions []byte) (int64, er
return 0, err return 0, err
} }
fde, err := thread.Process.frameEntries.FDEForPC(regs.PC()) fde, err := thread.dbp.frameEntries.FDEForPC(regs.PC())
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -413,7 +413,7 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, rdr
ptraddress := uintptr(address) ptraddress := uintptr(address)
ptr, err := thread.readMemory(ptraddress, thread.Process.arch.PtrSize()) ptr, err := thread.readMemory(ptraddress, thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -453,7 +453,7 @@ func (thread *ThreadContext) extractValueInternal(instructions []byte, addr int6
ptraddress := uintptr(addr) ptraddress := uintptr(addr)
switch t := typ.(type) { switch t := typ.(type) {
case *dwarf.PtrType: case *dwarf.PtrType:
ptr, err := thread.readMemory(ptraddress, thread.Process.arch.PtrSize()) ptr, err := thread.readMemory(ptraddress, thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return "", err return "", err
} }
@ -528,14 +528,14 @@ func (thread *ThreadContext) readString(addr uintptr) (string, error) {
// http://research.swtch.com/godata // http://research.swtch.com/godata
// read len // read len
val, err := thread.readMemory(addr+uintptr(thread.Process.arch.PtrSize()), thread.Process.arch.PtrSize()) val, err := thread.readMemory(addr+uintptr(thread.dbp.arch.PtrSize()), thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return "", err return "", err
} }
strlen := int(binary.LittleEndian.Uint64(val)) strlen := int(binary.LittleEndian.Uint64(val))
// read addr // read addr
val, err = thread.readMemory(addr, thread.Process.arch.PtrSize()) val, err = thread.readMemory(addr, thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return "", err return "", err
} }
@ -559,7 +559,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
for _, f := range t.Field { for _, f := range t.Field {
switch f.Name { switch f.Name {
case "array": case "array":
val, err := thread.readMemory(addr+uintptr(f.ByteOffset), thread.Process.arch.PtrSize()) val, err := thread.readMemory(addr+uintptr(f.ByteOffset), thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return "", err return "", err
} }
@ -593,7 +593,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
stride := arrayType.Size() stride := arrayType.Size()
if _, ok := arrayType.(*dwarf.PtrType); ok { if _, ok := arrayType.(*dwarf.PtrType); ok {
stride = int64(thread.Process.arch.PtrSize()) stride = int64(thread.dbp.arch.PtrSize())
} }
vals, err := thread.readArrayValues(arrayAddr, sliceLen, stride, arrayType) vals, err := thread.readArrayValues(arrayAddr, sliceLen, stride, arrayType)
if err != nil { if err != nil {
@ -729,7 +729,7 @@ func (thread *ThreadContext) readBool(addr uintptr) (string, error) {
} }
func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) { func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
val, err := thread.readMemory(addr, thread.Process.arch.PtrSize()) val, err := thread.readMemory(addr, thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return "", err return "", err
} }
@ -740,13 +740,13 @@ func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
return "nil", nil return "nil", nil
} }
val, err = thread.readMemory(addr, thread.Process.arch.PtrSize()) val, err = thread.readMemory(addr, thread.dbp.arch.PtrSize())
if err != nil { if err != nil {
return "", err return "", err
} }
funcAddr := binary.LittleEndian.Uint64(val) funcAddr := binary.LittleEndian.Uint64(val)
fn := thread.Process.goSymTable.PCToFunc(uint64(funcAddr)) fn := thread.dbp.goSymTable.PCToFunc(uint64(funcAddr))
if fn == nil { if fn == nil {
return "", fmt.Errorf("could not find function for %#v", funcAddr) return "", fmt.Errorf("could not find function for %#v", funcAddr)
} }
@ -774,7 +774,7 @@ func (thread *ThreadContext) variablesByTag(tag dwarf.Tag) ([]*Variable, error)
return nil, err return nil, err
} }
reader := thread.Process.DwarfReader() reader := thread.dbp.DwarfReader()
_, err = reader.SeekToFunction(pc) _, err = reader.SeekToFunction(pc)
if err != nil { if err != nil {

View File

@ -474,20 +474,24 @@ func convertBreakPoint(bp *proctl.BreakPoint) *api.BreakPoint {
// convertThread converts an internal thread to an API Thread. // convertThread converts an internal thread to an API Thread.
func convertThread(th *proctl.ThreadContext) *api.Thread { func convertThread(th *proctl.ThreadContext) *api.Thread {
var function *api.Function var (
file, line := "", 0 function *api.Function
file string
line int
pc uint64
)
pc, err := th.PC() loc, err := th.Location()
if err == nil { if err == nil {
f, l, fn := th.Process.PCToLine(pc) pc = loc.PC
file = f file = loc.File
line = l line = loc.Line
if fn != nil { if loc.Fn != nil {
function = &api.Function{ function = &api.Function{
Name: fn.Name, Name: loc.Fn.Name,
Type: fn.Type, Type: loc.Fn.Type,
Value: fn.Value, Value: loc.Fn.Value,
GoType: fn.GoType, GoType: loc.Fn.GoType,
} }
} }
} }