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 {
prefix = "* "
}
pc, err := th.PC()
loc, err := th.Location()
if err != nil {
return err
}
f, l, fn := th.Process.PCToLine(pc)
if fn != nil {
fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, pc, f, l, fn.Name)
if loc.Fn != nil {
fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, loc.PC, loc.File, loc.Line, loc.Fn.Name)
} 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

View File

@ -121,9 +121,9 @@ func (dbp *DebuggedProcess) addThread(port int, attach bool) (*ThreadContext, er
return thread, nil
}
thread := &ThreadContext{
Id: port,
Process: dbp,
os: new(OSSpecificDetails),
Id: port,
dbp: dbp,
os: new(OSSpecificDetails),
}
dbp.Threads[port] = thread
thread.os.thread_act = C.thread_act_t(port)

View File

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

View File

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

View File

@ -19,7 +19,7 @@ func (thread *ThreadContext) ReturnAddress() (uint64, error) {
if err != nil {
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 {
return 0, err
}

View File

@ -1,6 +1,7 @@
package proctl
import (
"debug/gosym"
"fmt"
"path/filepath"
@ -16,14 +17,21 @@ import (
// on this thread.
type ThreadContext struct {
Id int
Process *DebuggedProcess
Status *sys.WaitStatus
CurrentBreakpoint *BreakPoint
dbp *DebuggedProcess
singleStepping bool
running bool
os *OSSpecificDetails
}
type Location struct {
PC uint64
File string
Line int
Fn *gosym.Func
}
// Continue the execution of this thread. This method takes
// software breakpoints into consideration and ensures that
// 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
// 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 {
return err
}
@ -54,10 +62,10 @@ func (thread *ThreadContext) Step() (err error) {
return err
}
bp, ok := thread.Process.BreakPoints[pc]
bp, ok := thread.dbp.BreakPoints[pc]
if ok {
// Clear the breakpoint so that we can continue execution.
_, err = thread.Process.Clear(bp.Addr)
_, err = thread.dbp.Clear(bp.Addr)
if err != nil {
return err
}
@ -65,7 +73,7 @@ func (thread *ThreadContext) Step() (err error) {
// Restore breakpoint now that we have passed it.
defer func() {
var nbp *BreakPoint
nbp, err = thread.Process.Break(bp.Addr)
nbp, err = thread.dbp.Break(bp.Addr)
nbp.Temp = bp.Temp
}()
}
@ -79,7 +87,7 @@ func (thread *ThreadContext) Step() (err error) {
// Call a function named `name`. This is currently _NOT_ safe.
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 {
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 {
return err
}
defer thread.Process.Clear(bp.Addr)
defer thread.dbp.Clear(bp.Addr)
regs, err := thread.saveRegisters()
if err != nil {
@ -110,7 +118,7 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
if err = thread.Continue(); err != nil {
return err
}
th, err := thread.Process.trapWait(-1)
th, err := thread.dbp.trapWait(-1)
if err != nil {
return err
}
@ -120,17 +128,26 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
// Set breakpoint using this thread.
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.
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.
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.
@ -149,15 +166,18 @@ func (thread *ThreadContext) Next() (err error) {
// Grab info on our current stack frame. Used to determine
// 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 {
return err
}
// Get current file/line.
f, l, _ := thread.Process.goSymTable.PCToLine(curpc)
if filepath.Ext(f) == ".go" {
if err = thread.next(curpc, fde, f, l); err != nil {
loc, err := thread.Location()
if err != nil {
return err
}
if filepath.Ext(loc.File) == ".go" {
if err = thread.next(curpc, fde, loc.File, loc.Line); err != nil {
return err
}
} 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
// we could end up at.
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 _, ok := err.(source.NoNodeError); !ok {
return err
@ -194,7 +214,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
pcs := make([]uint64, 0, len(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
@ -206,7 +226,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
}
if !covered {
fn := thread.Process.goSymTable.PCToFunc(ret)
fn := thread.dbp.goSymTable.PCToFunc(ret)
if fn != nil && fn.Name == "runtime.goexit" {
g, err := thread.curG()
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
// cannot accurately predict where we may end up.
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()
if err != nil {
return err
@ -237,7 +257,7 @@ func (thread *ThreadContext) setNextTempBreakpoints(curpc uint64, pcs []uint64)
if pcs[i] == curpc || pcs[i] == curpc-1 {
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 {
return err
}
@ -262,7 +282,7 @@ func (thread *ThreadContext) curG() (*G, error) {
if err != nil {
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 g, err

View File

@ -26,7 +26,7 @@ func (t *ThreadContext) singleStep() error {
if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not single step")
}
t.Process.trapWait(0)
t.dbp.trapWait(0)
kret = C.clear_trap_flag(t.os.thread_act)
if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not clear CPU trap flag")
@ -36,7 +36,7 @@ func (t *ThreadContext) singleStep() error {
func (t *ThreadContext) resume() error {
// TODO(dp) set flag for ptrace stops
if PtraceCont(t.Process.Pid, 0) == nil {
if PtraceCont(t.dbp.Pid, 0) == nil {
return nil
}
kret := C.resume_thread(t.os.thread_act)
@ -49,7 +49,7 @@ func (t *ThreadContext) resume() error {
func (t *ThreadContext) blocked() bool {
// TODO(dp) cache the func pc to remove this lookup
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") {
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))
)
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 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))
)
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 {
return 0, fmt.Errorf("could not read memory")
}

View File

@ -16,7 +16,7 @@ func (t *ThreadContext) Halt() error {
if stopped(t.Id) {
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 {
return fmt.Errorf("Halt err %s %d", err, t.Id)
}
@ -43,7 +43,7 @@ func (t *ThreadContext) singleStep() error {
func (t *ThreadContext) blocked() bool {
// TODO(dp) cache the func pc to remove this lookup
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")) {
return true
}

View File

@ -80,7 +80,7 @@ func (ng NoGError) Error() string {
}
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 {
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}
}
rdr := thread.Process.DwarfReader()
rdr := thread.dbp.DwarfReader()
rdr.Seek(0)
entry, err := rdr.SeekToTypeNamed("runtime.g")
if err != nil {
@ -107,7 +107,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
}
var deferPC uint64
// 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 {
return nil, fmt.Errorf("error derefing *G %s", err)
}
@ -141,7 +141,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
if err != nil {
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 {
return nil, err
}
@ -173,7 +173,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
return nil, err
}
f, l, fn := thread.Process.goSymTable.PCToLine(gopc)
f, l, fn := thread.dbp.goSymTable.PCToLine(gopc)
g := &G{
Id: int(goid),
GoPC: gopc,
@ -195,7 +195,7 @@ func (thread *ThreadContext) EvalSymbol(name string) (*Variable, error) {
return nil, err
}
reader := thread.Process.DwarfReader()
reader := thread.dbp.DwarfReader()
_, err = reader.SeekToFunction(pc)
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.
func (thread *ThreadContext) PackageVariables() ([]*Variable, error) {
reader := thread.Process.DwarfReader()
reader := thread.dbp.DwarfReader()
vars := make([]*Variable, 0)
@ -308,7 +308,7 @@ func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, rdr
return nil, fmt.Errorf("type assertion failed")
}
data := thread.Process.dwarf
data := thread.dbp.dwarf
t, err := data.Type(offset)
if err != nil {
return nil, err
@ -349,7 +349,7 @@ func (thread *ThreadContext) extractVariableFromEntry(entry *dwarf.Entry) (*Vari
return nil, fmt.Errorf("type assertion failed")
}
data := thread.Process.dwarf
data := thread.dbp.dwarf
t, err := data.Type(offset)
if err != nil {
return nil, err
@ -375,7 +375,7 @@ func (thread *ThreadContext) executeStackProgram(instructions []byte) (int64, er
return 0, err
}
fde, err := thread.Process.frameEntries.FDEForPC(regs.PC())
fde, err := thread.dbp.frameEntries.FDEForPC(regs.PC())
if err != nil {
return 0, err
}
@ -413,7 +413,7 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, rdr
ptraddress := uintptr(address)
ptr, err := thread.readMemory(ptraddress, thread.Process.arch.PtrSize())
ptr, err := thread.readMemory(ptraddress, thread.dbp.arch.PtrSize())
if err != nil {
return 0, err
}
@ -453,7 +453,7 @@ func (thread *ThreadContext) extractValueInternal(instructions []byte, addr int6
ptraddress := uintptr(addr)
switch t := typ.(type) {
case *dwarf.PtrType:
ptr, err := thread.readMemory(ptraddress, thread.Process.arch.PtrSize())
ptr, err := thread.readMemory(ptraddress, thread.dbp.arch.PtrSize())
if err != nil {
return "", err
}
@ -528,14 +528,14 @@ func (thread *ThreadContext) readString(addr uintptr) (string, error) {
// http://research.swtch.com/godata
// 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 {
return "", err
}
strlen := int(binary.LittleEndian.Uint64(val))
// read addr
val, err = thread.readMemory(addr, thread.Process.arch.PtrSize())
val, err = thread.readMemory(addr, thread.dbp.arch.PtrSize())
if err != nil {
return "", err
}
@ -559,7 +559,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
for _, f := range t.Field {
switch f.Name {
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 {
return "", err
}
@ -593,7 +593,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
stride := arrayType.Size()
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)
if err != nil {
@ -729,7 +729,7 @@ func (thread *ThreadContext) readBool(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 {
return "", err
}
@ -740,13 +740,13 @@ func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
return "nil", nil
}
val, err = thread.readMemory(addr, thread.Process.arch.PtrSize())
val, err = thread.readMemory(addr, thread.dbp.arch.PtrSize())
if err != nil {
return "", err
}
funcAddr := binary.LittleEndian.Uint64(val)
fn := thread.Process.goSymTable.PCToFunc(uint64(funcAddr))
fn := thread.dbp.goSymTable.PCToFunc(uint64(funcAddr))
if fn == nil {
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
}
reader := thread.Process.DwarfReader()
reader := thread.dbp.DwarfReader()
_, err = reader.SeekToFunction(pc)
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.
func convertThread(th *proctl.ThreadContext) *api.Thread {
var function *api.Function
file, line := "", 0
var (
function *api.Function
file string
line int
pc uint64
)
pc, err := th.PC()
loc, err := th.Location()
if err == nil {
f, l, fn := th.Process.PCToLine(pc)
file = f
line = l
if fn != nil {
pc = loc.PC
file = loc.File
line = loc.Line
if loc.Fn != nil {
function = &api.Function{
Name: fn.Name,
Type: fn.Type,
Value: fn.Value,
GoType: fn.GoType,
Name: loc.Fn.Name,
Type: loc.Fn.Type,
Value: loc.Fn.Value,
GoType: loc.Fn.GoType,
}
}
}