提交 26ad5f1d 编写于 作者: D Derek Parker

Introduce target interface

上级 3658d1e1
package target
import (
"debug/gosym"
"go/ast"
"time"
"github.com/derekparker/delve/proc"
)
// Target represents the target of the debugger. This
// target could be a system process, core file, etc.
type Interface interface {
Info
ProcessManipulation
BreakpointManipulation
VariableEval
}
// Info is an interface that provides general information on the target.
type Info interface {
Pid() int
Exited() bool
Running() bool
BinaryInfo
ThreadInfo
GoroutineInfo
}
// BinaryInfo is an interface for accessing information on the binary file
// and the contents of binary sections.
type BinaryInfo interface {
LastModified() time.Time
Sources() map[string]*gosym.Obj
FindFileLocation(fileName string, lineNumber int) (uint64, error)
FindFunctionLocation(funcName string, firstLine bool, lineOffset int) (uint64, error)
Funcs() []gosym.Func
Types() ([]string, error)
PCToLine(uint64) (string, int, *gosym.Func)
FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error)
}
// ThreadInfo is an interface for getting information on active threads
// in the process.
type ThreadInfo interface {
Threads() map[int]*proc.Thread
CurrentThread() *proc.Thread
}
// GoroutineInfo is an interface for getting information on running goroutines.
type GoroutineInfo interface {
GoroutinesInfo() ([]*proc.G, error)
SelectedGoroutine() *proc.G
FindGoroutine(int) (*proc.G, error)
}
// ProcessManipulation is an interface for changing the execution state of a process.
type ProcessManipulation interface {
Continue() error
Next() error
Step() error
StepOut() error
StepInstruction() error
SwitchThread(int) error
SwitchGoroutine(int) error
RequestManualStop() error
Halt() error
Kill() error
Detach(bool) error
}
// BreakpointManipulation is an interface for managing breakpoints.
type BreakpointManipulation interface {
Breakpoints() map[uint64]*proc.Breakpoint
SetBreakpoint(addr uint64, kind proc.BreakpointKind, cond ast.Expr) (*proc.Breakpoint, error)
ClearBreakpoint(addr uint64) (*proc.Breakpoint, error)
ClearInternalBreakpoints() error
}
// VariableEval is an interface for dealing with eval scopes.
type VariableEval interface {
ConvertEvalScope(gid, frame int) (*proc.EvalScope, error)
}
...@@ -41,7 +41,7 @@ func (thread *Thread) Disassemble(startPC, endPC uint64, currentGoroutine bool) ...@@ -41,7 +41,7 @@ func (thread *Thread) Disassemble(startPC, endPC uint64, currentGoroutine bool)
} }
for len(mem) > 0 { for len(mem) > 0 {
bp, atbp := thread.dbp.Breakpoints[pc] bp, atbp := thread.dbp.breakpoints[pc]
if atbp { if atbp {
for i := range bp.OriginalData { for i := range bp.OriginalData {
mem[i] = bp.OriginalData[i] mem[i] = bp.OriginalData[i]
......
...@@ -3,6 +3,7 @@ package proc ...@@ -3,6 +3,7 @@ package proc
import ( import (
"debug/gosym" "debug/gosym"
"encoding/binary" "encoding/binary"
"rsc.io/x86/x86asm" "rsc.io/x86/x86asm"
) )
...@@ -145,7 +146,7 @@ func init() { ...@@ -145,7 +146,7 @@ func init() {
// FirstPCAfterPrologue returns the address of the first instruction after the prologue for function fn // FirstPCAfterPrologue returns the address of the first instruction after the prologue for function fn
// If sameline is set FirstPCAfterPrologue will always return an address associated with the same line as fn.Entry // If sameline is set FirstPCAfterPrologue will always return an address associated with the same line as fn.Entry
func (dbp *Process) FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error) { func (dbp *Process) FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error) {
text, err := dbp.CurrentThread.Disassemble(fn.Entry, fn.End, false) text, err := dbp.CurrentThread().Disassemble(fn.Entry, fn.End, false)
if err != nil { if err != nil {
return fn.Entry, err return fn.Entry, err
} }
......
...@@ -13,7 +13,7 @@ type moduleData struct { ...@@ -13,7 +13,7 @@ type moduleData struct {
func (dbp *Process) loadModuleData() (err error) { func (dbp *Process) loadModuleData() (err error) {
dbp.loadModuleDataOnce.Do(func() { dbp.loadModuleDataOnce.Do(func() {
scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0} scope := &EvalScope{Thread: dbp.currentThread, PC: 0, CFA: 0}
var md *Variable var md *Variable
md, err = scope.packageVarAddr("runtime.firstmoduledata") md, err = scope.packageVarAddr("runtime.firstmoduledata")
if err != nil { if err != nil {
...@@ -84,13 +84,13 @@ func (dbp *Process) resolveTypeOff(typeAddr uintptr, off uintptr) (*Variable, er ...@@ -84,13 +84,13 @@ func (dbp *Process) resolveTypeOff(typeAddr uintptr, off uintptr) (*Variable, er
return v.newVariable(v.Name, uintptr(addr), rtyp), nil return v.newVariable(v.Name, uintptr(addr), rtyp), nil
} }
if t, _ := md.typemapVar.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.CurrentThread)); t != nil { if t, _ := md.typemapVar.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.currentThread)); t != nil {
return t, nil return t, nil
} }
res := md.types + uintptr(off) res := md.types + uintptr(off)
return dbp.CurrentThread.newVariable("", res, rtyp), nil return dbp.currentThread.newVariable("", res, rtyp), nil
} }
func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (name, tag string, pkgpathoff int32, err error) { func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (name, tag string, pkgpathoff int32, err error) {
...@@ -119,7 +119,7 @@ func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (name, tag str ...@@ -119,7 +119,7 @@ func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (name, tag str
} }
func (dbp *Process) reflectOffsMapAccess(off uintptr) (*Variable, error) { func (dbp *Process) reflectOffsMapAccess(off uintptr) (*Variable, error) {
scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0} scope := &EvalScope{Thread: dbp.currentThread, PC: 0, CFA: 0}
reflectOffs, err := scope.packageVarAddr("runtime.reflectOffs") reflectOffs, err := scope.packageVarAddr("runtime.reflectOffs")
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -130,7 +130,7 @@ func (dbp *Process) reflectOffsMapAccess(off uintptr) (*Variable, error) { ...@@ -130,7 +130,7 @@ func (dbp *Process) reflectOffsMapAccess(off uintptr) (*Variable, error) {
return nil, err return nil, err
} }
return reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.CurrentThread)) return reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.currentThread))
} }
const ( const (
...@@ -142,7 +142,7 @@ const ( ...@@ -142,7 +142,7 @@ const (
func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32, err error) { func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32, err error) {
off := addr off := addr
namedata, err := dbp.CurrentThread.readMemory(off, 3) namedata, err := dbp.currentThread.readMemory(off, 3)
off += 3 off += 3
if err != nil { if err != nil {
return "", "", 0, err return "", "", 0, err
...@@ -150,7 +150,7 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32, ...@@ -150,7 +150,7 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32,
namelen := uint16(namedata[1]<<8) | uint16(namedata[2]) namelen := uint16(namedata[1]<<8) | uint16(namedata[2])
rawstr, err := dbp.CurrentThread.readMemory(off, int(namelen)) rawstr, err := dbp.currentThread.readMemory(off, int(namelen))
off += uintptr(namelen) off += uintptr(namelen)
if err != nil { if err != nil {
return "", "", 0, err return "", "", 0, err
...@@ -159,14 +159,14 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32, ...@@ -159,14 +159,14 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32,
name = string(rawstr) name = string(rawstr)
if namedata[0]&nameflagHasTag != 0 { if namedata[0]&nameflagHasTag != 0 {
taglendata, err := dbp.CurrentThread.readMemory(off, 2) taglendata, err := dbp.currentThread.readMemory(off, 2)
off += 2 off += 2
if err != nil { if err != nil {
return "", "", 0, err return "", "", 0, err
} }
taglen := uint16(taglendata[0]<<8) | uint16(taglendata[1]) taglen := uint16(taglendata[0]<<8) | uint16(taglendata[1])
rawstr, err := dbp.CurrentThread.readMemory(off, int(taglen)) rawstr, err := dbp.currentThread.readMemory(off, int(taglen))
off += uintptr(taglen) off += uintptr(taglen)
if err != nil { if err != nil {
return "", "", 0, err return "", "", 0, err
...@@ -176,7 +176,7 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32, ...@@ -176,7 +176,7 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32,
} }
if namedata[0]&nameflagHasPkg != 0 { if namedata[0]&nameflagHasPkg != 0 {
pkgdata, err := dbp.CurrentThread.readMemory(off, 4) pkgdata, err := dbp.currentThread.readMemory(off, 4)
if err != nil { if err != nil {
return "", "", 0, err return "", "", 0, err
} }
......
...@@ -25,23 +25,23 @@ import ( ...@@ -25,23 +25,23 @@ import (
// Process represents all of the information the debugger // Process represents all of the information the debugger
// is holding onto regarding the process we are debugging. // is holding onto regarding the process we are debugging.
type Process struct { type Process struct {
Pid int // Process Pid pid int // Process Pid
Process *os.Process // Pointer to process struct for the actual process we are debugging Process *os.Process // Pointer to process struct for the actual process we are debugging
LastModified time.Time // Time the executable of this process was last modified lastModified time.Time // Time the executable of this process was last modified
// Breakpoint table, holds information on breakpoints. // Breakpoint table, holds information on breakpoints.
// Maps instruction address to Breakpoint struct. // Maps instruction address to Breakpoint struct.
Breakpoints map[uint64]*Breakpoint breakpoints map[uint64]*Breakpoint
// List of threads mapped as such: pid -> *Thread // List of threads mapped as such: pid -> *Thread
Threads map[int]*Thread threads map[int]*Thread
// Active thread // Active thread
CurrentThread *Thread currentThread *Thread
// Goroutine that will be used by default to set breakpoint, eval variables, etc... // Goroutine that will be used by default to set breakpoint, eval variables, etc...
// Normally SelectedGoroutine is CurrentThread.GetG, it will not be only if SwitchGoroutine is called with a goroutine that isn't attached to a thread // Normally selectedGoroutine is currentThread.GetG, it will not be only if SwitchGoroutine is called with a goroutine that isn't attached to a thread
SelectedGoroutine *G selectedGoroutine *G
// Maps package names to package paths, needed to lookup types inside DWARF info // Maps package names to package paths, needed to lookup types inside DWARF info
packageMap map[string]string packageMap map[string]string
...@@ -81,9 +81,9 @@ var NotExecutableErr = errors.New("not an executable file") ...@@ -81,9 +81,9 @@ var NotExecutableErr = errors.New("not an executable file")
// `handlePtraceFuncs`. // `handlePtraceFuncs`.
func New(pid int) *Process { func New(pid int) *Process {
dbp := &Process{ dbp := &Process{
Pid: pid, pid: pid,
Threads: make(map[int]*Thread), threads: make(map[int]*Thread),
Breakpoints: make(map[uint64]*Breakpoint), breakpoints: make(map[uint64]*Breakpoint),
firstStart: true, firstStart: true,
os: new(OSProcessDetails), os: new(OSProcessDetails),
ptraceChan: make(chan func()), ptraceChan: make(chan func()),
...@@ -119,7 +119,7 @@ func (dbp *Process) Detach(kill bool) (err error) { ...@@ -119,7 +119,7 @@ func (dbp *Process) Detach(kill bool) (err error) {
} }
if !kill { if !kill {
// Clean up any breakpoints we've set. // Clean up any breakpoints we've set.
for _, bp := range dbp.Breakpoints { for _, bp := range dbp.breakpoints {
if bp != nil { if bp != nil {
_, err := dbp.ClearBreakpoint(bp.Addr) _, err := dbp.ClearBreakpoint(bp.Addr)
if err != nil { if err != nil {
...@@ -129,12 +129,12 @@ func (dbp *Process) Detach(kill bool) (err error) { ...@@ -129,12 +129,12 @@ func (dbp *Process) Detach(kill bool) (err error) {
} }
} }
dbp.execPtraceFunc(func() { dbp.execPtraceFunc(func() {
err = PtraceDetach(dbp.Pid, 0) err = PtraceDetach(dbp.pid, 0)
if err != nil { if err != nil {
return return
} }
if kill { if kill {
err = killProcess(dbp.Pid) err = killProcess(dbp.pid)
} }
}) })
return return
...@@ -149,7 +149,7 @@ func (dbp *Process) Exited() bool { ...@@ -149,7 +149,7 @@ func (dbp *Process) Exited() bool {
// Running returns whether the debugged // Running returns whether the debugged
// process is currently executing. // process is currently executing.
func (dbp *Process) Running() bool { func (dbp *Process) Running() bool {
for _, th := range dbp.Threads { for _, th := range dbp.threads {
if th.running { if th.running {
return true return true
} }
...@@ -157,6 +157,30 @@ func (dbp *Process) Running() bool { ...@@ -157,6 +157,30 @@ func (dbp *Process) Running() bool {
return false return false
} }
func (dbp *Process) LastModified() time.Time {
return dbp.lastModified
}
func (dbp *Process) Pid() int {
return dbp.pid
}
func (dbp *Process) SelectedGoroutine() *G {
return dbp.selectedGoroutine
}
func (dbp *Process) Threads() map[int]*Thread {
return dbp.threads
}
func (dbp *Process) CurrentThread() *Thread {
return dbp.currentThread
}
func (dbp *Process) Breakpoints() map[uint64]*Breakpoint {
return dbp.breakpoints
}
// LoadInformation finds the executable and then uses it // LoadInformation finds the executable and then uses it
// to parse the following information: // to parse the following information:
// * Dwarf .debug_frame section // * Dwarf .debug_frame section
...@@ -171,7 +195,7 @@ func (dbp *Process) LoadInformation(path string) error { ...@@ -171,7 +195,7 @@ func (dbp *Process) LoadInformation(path string) error {
} }
fi, err := os.Stat(path) fi, err := os.Stat(path)
if err == nil { if err == nil {
dbp.LastModified = fi.ModTime() dbp.lastModified = fi.ModTime()
} }
wg.Add(5) wg.Add(5)
...@@ -223,7 +247,7 @@ func (dbp *Process) FindFunctionLocation(funcName string, firstLine bool, lineOf ...@@ -223,7 +247,7 @@ func (dbp *Process) FindFunctionLocation(funcName string, firstLine bool, lineOf
// CurrentLocation returns the location of the current thread. // CurrentLocation returns the location of the current thread.
func (dbp *Process) CurrentLocation() (*Location, error) { func (dbp *Process) CurrentLocation() (*Location, error) {
return dbp.CurrentThread.Location() return dbp.currentThread.Location()
} }
// RequestManualStop sets the `halt` flag and // RequestManualStop sets the `halt` flag and
...@@ -240,7 +264,7 @@ func (dbp *Process) RequestManualStop() error { ...@@ -240,7 +264,7 @@ func (dbp *Process) RequestManualStop() error {
// break point table. Setting a break point must be thread specific due to // break point table. Setting a break point must be thread specific due to
// ptrace actions needing the thread to be in a signal-delivery-stop. // ptrace actions needing the thread to be in a signal-delivery-stop.
func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Expr) (*Breakpoint, error) { func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Expr) (*Breakpoint, error) {
tid := dbp.CurrentThread.ID tid := dbp.currentThread.ID
if bp, ok := dbp.FindBreakpoint(addr); ok { if bp, ok := dbp.FindBreakpoint(addr); ok {
return nil, BreakpointExistsError{bp.File, bp.Line, bp.Addr} return nil, BreakpointExistsError{bp.File, bp.Line, bp.Addr}
...@@ -269,7 +293,7 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp ...@@ -269,7 +293,7 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp
newBreakpoint.ID = dbp.breakpointIDCounter newBreakpoint.ID = dbp.breakpointIDCounter
} }
thread := dbp.Threads[tid] thread := dbp.threads[tid]
originalData, err := thread.readMemory(uintptr(addr), dbp.arch.BreakpointSize()) originalData, err := thread.readMemory(uintptr(addr), dbp.arch.BreakpointSize())
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -278,7 +302,7 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp ...@@ -278,7 +302,7 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp
return nil, err return nil, err
} }
newBreakpoint.OriginalData = originalData newBreakpoint.OriginalData = originalData
dbp.Breakpoints[addr] = newBreakpoint dbp.breakpoints[addr] = newBreakpoint
return newBreakpoint, nil return newBreakpoint, nil
} }
...@@ -293,18 +317,18 @@ func (dbp *Process) ClearBreakpoint(addr uint64) (*Breakpoint, error) { ...@@ -293,18 +317,18 @@ func (dbp *Process) ClearBreakpoint(addr uint64) (*Breakpoint, error) {
return nil, NoBreakpointError{addr: addr} return nil, NoBreakpointError{addr: addr}
} }
if _, err := bp.Clear(dbp.CurrentThread); err != nil { if _, err := bp.Clear(dbp.currentThread); err != nil {
return nil, err return nil, err
} }
delete(dbp.Breakpoints, addr) delete(dbp.breakpoints, addr)
return bp, nil return bp, nil
} }
// Status returns the status of the current main thread context. // Status returns the status of the current main thread context.
func (dbp *Process) Status() *WaitStatus { func (dbp *Process) Status() *WaitStatus {
return dbp.CurrentThread.Status return dbp.currentThread.Status
} }
// Next continues execution until the next source line. // Next continues execution until the next source line.
...@@ -312,8 +336,8 @@ func (dbp *Process) Next() (err error) { ...@@ -312,8 +336,8 @@ func (dbp *Process) Next() (err error) {
if dbp.exited { if dbp.exited {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
for i := range dbp.Breakpoints { for i := range dbp.breakpoints {
if dbp.Breakpoints[i].Internal() { if dbp.breakpoints[i].Internal() {
return fmt.Errorf("next while nexting") return fmt.Errorf("next while nexting")
} }
} }
...@@ -343,7 +367,7 @@ func (dbp *Process) Continue() error { ...@@ -343,7 +367,7 @@ func (dbp *Process) Continue() error {
} }
dbp.allGCache = nil dbp.allGCache = nil
for _, th := range dbp.Threads { for _, th := range dbp.threads {
th.clearBreakpointState() th.clearBreakpointState()
} }
...@@ -362,42 +386,42 @@ func (dbp *Process) Continue() error { ...@@ -362,42 +386,42 @@ func (dbp *Process) Continue() error {
} }
switch { switch {
case dbp.CurrentThread.CurrentBreakpoint == nil: case dbp.currentThread.CurrentBreakpoint == nil:
// runtime.Breakpoint or manual stop // runtime.Breakpoint or manual stop
if dbp.CurrentThread.onRuntimeBreakpoint() { if dbp.currentThread.onRuntimeBreakpoint() {
// Single-step current thread until we exit runtime.breakpoint and // Single-step current thread until we exit runtime.breakpoint and
// runtime.Breakpoint. // runtime.Breakpoint.
// On go < 1.8 it was sufficient to single-step twice on go1.8 a change // On go < 1.8 it was sufficient to single-step twice on go1.8 a change
// to the compiler requires 4 steps. // to the compiler requires 4 steps.
for { for {
if err = dbp.CurrentThread.StepInstruction(); err != nil { if err = dbp.currentThread.StepInstruction(); err != nil {
return err return err
} }
loc, err := dbp.CurrentThread.Location() loc, err := dbp.currentThread.Location()
if err != nil || loc.Fn == nil || (loc.Fn.Name != "runtime.breakpoint" && loc.Fn.Name != "runtime.Breakpoint") { if err != nil || loc.Fn == nil || (loc.Fn.Name != "runtime.breakpoint" && loc.Fn.Name != "runtime.Breakpoint") {
break break
} }
} }
} }
return dbp.conditionErrors() return dbp.conditionErrors()
case dbp.CurrentThread.onTriggeredInternalBreakpoint(): case dbp.currentThread.onTriggeredInternalBreakpoint():
if dbp.CurrentThread.CurrentBreakpoint.Kind == StepBreakpoint { if dbp.currentThread.CurrentBreakpoint.Kind == StepBreakpoint {
// See description of proc.(*Process).next for the meaning of StepBreakpoints // See description of proc.(*Process).next for the meaning of StepBreakpoints
if err := dbp.conditionErrors(); err != nil { if err := dbp.conditionErrors(); err != nil {
return err return err
} }
pc, err := dbp.CurrentThread.PC() pc, err := dbp.currentThread.PC()
if err != nil { if err != nil {
return err return err
} }
text, err := dbp.CurrentThread.Disassemble(pc, pc+maxInstructionLength, true) text, err := dbp.currentThread.Disassemble(pc, pc+maxInstructionLength, true)
if err != nil { if err != nil {
return err return err
} }
// here we either set a breakpoint into the destination of the CALL // here we either set a breakpoint into the destination of the CALL
// instruction or we determined that the called function is hidden, // instruction or we determined that the called function is hidden,
// either way we need to resume execution // either way we need to resume execution
if err = dbp.setStepIntoBreakpoint(text, sameGoroutineCondition(dbp.SelectedGoroutine)); err != nil { if err = dbp.setStepIntoBreakpoint(text, sameGoroutineCondition(dbp.selectedGoroutine)); err != nil {
return err return err
} }
} else { } else {
...@@ -406,8 +430,8 @@ func (dbp *Process) Continue() error { ...@@ -406,8 +430,8 @@ func (dbp *Process) Continue() error {
} }
return dbp.conditionErrors() return dbp.conditionErrors()
} }
case dbp.CurrentThread.onTriggeredBreakpoint(): case dbp.currentThread.onTriggeredBreakpoint():
onNextGoroutine, err := dbp.CurrentThread.onNextGoroutine() onNextGoroutine, err := dbp.currentThread.onNextGoroutine()
if err != nil { if err != nil {
return err return err
} }
...@@ -426,7 +450,7 @@ func (dbp *Process) Continue() error { ...@@ -426,7 +450,7 @@ func (dbp *Process) Continue() error {
func (dbp *Process) conditionErrors() error { func (dbp *Process) conditionErrors() error {
var condErr error var condErr error
for _, th := range dbp.Threads { for _, th := range dbp.threads {
if th.CurrentBreakpoint != nil && th.BreakpointConditionError != nil { if th.CurrentBreakpoint != nil && th.BreakpointConditionError != nil {
if condErr == nil { if condErr == nil {
condErr = th.BreakpointConditionError condErr = th.BreakpointConditionError
...@@ -438,12 +462,12 @@ func (dbp *Process) conditionErrors() error { ...@@ -438,12 +462,12 @@ func (dbp *Process) conditionErrors() error {
return condErr return condErr
} }
// pick a new dbp.CurrentThread, with the following priority: // pick a new dbp.currentThread, with the following priority:
// - a thread with onTriggeredInternalBreakpoint() == true // - a thread with onTriggeredInternalBreakpoint() == true
// - a thread with onTriggeredBreakpoint() == true (prioritizing trapthread) // - a thread with onTriggeredBreakpoint() == true (prioritizing trapthread)
// - trapthread // - trapthread
func (dbp *Process) pickCurrentThread(trapthread *Thread) error { func (dbp *Process) pickCurrentThread(trapthread *Thread) error {
for _, th := range dbp.Threads { for _, th := range dbp.threads {
if th.onTriggeredInternalBreakpoint() { if th.onTriggeredInternalBreakpoint() {
return dbp.SwitchThread(th.ID) return dbp.SwitchThread(th.ID)
} }
...@@ -451,7 +475,7 @@ func (dbp *Process) pickCurrentThread(trapthread *Thread) error { ...@@ -451,7 +475,7 @@ func (dbp *Process) pickCurrentThread(trapthread *Thread) error {
if trapthread.onTriggeredBreakpoint() { if trapthread.onTriggeredBreakpoint() {
return dbp.SwitchThread(trapthread.ID) return dbp.SwitchThread(trapthread.ID)
} }
for _, th := range dbp.Threads { for _, th := range dbp.threads {
if th.onTriggeredBreakpoint() { if th.onTriggeredBreakpoint() {
return dbp.SwitchThread(th.ID) return dbp.SwitchThread(th.ID)
} }
...@@ -465,8 +489,8 @@ func (dbp *Process) Step() (err error) { ...@@ -465,8 +489,8 @@ func (dbp *Process) Step() (err error) {
if dbp.exited { if dbp.exited {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
for i := range dbp.Breakpoints { for i := range dbp.breakpoints {
if dbp.Breakpoints[i].Internal() { if dbp.breakpoints[i].Internal() {
return fmt.Errorf("next while nexting") return fmt.Errorf("next while nexting")
} }
} }
...@@ -506,12 +530,12 @@ func sameGoroutineCondition(g *G) ast.Expr { ...@@ -506,12 +530,12 @@ func sameGoroutineCondition(g *G) ast.Expr {
// asssociated with the selected goroutine. All other // asssociated with the selected goroutine. All other
// threads will remain stopped. // threads will remain stopped.
func (dbp *Process) StepInstruction() (err error) { func (dbp *Process) StepInstruction() (err error) {
if dbp.SelectedGoroutine == nil { if dbp.selectedGoroutine == nil {
return errors.New("cannot single step: no selected goroutine") return errors.New("cannot single step: no selected goroutine")
} }
if dbp.SelectedGoroutine.thread == nil { if dbp.selectedGoroutine.thread == nil {
// Step called on parked goroutine // Step called on parked goroutine
if _, err := dbp.SetBreakpoint(dbp.SelectedGoroutine.PC, NextBreakpoint, sameGoroutineCondition(dbp.SelectedGoroutine)); err != nil { if _, err := dbp.SetBreakpoint(dbp.selectedGoroutine.PC, NextBreakpoint, sameGoroutineCondition(dbp.selectedGoroutine)); err != nil {
return err return err
} }
return dbp.Continue() return dbp.Continue()
...@@ -520,20 +544,20 @@ func (dbp *Process) StepInstruction() (err error) { ...@@ -520,20 +544,20 @@ func (dbp *Process) StepInstruction() (err error) {
if dbp.exited { if dbp.exited {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
dbp.SelectedGoroutine.thread.clearBreakpointState() dbp.selectedGoroutine.thread.clearBreakpointState()
err = dbp.SelectedGoroutine.thread.StepInstruction() err = dbp.selectedGoroutine.thread.StepInstruction()
if err != nil { if err != nil {
return err return err
} }
return dbp.SelectedGoroutine.thread.SetCurrentBreakpoint() return dbp.selectedGoroutine.thread.SetCurrentBreakpoint()
} }
// StepOut will continue until the current goroutine exits the // StepOut will continue until the current goroutine exits the
// function currently being executed or a deferred function is executed // function currently being executed or a deferred function is executed
func (dbp *Process) StepOut() error { func (dbp *Process) StepOut() error {
cond := sameGoroutineCondition(dbp.SelectedGoroutine) cond := sameGoroutineCondition(dbp.selectedGoroutine)
topframe, err := topframe(dbp.SelectedGoroutine, dbp.CurrentThread) topframe, err := topframe(dbp.selectedGoroutine, dbp.currentThread)
if err != nil { if err != nil {
return err return err
} }
...@@ -542,8 +566,8 @@ func (dbp *Process) StepOut() error { ...@@ -542,8 +566,8 @@ func (dbp *Process) StepOut() error {
var deferpc uint64 = 0 var deferpc uint64 = 0
if filepath.Ext(topframe.Current.File) == ".go" { if filepath.Ext(topframe.Current.File) == ".go" {
if dbp.SelectedGoroutine != nil { if dbp.selectedGoroutine != nil {
deferPCEntry := dbp.SelectedGoroutine.DeferPC() deferPCEntry := dbp.selectedGoroutine.DeferPC()
if deferPCEntry != 0 { if deferPCEntry != 0 {
_, _, deferfn := dbp.goSymTable.PCToLine(deferPCEntry) _, _, deferfn := dbp.goSymTable.PCToLine(deferPCEntry)
deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false) deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false)
...@@ -589,9 +613,9 @@ func (dbp *Process) SwitchThread(tid int) error { ...@@ -589,9 +613,9 @@ func (dbp *Process) SwitchThread(tid int) error {
if dbp.exited { if dbp.exited {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
if th, ok := dbp.Threads[tid]; ok { if th, ok := dbp.threads[tid]; ok {
dbp.CurrentThread = th dbp.currentThread = th
dbp.SelectedGoroutine, _ = dbp.CurrentThread.GetG() dbp.selectedGoroutine, _ = dbp.currentThread.GetG()
return nil return nil
} }
return fmt.Errorf("thread %d does not exist", tid) return fmt.Errorf("thread %d does not exist", tid)
...@@ -608,13 +632,13 @@ func (dbp *Process) SwitchGoroutine(gid int) error { ...@@ -608,13 +632,13 @@ func (dbp *Process) SwitchGoroutine(gid int) error {
return err return err
} }
if g == nil { if g == nil {
// user specified -1 and SelectedGoroutine is nil // user specified -1 and selectedGoroutine is nil
return nil return nil
} }
if g.thread != nil { if g.thread != nil {
return dbp.SwitchThread(g.thread.ID) return dbp.SwitchThread(g.thread.ID)
} }
dbp.SelectedGoroutine = g dbp.selectedGoroutine = g
return nil return nil
} }
...@@ -634,13 +658,13 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) { ...@@ -634,13 +658,13 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
rdr = dbp.DwarfReader() rdr = dbp.DwarfReader()
) )
for i := range dbp.Threads { for i := range dbp.threads {
if dbp.Threads[i].blocked() { if dbp.threads[i].blocked() {
continue continue
} }
g, _ := dbp.Threads[i].GetG() g, _ := dbp.threads[i].GetG()
if g != nil { if g != nil {
threadg[g.ID] = dbp.Threads[i] threadg[g.ID] = dbp.threads[i]
} }
} }
...@@ -648,7 +672,7 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) { ...@@ -648,7 +672,7 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
allglenBytes, err := dbp.CurrentThread.readMemory(uintptr(addr), 8) allglenBytes, err := dbp.currentThread.readMemory(uintptr(addr), 8)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -663,11 +687,11 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) { ...@@ -663,11 +687,11 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
return nil, err return nil, err
} }
} }
faddr, err := dbp.CurrentThread.readMemory(uintptr(allgentryaddr), dbp.arch.PtrSize()) faddr, err := dbp.currentThread.readMemory(uintptr(allgentryaddr), dbp.arch.PtrSize())
allgptr := binary.LittleEndian.Uint64(faddr) allgptr := binary.LittleEndian.Uint64(faddr)
for i := uint64(0); i < allglen; i++ { for i := uint64(0); i < allglen; i++ {
gvar, err := dbp.CurrentThread.newGVariable(uintptr(allgptr+(i*uint64(dbp.arch.PtrSize()))), true) gvar, err := dbp.currentThread.newGVariable(uintptr(allgptr+(i*uint64(dbp.arch.PtrSize()))), true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -701,7 +725,7 @@ func (dbp *Process) Halt() (err error) { ...@@ -701,7 +725,7 @@ func (dbp *Process) Halt() (err error) {
if dbp.exited { if dbp.exited {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
for _, th := range dbp.Threads { for _, th := range dbp.threads {
if err := th.Halt(); err != nil { if err := th.Halt(); err != nil {
return err return err
} }
...@@ -712,18 +736,18 @@ func (dbp *Process) Halt() (err error) { ...@@ -712,18 +736,18 @@ func (dbp *Process) Halt() (err error) {
// Registers obtains register values from the // Registers obtains register values from the
// "current" thread of the traced process. // "current" thread of the traced process.
func (dbp *Process) Registers() (Registers, error) { func (dbp *Process) Registers() (Registers, error) {
return dbp.CurrentThread.Registers(false) return dbp.currentThread.Registers(false)
} }
// PC returns the PC of the current thread. // PC returns the PC of the current thread.
func (dbp *Process) PC() (uint64, error) { func (dbp *Process) PC() (uint64, error) {
return dbp.CurrentThread.PC() return dbp.currentThread.PC()
} }
// CurrentBreakpoint returns the breakpoint the current thread // CurrentBreakpoint returns the breakpoint the current thread
// is stopped at. // is stopped at.
func (dbp *Process) CurrentBreakpoint() *Breakpoint { func (dbp *Process) CurrentBreakpoint() *Breakpoint {
return dbp.CurrentThread.CurrentBreakpoint return dbp.currentThread.CurrentBreakpoint
} }
// DwarfReader returns a reader for the dwarf data // DwarfReader returns a reader for the dwarf data
...@@ -757,7 +781,7 @@ func (dbp *Process) PCToLine(pc uint64) (string, int, *gosym.Func) { ...@@ -757,7 +781,7 @@ func (dbp *Process) PCToLine(pc uint64) (string, int, *gosym.Func) {
// FindBreakpointByID finds the breakpoint for the given ID. // FindBreakpointByID finds the breakpoint for the given ID.
func (dbp *Process) FindBreakpointByID(id int) (*Breakpoint, bool) { func (dbp *Process) FindBreakpointByID(id int) (*Breakpoint, bool) {
for _, bp := range dbp.Breakpoints { for _, bp := range dbp.breakpoints {
if bp.ID == id { if bp.ID == id {
return bp, true return bp, true
} }
...@@ -768,11 +792,11 @@ func (dbp *Process) FindBreakpointByID(id int) (*Breakpoint, bool) { ...@@ -768,11 +792,11 @@ func (dbp *Process) FindBreakpointByID(id int) (*Breakpoint, bool) {
// FindBreakpoint finds the breakpoint for the given pc. // FindBreakpoint finds the breakpoint for the given pc.
func (dbp *Process) FindBreakpoint(pc uint64) (*Breakpoint, bool) { func (dbp *Process) FindBreakpoint(pc uint64) (*Breakpoint, bool) {
// Check to see if address is past the breakpoint, (i.e. breakpoint was hit). // Check to see if address is past the breakpoint, (i.e. breakpoint was hit).
if bp, ok := dbp.Breakpoints[pc-uint64(dbp.arch.BreakpointSize())]; ok { if bp, ok := dbp.breakpoints[pc-uint64(dbp.arch.BreakpointSize())]; ok {
return bp, true return bp, true
} }
// Directly use addr to lookup breakpoint. // Directly use addr to lookup breakpoint.
if bp, ok := dbp.Breakpoints[pc]; ok { if bp, ok := dbp.breakpoints[pc]; ok {
return bp, true return bp, true
} }
return nil, false return nil, false
...@@ -782,17 +806,17 @@ func (dbp *Process) FindBreakpoint(pc uint64) (*Breakpoint, bool) { ...@@ -782,17 +806,17 @@ func (dbp *Process) FindBreakpoint(pc uint64) (*Breakpoint, bool) {
func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, error) { func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, error) {
if attach { if attach {
var err error var err error
dbp.execPtraceFunc(func() { err = PtraceAttach(dbp.Pid) }) dbp.execPtraceFunc(func() { err = PtraceAttach(dbp.pid) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, _, err = dbp.wait(dbp.Pid, 0) _, _, err = dbp.wait(dbp.pid, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
proc, err := os.FindProcess(dbp.Pid) proc, err := os.FindProcess(dbp.pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -813,11 +837,11 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e ...@@ -813,11 +837,11 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e
} }
dbp.arch.SetGStructOffset(ver, isextld) dbp.arch.SetGStructOffset(ver, isextld)
// SelectedGoroutine can not be set correctly by the call to updateThreadList // selectedGoroutine can not be set correctly by the call to updateThreadList
// because without calling SetGStructOffset we can not read the G struct of CurrentThread // because without calling SetGStructOffset we can not read the G struct of currentThread
// but without calling updateThreadList we can not examine memory to determine // but without calling updateThreadList we can not examine memory to determine
// the offset of g struct inside TLS // the offset of g struct inside TLS
dbp.SelectedGoroutine, _ = dbp.CurrentThread.GetG() dbp.selectedGoroutine, _ = dbp.currentThread.GetG()
panicpc, err := dbp.FindFunctionLocation("runtime.startpanic", true, 0) panicpc, err := dbp.FindFunctionLocation("runtime.startpanic", true, 0)
if err == nil { if err == nil {
...@@ -833,7 +857,7 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e ...@@ -833,7 +857,7 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e
} }
func (dbp *Process) ClearInternalBreakpoints() error { func (dbp *Process) ClearInternalBreakpoints() error {
for _, bp := range dbp.Breakpoints { for _, bp := range dbp.breakpoints {
if !bp.Internal() { if !bp.Internal() {
continue continue
} }
...@@ -841,9 +865,9 @@ func (dbp *Process) ClearInternalBreakpoints() error { ...@@ -841,9 +865,9 @@ func (dbp *Process) ClearInternalBreakpoints() error {
return err return err
} }
} }
for i := range dbp.Threads { for i := range dbp.threads {
if dbp.Threads[i].CurrentBreakpoint != nil && dbp.Threads[i].CurrentBreakpoint.Internal() { if dbp.threads[i].CurrentBreakpoint != nil && dbp.threads[i].CurrentBreakpoint.Internal() {
dbp.Threads[i].CurrentBreakpoint = nil dbp.threads[i].CurrentBreakpoint = nil
} }
} }
return nil return nil
...@@ -901,7 +925,7 @@ func (dbp *Process) getGoInformation() (ver GoVersion, isextld bool, err error) ...@@ -901,7 +925,7 @@ func (dbp *Process) getGoInformation() (ver GoVersion, isextld bool, err error)
// specified by `gid`. // specified by `gid`.
func (dbp *Process) FindGoroutine(gid int) (*G, error) { func (dbp *Process) FindGoroutine(gid int) (*G, error) {
if gid == -1 { if gid == -1 {
return dbp.SelectedGoroutine, nil return dbp.selectedGoroutine, nil
} }
gs, err := dbp.GoroutinesInfo() gs, err := dbp.GoroutinesInfo()
...@@ -927,13 +951,13 @@ func (dbp *Process) ConvertEvalScope(gid, frame int) (*EvalScope, error) { ...@@ -927,13 +951,13 @@ func (dbp *Process) ConvertEvalScope(gid, frame int) (*EvalScope, error) {
return nil, err return nil, err
} }
if g == nil { if g == nil {
return dbp.CurrentThread.Scope() return dbp.currentThread.Scope()
} }
var out EvalScope var out EvalScope
if g.thread == nil { if g.thread == nil {
out.Thread = dbp.CurrentThread out.Thread = dbp.currentThread
} else { } else {
out.Thread = g.thread out.Thread = g.thread
} }
......
...@@ -77,7 +77,7 @@ func Launch(cmd []string, wd string) (*Process, error) { ...@@ -77,7 +77,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
if pid <= 0 { if pid <= 0 {
return nil, fmt.Errorf("could not fork/exec") return nil, fmt.Errorf("could not fork/exec")
} }
dbp.Pid = pid dbp.pid = pid
for i := range argvSlice { for i := range argvSlice {
C.free(unsafe.Pointer(argvSlice[i])) C.free(unsafe.Pointer(argvSlice[i]))
} }
...@@ -86,7 +86,7 @@ func Launch(cmd []string, wd string) (*Process, error) { ...@@ -86,7 +86,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
// trapWait to wait until the child process calls execve. // trapWait to wait until the child process calls execve.
for { for {
err = dbp.updateThreadListForTask(C.get_task_for_pid(C.int(dbp.Pid))) err = dbp.updateThreadListForTask(C.get_task_for_pid(C.int(dbp.pid)))
if err == nil { if err == nil {
break break
} }
...@@ -100,7 +100,7 @@ func Launch(cmd []string, wd string) (*Process, error) { ...@@ -100,7 +100,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
} }
dbp.allGCache = nil dbp.allGCache = nil
for _, th := range dbp.Threads { for _, th := range dbp.threads {
th.clearBreakpointState() th.clearBreakpointState()
} }
...@@ -152,11 +152,11 @@ func (dbp *Process) Kill() (err error) { ...@@ -152,11 +152,11 @@ func (dbp *Process) Kill() (err error) {
if dbp.exited { if dbp.exited {
return nil return nil
} }
err = sys.Kill(-dbp.Pid, sys.SIGKILL) err = sys.Kill(-dbp.pid, sys.SIGKILL)
if err != nil { if err != nil {
return errors.New("could not deliver signal: " + err.Error()) return errors.New("could not deliver signal: " + err.Error())
} }
for port := range dbp.Threads { for port := range dbp.threads {
if C.thread_resume(C.thread_act_t(port)) != C.KERN_SUCCESS { if C.thread_resume(C.thread_act_t(port)) != C.KERN_SUCCESS {
return errors.New("could not resume task") return errors.New("could not resume task")
} }
...@@ -218,12 +218,12 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error { ...@@ -218,12 +218,12 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error {
return couldNotGetThreadList return couldNotGetThreadList
} }
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
thread.os.exists = false thread.os.exists = false
} }
for _, port := range list { for _, port := range list {
thread, ok := dbp.Threads[int(port)] thread, ok := dbp.threads[int(port)]
if !ok { if !ok {
thread, err = dbp.addThread(int(port), false) thread, err = dbp.addThread(int(port), false)
if err != nil { if err != nil {
...@@ -233,9 +233,9 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error { ...@@ -233,9 +233,9 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error {
thread.os.exists = true thread.os.exists = true
} }
for threadID, thread := range dbp.Threads { for threadID, thread := range dbp.threads {
if !thread.os.exists { if !thread.os.exists {
delete(dbp.Threads, threadID) delete(dbp.threads, threadID)
} }
} }
...@@ -243,7 +243,7 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error { ...@@ -243,7 +243,7 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error {
} }
func (dbp *Process) addThread(port int, attach bool) (*Thread, error) { func (dbp *Process) addThread(port int, attach bool) (*Thread, error) {
if thread, ok := dbp.Threads[port]; ok { if thread, ok := dbp.threads[port]; ok {
return thread, nil return thread, nil
} }
thread := &Thread{ thread := &Thread{
...@@ -251,7 +251,7 @@ func (dbp *Process) addThread(port int, attach bool) (*Thread, error) { ...@@ -251,7 +251,7 @@ func (dbp *Process) addThread(port int, attach bool) (*Thread, error) {
dbp: dbp, dbp: dbp,
os: new(OSSpecificDetails), os: new(OSSpecificDetails),
} }
dbp.Threads[port] = thread dbp.threads[port] = thread
thread.os.threadAct = C.thread_act_t(port) thread.os.threadAct = C.thread_act_t(port)
if dbp.CurrentThread == nil { if dbp.CurrentThread == nil {
dbp.SwitchThread(thread.ID) dbp.SwitchThread(thread.ID)
...@@ -338,7 +338,7 @@ var UnsupportedArchErr = errors.New("unsupported architecture - only darwin/amd6 ...@@ -338,7 +338,7 @@ var UnsupportedArchErr = errors.New("unsupported architecture - only darwin/amd6
func (dbp *Process) findExecutable(path string) (*macho.File, string, error) { func (dbp *Process) findExecutable(path string) (*macho.File, string, error) {
if path == "" { if path == "" {
path = C.GoString(C.find_executable(C.int(dbp.Pid))) path = C.GoString(C.find_executable(C.int(dbp.pid)))
} }
exe, err := macho.Open(path) exe, err := macho.Open(path)
if err != nil { if err != nil {
...@@ -369,16 +369,16 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -369,16 +369,16 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
continue continue
} }
if !dbp.os.initialized { if !dbp.os.initialized {
if pidtask := C.get_task_for_pid(C.int(dbp.Pid)); pidtask != 0 && dbp.os.task != pidtask { if pidtask := C.get_task_for_pid(C.int(dbp.pid)); pidtask != 0 && dbp.os.task != pidtask {
continue continue
} }
} }
_, status, err := dbp.wait(dbp.Pid, 0) _, status, err := dbp.wait(dbp.pid, 0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
dbp.postExit() dbp.postExit()
return nil, ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()} return nil, ProcessExitedError{Pid: dbp.pid, Status: status.ExitStatus()}
case C.MACH_RCV_INTERRUPTED: case C.MACH_RCV_INTERRUPTED:
if !dbp.halt { if !dbp.halt {
...@@ -407,7 +407,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -407,7 +407,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
// Since we cannot be notified of new threads on OS X // Since we cannot be notified of new threads on OS X
// this is as good a time as any to check for them. // this is as good a time as any to check for them.
dbp.updateThreadList() dbp.updateThreadList()
th, ok := dbp.Threads[int(port)] th, ok := dbp.threads[int(port)]
if !ok { if !ok {
if dbp.halt { if dbp.halt {
dbp.halt = false dbp.halt = false
...@@ -427,7 +427,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -427,7 +427,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
} }
func (dbp *Process) waitForStop() ([]int, error) { func (dbp *Process) waitForStop() ([]int, error) {
ports := make([]int, 0, len(dbp.Threads)) ports := make([]int, 0, len(dbp.threads))
count := 0 count := 0
for { for {
var task C.task_t var task C.task_t
...@@ -455,7 +455,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error { ...@@ -455,7 +455,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
} }
trapthread.SetCurrentBreakpoint() trapthread.SetCurrentBreakpoint()
for _, port := range ports { for _, port := range ports {
if th, ok := dbp.Threads[port]; ok { if th, ok := dbp.threads[port]; ok {
err := th.SetCurrentBreakpoint() err := th.SetCurrentBreakpoint()
if err != nil { if err != nil {
return err return err
...@@ -483,17 +483,17 @@ func (dbp *Process) exitGuard(err error) error { ...@@ -483,17 +483,17 @@ func (dbp *Process) exitGuard(err error) error {
if err != ErrContinueThread { if err != ErrContinueThread {
return err return err
} }
_, status, werr := dbp.wait(dbp.Pid, sys.WNOHANG) _, status, werr := dbp.wait(dbp.pid, sys.WNOHANG)
if werr == nil && status.Exited() { if werr == nil && status.Exited() {
dbp.postExit() dbp.postExit()
return ProcessExitedError{Pid: dbp.Pid, Status: status.ExitStatus()} return ProcessExitedError{Pid: dbp.pid, Status: status.ExitStatus()}
} }
return err return err
} }
func (dbp *Process) resume() error { func (dbp *Process) resume() error {
// all threads stopped over a breakpoint are made to step over it // all threads stopped over a breakpoint are made to step over it
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
if thread.CurrentBreakpoint != nil { if thread.CurrentBreakpoint != nil {
if err := thread.StepInstruction(); err != nil { if err := thread.StepInstruction(); err != nil {
return err return err
...@@ -502,7 +502,7 @@ func (dbp *Process) resume() error { ...@@ -502,7 +502,7 @@ func (dbp *Process) resume() error {
} }
} }
// everything is resumed // everything is resumed
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
if err := thread.resume(); err != nil { if err := thread.resume(); err != nil {
return dbp.exitGuard(err) return dbp.exitGuard(err)
} }
......
...@@ -70,7 +70,7 @@ func Launch(cmd []string, wd string) (*Process, error) { ...@@ -70,7 +70,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
dbp.Pid = proc.Process.Pid dbp.pid = proc.Process.Pid
_, _, err = dbp.wait(proc.Process.Pid, 0) _, _, err = dbp.wait(proc.Process.Pid, 0)
if err != nil { if err != nil {
return nil, fmt.Errorf("waiting for target execve failed: %s", err) return nil, fmt.Errorf("waiting for target execve failed: %s", err)
...@@ -88,13 +88,13 @@ func (dbp *Process) Kill() (err error) { ...@@ -88,13 +88,13 @@ func (dbp *Process) Kill() (err error) {
if dbp.exited { if dbp.exited {
return nil return nil
} }
if !dbp.Threads[dbp.Pid].Stopped() { if !dbp.threads[dbp.pid].Stopped() {
return errors.New("process must be stopped in order to kill it") return errors.New("process must be stopped in order to kill it")
} }
if err = sys.Kill(-dbp.Pid, sys.SIGKILL); err != nil { if err = sys.Kill(-dbp.pid, sys.SIGKILL); err != nil {
return errors.New("could not deliver signal " + err.Error()) return errors.New("could not deliver signal " + err.Error())
} }
if _, _, err = dbp.wait(dbp.Pid, 0); err != nil { if _, _, err = dbp.wait(dbp.pid, 0); err != nil {
return return
} }
dbp.postExit() dbp.postExit()
...@@ -102,13 +102,13 @@ func (dbp *Process) Kill() (err error) { ...@@ -102,13 +102,13 @@ func (dbp *Process) Kill() (err error) {
} }
func (dbp *Process) requestManualStop() (err error) { func (dbp *Process) requestManualStop() (err error) {
return sys.Kill(dbp.Pid, sys.SIGTRAP) return sys.Kill(dbp.pid, sys.SIGTRAP)
} }
// Attach to a newly created thread, and store that thread in our list of // Attach to a newly created thread, and store that thread in our list of
// known threads. // known threads.
func (dbp *Process) addThread(tid int, attach bool) (*Thread, error) { func (dbp *Process) addThread(tid int, attach bool) (*Thread, error) {
if thread, ok := dbp.Threads[tid]; ok { if thread, ok := dbp.threads[tid]; ok {
return thread, nil return thread, nil
} }
...@@ -145,26 +145,26 @@ func (dbp *Process) addThread(tid int, attach bool) (*Thread, error) { ...@@ -145,26 +145,26 @@ func (dbp *Process) addThread(tid int, attach bool) (*Thread, error) {
} }
} }
dbp.Threads[tid] = &Thread{ dbp.threads[tid] = &Thread{
ID: tid, ID: tid,
dbp: dbp, dbp: dbp,
os: new(OSSpecificDetails), os: new(OSSpecificDetails),
} }
if dbp.CurrentThread == nil { if dbp.currentThread == nil {
dbp.SwitchThread(tid) dbp.SwitchThread(tid)
} }
return dbp.Threads[tid], nil return dbp.threads[tid], nil
} }
func (dbp *Process) updateThreadList() error { func (dbp *Process) updateThreadList() error {
tids, _ := filepath.Glob(fmt.Sprintf("/proc/%d/task/*", dbp.Pid)) tids, _ := filepath.Glob(fmt.Sprintf("/proc/%d/task/*", dbp.pid))
for _, tidpath := range tids { for _, tidpath := range tids {
tidstr := filepath.Base(tidpath) tidstr := filepath.Base(tidpath)
tid, err := strconv.Atoi(tidstr) tid, err := strconv.Atoi(tidstr)
if err != nil { if err != nil {
return err return err
} }
if _, err := dbp.addThread(tid, tid != dbp.Pid); err != nil { if _, err := dbp.addThread(tid, tid != dbp.pid); err != nil {
return err return err
} }
} }
...@@ -175,7 +175,7 @@ var UnsupportedArchErr = errors.New("unsupported architecture - only linux/amd64 ...@@ -175,7 +175,7 @@ var UnsupportedArchErr = errors.New("unsupported architecture - only linux/amd64
func (dbp *Process) findExecutable(path string) (*elf.File, string, error) { func (dbp *Process) findExecutable(path string) (*elf.File, string, error) {
if path == "" { if path == "" {
path = fmt.Sprintf("/proc/%d/exe", dbp.Pid) path = fmt.Sprintf("/proc/%d/exe", dbp.pid)
} }
f, err := os.OpenFile(path, 0, os.ModePerm) f, err := os.OpenFile(path, 0, os.ModePerm)
if err != nil { if err != nil {
...@@ -279,16 +279,16 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -279,16 +279,16 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
if wpid == 0 { if wpid == 0 {
continue continue
} }
th, ok := dbp.Threads[wpid] th, ok := dbp.threads[wpid]
if ok { if ok {
th.Status = (*WaitStatus)(status) th.Status = (*WaitStatus)(status)
} }
if status.Exited() { if status.Exited() {
if wpid == dbp.Pid { if wpid == dbp.pid {
dbp.postExit() dbp.postExit()
return nil, ProcessExitedError{Pid: wpid, Status: status.ExitStatus()} return nil, ProcessExitedError{Pid: wpid, Status: status.ExitStatus()}
} }
delete(dbp.Threads, wpid) delete(dbp.threads, wpid)
continue continue
} }
if status.StopSignal() == sys.SIGTRAP && status.TrapCause() == sys.PTRACE_EVENT_CLONE { if status.StopSignal() == sys.SIGTRAP && status.TrapCause() == sys.PTRACE_EVENT_CLONE {
...@@ -314,12 +314,12 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -314,12 +314,12 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
if err = th.Continue(); err != nil { if err = th.Continue(); err != nil {
if err == sys.ESRCH { if err == sys.ESRCH {
// thread died while we were adding it // thread died while we were adding it
delete(dbp.Threads, th.ID) delete(dbp.threads, th.ID)
continue continue
} }
return nil, fmt.Errorf("could not continue new thread %d %s", cloned, err) return nil, fmt.Errorf("could not continue new thread %d %s", cloned, err)
} }
if err = dbp.Threads[int(wpid)].Continue(); err != nil { if err = dbp.threads[int(wpid)].Continue(); err != nil {
if err != sys.ESRCH { if err != sys.ESRCH {
return nil, fmt.Errorf("could not continue existing thread %d %s", wpid, err) return nil, fmt.Errorf("could not continue existing thread %d %s", wpid, err)
} }
...@@ -343,7 +343,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -343,7 +343,7 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
// TODO(dp) alert user about unexpected signals here. // TODO(dp) alert user about unexpected signals here.
if err := th.resumeWithSig(int(status.StopSignal())); err != nil { if err := th.resumeWithSig(int(status.StopSignal())); err != nil {
if err == sys.ESRCH { if err == sys.ESRCH {
return nil, ProcessExitedError{Pid: dbp.Pid} return nil, ProcessExitedError{Pid: dbp.pid}
} }
return nil, err return nil, err
} }
...@@ -354,19 +354,19 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -354,19 +354,19 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) { func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
comm, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/comm", dbp.Pid)) comm, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/comm", dbp.pid))
if err == nil { if err == nil {
// removes newline character // removes newline character
comm = bytes.TrimSuffix(comm, []byte("\n")) comm = bytes.TrimSuffix(comm, []byte("\n"))
} }
if comm == nil || len(comm) <= 0 { if comm == nil || len(comm) <= 0 {
stat, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", dbp.Pid)) stat, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", dbp.pid))
if err != nil { if err != nil {
fmt.Printf("Could not read proc stat: %v\n", err) fmt.Printf("Could not read proc stat: %v\n", err)
os.Exit(1) os.Exit(1)
} }
expr := fmt.Sprintf("%d\\s*\\((.*)\\)", dbp.Pid) expr := fmt.Sprintf("%d\\s*\\((.*)\\)", dbp.pid)
rexp, err := regexp.Compile(expr) rexp, err := regexp.Compile(expr)
if err != nil { if err != nil {
fmt.Printf("Regexp compile error: %v\n", err) fmt.Printf("Regexp compile error: %v\n", err)
...@@ -374,7 +374,7 @@ func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) { ...@@ -374,7 +374,7 @@ func (dbp *Process) loadProcessInformation(wg *sync.WaitGroup) {
} }
match := rexp.FindSubmatch(stat) match := rexp.FindSubmatch(stat)
if match == nil { if match == nil {
fmt.Printf("No match found using regexp '%s' in /proc/%d/stat\n", expr, dbp.Pid) fmt.Printf("No match found using regexp '%s' in /proc/%d/stat\n", expr, dbp.pid)
os.Exit(1) os.Exit(1)
} }
comm = match[1] comm = match[1]
...@@ -411,7 +411,7 @@ func (dbp *Process) waitFast(pid int) (int, *sys.WaitStatus, error) { ...@@ -411,7 +411,7 @@ func (dbp *Process) waitFast(pid int) (int, *sys.WaitStatus, error) {
func (dbp *Process) wait(pid, options int) (int, *sys.WaitStatus, error) { func (dbp *Process) wait(pid, options int) (int, *sys.WaitStatus, error) {
var s sys.WaitStatus var s sys.WaitStatus
if (pid != dbp.Pid) || (options != 0) { if (pid != dbp.pid) || (options != 0) {
wpid, err := sys.Wait4(pid, &s, sys.WALL|options, nil) wpid, err := sys.Wait4(pid, &s, sys.WALL|options, nil)
return wpid, &s, err return wpid, &s, err
} }
...@@ -442,7 +442,7 @@ func (dbp *Process) wait(pid, options int) (int, *sys.WaitStatus, error) { ...@@ -442,7 +442,7 @@ func (dbp *Process) wait(pid, options int) (int, *sys.WaitStatus, error) {
} }
func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error { func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
for _, th := range dbp.Threads { for _, th := range dbp.threads {
if th.CurrentBreakpoint == nil { if th.CurrentBreakpoint == nil {
err := th.SetCurrentBreakpoint() err := th.SetCurrentBreakpoint()
if err != nil { if err != nil {
...@@ -457,7 +457,7 @@ func (dbp *Process) exitGuard(err error) error { ...@@ -457,7 +457,7 @@ func (dbp *Process) exitGuard(err error) error {
if err != sys.ESRCH { if err != sys.ESRCH {
return err return err
} }
if status(dbp.Pid, dbp.os.comm) == StatusZombie { if status(dbp.pid, dbp.os.comm) == StatusZombie {
_, err := dbp.trapWait(-1) _, err := dbp.trapWait(-1)
return err return err
} }
...@@ -467,7 +467,7 @@ func (dbp *Process) exitGuard(err error) error { ...@@ -467,7 +467,7 @@ func (dbp *Process) exitGuard(err error) error {
func (dbp *Process) resume() error { func (dbp *Process) resume() error {
// all threads stopped over a breakpoint are made to step over it // all threads stopped over a breakpoint are made to step over it
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
if thread.CurrentBreakpoint != nil { if thread.CurrentBreakpoint != nil {
if err := thread.StepInstruction(); err != nil { if err := thread.StepInstruction(); err != nil {
return err return err
...@@ -476,7 +476,7 @@ func (dbp *Process) resume() error { ...@@ -476,7 +476,7 @@ func (dbp *Process) resume() error {
} }
} }
// everything is resumed // everything is resumed
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
if err := thread.resume(); err != nil && err != sys.ESRCH { if err := thread.resume(); err != nil && err != sys.ESRCH {
return err return err
} }
......
...@@ -108,7 +108,7 @@ func TestExit(t *testing.T) { ...@@ -108,7 +108,7 @@ func TestExit(t *testing.T) {
if pe.Status != 0 { if pe.Status != 0 {
t.Errorf("Unexpected error status: %d", pe.Status) t.Errorf("Unexpected error status: %d", pe.Status)
} }
if pe.Pid != p.Pid { if pe.Pid != p.pid {
t.Errorf("Unexpected process id: %d", pe.Pid) t.Errorf("Unexpected process id: %d", pe.Pid)
} }
}) })
...@@ -127,7 +127,7 @@ func TestExitAfterContinue(t *testing.T) { ...@@ -127,7 +127,7 @@ func TestExitAfterContinue(t *testing.T) {
if pe.Status != 0 { if pe.Status != 0 {
t.Errorf("Unexpected error status: %d", pe.Status) t.Errorf("Unexpected error status: %d", pe.Status)
} }
if pe.Pid != p.Pid { if pe.Pid != p.pid {
t.Errorf("Unexpected process id: %d", pe.Pid) t.Errorf("Unexpected process id: %d", pe.Pid)
} }
}) })
...@@ -159,7 +159,7 @@ func TestHalt(t *testing.T) { ...@@ -159,7 +159,7 @@ func TestHalt(t *testing.T) {
_, err := setFunctionBreakpoint(p, "main.loop") _, err := setFunctionBreakpoint(p, "main.loop")
assertNoError(err, t, "SetBreakpoint") assertNoError(err, t, "SetBreakpoint")
assertNoError(p.Continue(), t, "Continue") assertNoError(p.Continue(), t, "Continue")
for _, th := range p.Threads { for _, th := range p.threads {
if th.running != false { if th.running != false {
t.Fatal("expected running = false for thread", th.ID) t.Fatal("expected running = false for thread", th.ID)
} }
...@@ -182,7 +182,7 @@ func TestHalt(t *testing.T) { ...@@ -182,7 +182,7 @@ func TestHalt(t *testing.T) {
// Loop through threads and make sure they are all // Loop through threads and make sure they are all
// actually stopped, err will not be nil if the process // actually stopped, err will not be nil if the process
// is still running. // is still running.
for _, th := range p.Threads { for _, th := range p.threads {
if !th.Stopped() { if !th.Stopped() {
t.Fatal("expected thread to be stopped, but was not") t.Fatal("expected thread to be stopped, but was not")
} }
...@@ -207,7 +207,7 @@ func TestStep(t *testing.T) { ...@@ -207,7 +207,7 @@ func TestStep(t *testing.T) {
regs := getRegisters(p, t) regs := getRegisters(p, t)
rip := regs.PC() rip := regs.PC()
err = p.CurrentThread.StepInstruction() err = p.currentThread.StepInstruction()
assertNoError(err, t, "Step()") assertNoError(err, t, "Step()")
regs = getRegisters(p, t) regs = getRegisters(p, t)
...@@ -289,7 +289,7 @@ func TestClearBreakpointBreakpoint(t *testing.T) { ...@@ -289,7 +289,7 @@ func TestClearBreakpointBreakpoint(t *testing.T) {
bp, err = p.ClearBreakpoint(fn.Entry) bp, err = p.ClearBreakpoint(fn.Entry)
assertNoError(err, t, "ClearBreakpoint()") assertNoError(err, t, "ClearBreakpoint()")
data, err := dataAtAddr(p.CurrentThread, bp.Addr) data, err := dataAtAddr(p.currentThread, bp.Addr)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -311,7 +311,7 @@ type nextTest struct { ...@@ -311,7 +311,7 @@ type nextTest struct {
func countBreakpoints(p *Process) int { func countBreakpoints(p *Process) int {
bpcount := 0 bpcount := 0
for _, bp := range p.Breakpoints { for _, bp := range p.breakpoints {
if bp.ID >= 0 { if bp.ID >= 0 {
bpcount++ bpcount++
} }
...@@ -341,11 +341,11 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc ...@@ -341,11 +341,11 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
p.CurrentThread.SetPC(bp.Addr) p.currentThread.SetPC(bp.Addr)
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
for _, tc := range testcases { for _, tc := range testcases {
pc, _ := p.CurrentThread.PC() pc, _ := p.currentThread.PC()
if ln != tc.begin { if ln != tc.begin {
t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln) t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln)
} }
...@@ -358,14 +358,14 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc ...@@ -358,14 +358,14 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc
} }
f, ln = currentLineNumber(p, t) f, ln = currentLineNumber(p, t)
pc, _ = p.CurrentThread.PC() pc, _ = p.currentThread.PC()
if ln != tc.end { if ln != tc.end {
t.Fatalf("Program did not continue to correct next location expected %d was %s:%d (%#x)", tc.end, filepath.Base(f), ln, pc) t.Fatalf("Program did not continue to correct next location expected %d was %s:%d (%#x)", tc.end, filepath.Base(f), ln, pc)
} }
} }
if countBreakpoints(p) != 0 { if countBreakpoints(p) != 0 {
t.Fatal("Not all breakpoints were cleaned up", len(p.Breakpoints)) t.Fatal("Not all breakpoints were cleaned up", len(p.breakpoints))
} }
}) })
} }
...@@ -434,10 +434,10 @@ func TestNextConcurrent(t *testing.T) { ...@@ -434,10 +434,10 @@ func TestNextConcurrent(t *testing.T) {
_, err = p.ClearBreakpoint(bp.Addr) _, err = p.ClearBreakpoint(bp.Addr)
assertNoError(err, t, "ClearBreakpoint()") assertNoError(err, t, "ClearBreakpoint()")
for _, tc := range testcases { for _, tc := range testcases {
g, err := p.CurrentThread.GetG() g, err := p.currentThread.GetG()
assertNoError(err, t, "GetG()") assertNoError(err, t, "GetG()")
if p.SelectedGoroutine.ID != g.ID { if p.selectedGoroutine.ID != g.ID {
t.Fatalf("SelectedGoroutine not CurrentThread's goroutine: %d %d", g.ID, p.SelectedGoroutine.ID) t.Fatalf("SelectedGoroutine not CurrentThread's goroutine: %d %d", g.ID, p.selectedGoroutine.ID)
} }
if ln != tc.begin { if ln != tc.begin {
t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln) t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln)
...@@ -473,10 +473,10 @@ func TestNextConcurrentVariant2(t *testing.T) { ...@@ -473,10 +473,10 @@ func TestNextConcurrentVariant2(t *testing.T) {
initVval, _ := constant.Int64Val(initV.Value) initVval, _ := constant.Int64Val(initV.Value)
assertNoError(err, t, "EvalVariable") assertNoError(err, t, "EvalVariable")
for _, tc := range testcases { for _, tc := range testcases {
g, err := p.CurrentThread.GetG() g, err := p.currentThread.GetG()
assertNoError(err, t, "GetG()") assertNoError(err, t, "GetG()")
if p.SelectedGoroutine.ID != g.ID { if p.selectedGoroutine.ID != g.ID {
t.Fatalf("SelectedGoroutine not CurrentThread's goroutine: %d %d", g.ID, p.SelectedGoroutine.ID) t.Fatalf("SelectedGoroutine not CurrentThread's goroutine: %d %d", g.ID, p.selectedGoroutine.ID)
} }
if ln != tc.begin { if ln != tc.begin {
t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln) t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln)
...@@ -487,7 +487,7 @@ func TestNextConcurrentVariant2(t *testing.T) { ...@@ -487,7 +487,7 @@ func TestNextConcurrentVariant2(t *testing.T) {
v, err := evalVariable(p, "n") v, err := evalVariable(p, "n")
assertNoError(err, t, "EvalVariable") assertNoError(err, t, "EvalVariable")
vval, _ = constant.Int64Val(v.Value) vval, _ = constant.Int64Val(v.Value)
if p.CurrentThread.CurrentBreakpoint == nil { if p.currentThread.CurrentBreakpoint == nil {
if vval != initVval { if vval != initVval {
t.Fatal("Did not end up on same goroutine") t.Fatal("Did not end up on same goroutine")
} }
...@@ -599,7 +599,7 @@ func TestFindReturnAddress(t *testing.T) { ...@@ -599,7 +599,7 @@ func TestFindReturnAddress(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
addr, err := p.CurrentThread.ReturnAddress() addr, err := p.currentThread.ReturnAddress()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -623,7 +623,7 @@ func TestFindReturnAddressTopOfStackFn(t *testing.T) { ...@@ -623,7 +623,7 @@ func TestFindReturnAddressTopOfStackFn(t *testing.T) {
if err := p.Continue(); err != nil { if err := p.Continue(); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := p.CurrentThread.ReturnAddress(); err == nil { if _, err := p.currentThread.ReturnAddress(); err == nil {
t.Fatal("expected error to be returned") t.Fatal("expected error to be returned")
} }
}) })
...@@ -649,8 +649,8 @@ func TestSwitchThread(t *testing.T) { ...@@ -649,8 +649,8 @@ func TestSwitchThread(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
var nt int var nt int
ct := p.CurrentThread.ID ct := p.currentThread.ID
for tid := range p.Threads { for tid := range p.threads {
if tid != ct { if tid != ct {
nt = tid nt = tid
break break
...@@ -664,7 +664,7 @@ func TestSwitchThread(t *testing.T) { ...@@ -664,7 +664,7 @@ func TestSwitchThread(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if p.CurrentThread.ID != nt { if p.currentThread.ID != nt {
t.Fatal("Did not switch threads") t.Fatal("Did not switch threads")
} }
}) })
...@@ -725,7 +725,7 @@ func TestStacktrace(t *testing.T) { ...@@ -725,7 +725,7 @@ func TestStacktrace(t *testing.T) {
for i := range stacks { for i := range stacks {
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
locations, err := p.CurrentThread.Stacktrace(40) locations, err := p.currentThread.Stacktrace(40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if len(locations) != len(stacks[i])+2 { if len(locations) != len(stacks[i])+2 {
...@@ -753,7 +753,7 @@ func TestStacktrace2(t *testing.T) { ...@@ -753,7 +753,7 @@ func TestStacktrace2(t *testing.T) {
withTestProcess("retstack", t, func(p *Process, fixture protest.Fixture) { withTestProcess("retstack", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
locations, err := p.CurrentThread.Stacktrace(40) locations, err := p.currentThread.Stacktrace(40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if !stackMatch([]loc{{-1, "main.f"}, {16, "main.main"}}, locations, false) { if !stackMatch([]loc{{-1, "main.f"}, {16, "main.main"}}, locations, false) {
for i := range locations { for i := range locations {
...@@ -763,7 +763,7 @@ func TestStacktrace2(t *testing.T) { ...@@ -763,7 +763,7 @@ func TestStacktrace2(t *testing.T) {
} }
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
locations, err = p.CurrentThread.Stacktrace(40) locations, err = p.currentThread.Stacktrace(40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if !stackMatch([]loc{{-1, "main.g"}, {17, "main.main"}}, locations, false) { if !stackMatch([]loc{{-1, "main.g"}, {17, "main.main"}}, locations, false) {
for i := range locations { for i := range locations {
...@@ -863,9 +863,9 @@ func TestKill(t *testing.T) { ...@@ -863,9 +863,9 @@ func TestKill(t *testing.T) {
t.Fatal("expected process to have exited") t.Fatal("expected process to have exited")
} }
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
_, err := os.Open(fmt.Sprintf("/proc/%d/", p.Pid)) _, err := os.Open(fmt.Sprintf("/proc/%d/", p.pid))
if err == nil { if err == nil {
t.Fatal("process has not exited", p.Pid) t.Fatal("process has not exited", p.pid)
} }
} }
}) })
...@@ -877,7 +877,7 @@ func testGSupportFunc(name string, t *testing.T, p *Process, fixture protest.Fix ...@@ -877,7 +877,7 @@ func testGSupportFunc(name string, t *testing.T, p *Process, fixture protest.Fix
assertNoError(p.Continue(), t, name+": Continue()") assertNoError(p.Continue(), t, name+": Continue()")
g, err := p.CurrentThread.GetG() g, err := p.currentThread.GetG()
assertNoError(err, t, name+": GetG()") assertNoError(err, t, name+": GetG()")
if g == nil { if g == nil {
...@@ -1005,7 +1005,7 @@ func TestIssue239(t *testing.T) { ...@@ -1005,7 +1005,7 @@ func TestIssue239(t *testing.T) {
} }
func evalVariable(p *Process, symbol string) (*Variable, error) { func evalVariable(p *Process, symbol string) (*Variable, error) {
scope, err := p.CurrentThread.Scope() scope, err := p.currentThread.Scope()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -1013,7 +1013,7 @@ func evalVariable(p *Process, symbol string) (*Variable, error) { ...@@ -1013,7 +1013,7 @@ func evalVariable(p *Process, symbol string) (*Variable, error) {
} }
func setVariable(p *Process, symbol, value string) error { func setVariable(p *Process, symbol, value string) error {
scope, err := p.CurrentThread.Scope() scope, err := p.currentThread.Scope()
if err != nil { if err != nil {
return err return err
} }
...@@ -1152,7 +1152,7 @@ func TestFrameEvaluation(t *testing.T) { ...@@ -1152,7 +1152,7 @@ func TestFrameEvaluation(t *testing.T) {
// Testing evaluation on frames // Testing evaluation on frames
assertNoError(p.Continue(), t, "Continue() 2") assertNoError(p.Continue(), t, "Continue() 2")
g, err := p.CurrentThread.GetG() g, err := p.currentThread.GetG()
assertNoError(err, t, "GetG()") assertNoError(err, t, "GetG()")
for i := 0; i <= 3; i++ { for i := 0; i <= 3; i++ {
...@@ -1185,7 +1185,7 @@ func TestPointerSetting(t *testing.T) { ...@@ -1185,7 +1185,7 @@ func TestPointerSetting(t *testing.T) {
pval(1) pval(1)
// change p1 to point to i2 // change p1 to point to i2
scope, err := p.CurrentThread.Scope() scope, err := p.currentThread.Scope()
assertNoError(err, t, "Scope()") assertNoError(err, t, "Scope()")
i2addr, err := scope.EvalExpression("i2", normalLoadConfig) i2addr, err := scope.EvalExpression("i2", normalLoadConfig)
assertNoError(err, t, "EvalExpression()") assertNoError(err, t, "EvalExpression()")
...@@ -1320,7 +1320,7 @@ func TestBreakpointCountsWithDetection(t *testing.T) { ...@@ -1320,7 +1320,7 @@ func TestBreakpointCountsWithDetection(t *testing.T) {
} }
assertNoError(err, t, "Continue()") assertNoError(err, t, "Continue()")
} }
for _, th := range p.Threads { for _, th := range p.threads {
if th.CurrentBreakpoint == nil { if th.CurrentBreakpoint == nil {
continue continue
} }
...@@ -1454,7 +1454,7 @@ func TestIssue341(t *testing.T) { ...@@ -1454,7 +1454,7 @@ func TestIssue341(t *testing.T) {
func BenchmarkLocalVariables(b *testing.B) { func BenchmarkLocalVariables(b *testing.B) {
withTestProcess("testvariables", b, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables", b, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), b, "Continue() returned an error") assertNoError(p.Continue(), b, "Continue() returned an error")
scope, err := p.CurrentThread.Scope() scope, err := p.currentThread.Scope()
assertNoError(err, b, "Scope()") assertNoError(err, b, "Scope()")
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_, err := scope.LocalVariables(normalLoadConfig) _, err := scope.LocalVariables(normalLoadConfig)
...@@ -1588,7 +1588,7 @@ func TestIssue332_Part1(t *testing.T) { ...@@ -1588,7 +1588,7 @@ func TestIssue332_Part1(t *testing.T) {
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
assertNoError(p.Next(), t, "first Next()") assertNoError(p.Next(), t, "first Next()")
locations, err := p.CurrentThread.Stacktrace(2) locations, err := p.currentThread.Stacktrace(2)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if locations[0].Call.Fn == nil { if locations[0].Call.Fn == nil {
t.Fatalf("Not on a function") t.Fatalf("Not on a function")
...@@ -1617,7 +1617,7 @@ func TestIssue332_Part2(t *testing.T) { ...@@ -1617,7 +1617,7 @@ func TestIssue332_Part2(t *testing.T) {
// step until we enter changeMe // step until we enter changeMe
for { for {
assertNoError(p.Step(), t, "Step()") assertNoError(p.Step(), t, "Step()")
locations, err := p.CurrentThread.Stacktrace(2) locations, err := p.currentThread.Stacktrace(2)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if locations[0].Call.Fn == nil { if locations[0].Call.Fn == nil {
t.Fatalf("Not on a function") t.Fatalf("Not on a function")
...@@ -1627,7 +1627,7 @@ func TestIssue332_Part2(t *testing.T) { ...@@ -1627,7 +1627,7 @@ func TestIssue332_Part2(t *testing.T) {
} }
} }
pc, err := p.CurrentThread.PC() pc, err := p.currentThread.PC()
assertNoError(err, t, "PC()") assertNoError(err, t, "PC()")
pcAfterPrologue, err := p.FindFunctionLocation("main.changeMe", true, -1) pcAfterPrologue, err := p.FindFunctionLocation("main.changeMe", true, -1)
assertNoError(err, t, "FindFunctionLocation()") assertNoError(err, t, "FindFunctionLocation()")
...@@ -1680,7 +1680,7 @@ func TestPackageVariables(t *testing.T) { ...@@ -1680,7 +1680,7 @@ func TestPackageVariables(t *testing.T) {
withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := p.Continue()
assertNoError(err, t, "Continue()") assertNoError(err, t, "Continue()")
scope, err := p.CurrentThread.Scope() scope, err := p.currentThread.Scope()
assertNoError(err, t, "Scope()") assertNoError(err, t, "Scope()")
vars, err := scope.PackageVariables(normalLoadConfig) vars, err := scope.PackageVariables(normalLoadConfig)
assertNoError(err, t, "PackageVariables()") assertNoError(err, t, "PackageVariables()")
...@@ -1714,7 +1714,7 @@ func TestPanicBreakpoint(t *testing.T) { ...@@ -1714,7 +1714,7 @@ func TestPanicBreakpoint(t *testing.T) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
bp := p.CurrentBreakpoint() bp := p.CurrentBreakpoint()
if bp == nil || bp.Name != "unrecovered-panic" { if bp == nil || bp.Name != "unrecovered-panic" {
t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint) t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint())
} }
}) })
} }
...@@ -1724,7 +1724,7 @@ func TestCmdLineArgs(t *testing.T) { ...@@ -1724,7 +1724,7 @@ func TestCmdLineArgs(t *testing.T) {
err := p.Continue() err := p.Continue()
bp := p.CurrentBreakpoint() bp := p.CurrentBreakpoint()
if bp != nil && bp.Name == "unrecovered-panic" { if bp != nil && bp.Name == "unrecovered-panic" {
t.Fatalf("testing args failed on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint) t.Fatalf("testing args failed on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint())
} }
exit, exited := err.(ProcessExitedError) exit, exited := err.(ProcessExitedError)
if !exited { if !exited {
...@@ -1740,7 +1740,7 @@ func TestCmdLineArgs(t *testing.T) { ...@@ -1740,7 +1740,7 @@ func TestCmdLineArgs(t *testing.T) {
p.Continue() p.Continue()
bp := p.CurrentBreakpoint() bp := p.CurrentBreakpoint()
if bp == nil || bp.Name != "unrecovered-panic" { if bp == nil || bp.Name != "unrecovered-panic" {
t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint) t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint())
} }
} }
...@@ -1783,7 +1783,7 @@ func TestIssue462(t *testing.T) { ...@@ -1783,7 +1783,7 @@ func TestIssue462(t *testing.T) {
}() }()
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
_, err := p.CurrentThread.Stacktrace(40) _, err := p.currentThread.Stacktrace(40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
}) })
} }
...@@ -1828,8 +1828,8 @@ func TestNextParked(t *testing.T) { ...@@ -1828,8 +1828,8 @@ func TestNextParked(t *testing.T) {
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
assertNoError(p.Next(), t, "Next()") assertNoError(p.Next(), t, "Next()")
if p.SelectedGoroutine.ID != parkedg.ID { if p.selectedGoroutine.ID != parkedg.ID {
t.Fatalf("Next did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.SelectedGoroutine.ID) t.Fatalf("Next did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.selectedGoroutine.ID)
} }
}) })
} }
...@@ -1865,8 +1865,8 @@ func TestStepParked(t *testing.T) { ...@@ -1865,8 +1865,8 @@ func TestStepParked(t *testing.T) {
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
assertNoError(p.Step(), t, "Step()") assertNoError(p.Step(), t, "Step()")
if p.SelectedGoroutine.ID != parkedg.ID { if p.selectedGoroutine.ID != parkedg.ID {
t.Fatalf("Step did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.SelectedGoroutine.ID) t.Fatalf("Step did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.selectedGoroutine.ID)
} }
}) })
} }
...@@ -2093,7 +2093,7 @@ func TestStepConcurrentDirect(t *testing.T) { ...@@ -2093,7 +2093,7 @@ func TestStepConcurrentDirect(t *testing.T) {
_, err = p.ClearBreakpoint(bp.Addr) _, err = p.ClearBreakpoint(bp.Addr)
assertNoError(err, t, "ClearBreakpoint()") assertNoError(err, t, "ClearBreakpoint()")
gid := p.SelectedGoroutine.ID gid := p.selectedGoroutine.ID
seq := []int{37, 38, 13, 15, 16, 38} seq := []int{37, 38, 13, 15, 16, 38}
...@@ -2108,8 +2108,8 @@ func TestStepConcurrentDirect(t *testing.T) { ...@@ -2108,8 +2108,8 @@ func TestStepConcurrentDirect(t *testing.T) {
} }
t.Fatalf("Program did not continue at expected location (%d) %s:%d", seq[i], f, ln) t.Fatalf("Program did not continue at expected location (%d) %s:%d", seq[i], f, ln)
} }
if p.SelectedGoroutine.ID != gid { if p.selectedGoroutine.ID != gid {
t.Fatalf("Step switched to different goroutine %d %d\n", gid, p.SelectedGoroutine.ID) t.Fatalf("Step switched to different goroutine %d %d\n", gid, p.selectedGoroutine.ID)
} }
i = (i + 1) % len(seq) i = (i + 1) % len(seq)
if i == 0 { if i == 0 {
...@@ -2125,7 +2125,7 @@ func TestStepConcurrentDirect(t *testing.T) { ...@@ -2125,7 +2125,7 @@ func TestStepConcurrentDirect(t *testing.T) {
} }
func nextInProgress(p *Process) bool { func nextInProgress(p *Process) bool {
for _, bp := range p.Breakpoints { for _, bp := range p.breakpoints {
if bp.Internal() { if bp.Internal() {
return true return true
} }
...@@ -2155,7 +2155,7 @@ func TestStepConcurrentPtr(t *testing.T) { ...@@ -2155,7 +2155,7 @@ func TestStepConcurrentPtr(t *testing.T) {
t.Fatalf("Program did not continue at expected location (24): %s:%d", f, ln) t.Fatalf("Program did not continue at expected location (24): %s:%d", f, ln)
} }
gid := p.SelectedGoroutine.ID gid := p.selectedGoroutine.ID
kvar, err := evalVariable(p, "k") kvar, err := evalVariable(p, "k")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
...@@ -2170,14 +2170,14 @@ func TestStepConcurrentPtr(t *testing.T) { ...@@ -2170,14 +2170,14 @@ func TestStepConcurrentPtr(t *testing.T) {
assertNoError(p.Step(), t, "Step()") assertNoError(p.Step(), t, "Step()")
for nextInProgress(p) { for nextInProgress(p) {
if p.SelectedGoroutine.ID == gid { if p.selectedGoroutine.ID == gid {
t.Fatalf("step did not step into function call (but internal breakpoints still active?) (%d %d)", gid, p.SelectedGoroutine.ID) t.Fatalf("step did not step into function call (but internal breakpoints still active?) (%d %d)", gid, p.selectedGoroutine.ID)
} }
assertNoError(p.Continue(), t, "Continue()") assertNoError(p.Continue(), t, "Continue()")
} }
if p.SelectedGoroutine.ID != gid { if p.selectedGoroutine.ID != gid {
t.Fatalf("Step switched goroutines (wanted: %d got: %d)", gid, p.SelectedGoroutine.ID) t.Fatalf("Step switched goroutines (wanted: %d got: %d)", gid, p.selectedGoroutine.ID)
} }
f, ln = currentLineNumber(p, t) f, ln = currentLineNumber(p, t)
...@@ -2256,9 +2256,9 @@ func TestStepOnCallPtrInstr(t *testing.T) { ...@@ -2256,9 +2256,9 @@ func TestStepOnCallPtrInstr(t *testing.T) {
if ln != 10 { if ln != 10 {
break break
} }
pc, err := p.CurrentThread.PC() pc, err := p.currentThread.PC()
assertNoError(err, t, "PC()") assertNoError(err, t, "PC()")
text, err := p.CurrentThread.Disassemble(pc, pc+maxInstructionLength, true) text, err := p.currentThread.Disassemble(pc, pc+maxInstructionLength, true)
assertNoError(err, t, "Disassemble()") assertNoError(err, t, "Disassemble()")
if text[0].IsCall() { if text[0].IsCall() {
found = true found = true
...@@ -2394,7 +2394,7 @@ func BenchmarkTrace(b *testing.B) { ...@@ -2394,7 +2394,7 @@ func BenchmarkTrace(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
assertNoError(p.Continue(), b, "Continue()") assertNoError(p.Continue(), b, "Continue()")
s, err := p.CurrentThread.Scope() s, err := p.currentThread.Scope()
assertNoError(err, b, "Scope()") assertNoError(err, b, "Scope()")
_, err = s.FunctionArguments(LoadConfig{false, 0, 64, 0, 3}) _, err = s.FunctionArguments(LoadConfig{false, 0, 64, 0, 3})
assertNoError(err, b, "FunctionArguments()") assertNoError(err, b, "FunctionArguments()")
......
...@@ -17,7 +17,7 @@ func TestIssue419(t *testing.T) { ...@@ -17,7 +17,7 @@ func TestIssue419(t *testing.T) {
for { for {
if p.Running() { if p.Running() {
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
err := syscall.Kill(p.Pid, syscall.SIGINT) err := syscall.Kill(p.pid, syscall.SIGINT)
assertNoError(err, t, "syscall.Kill") assertNoError(err, t, "syscall.Kill")
return return
} }
......
...@@ -113,7 +113,7 @@ func Launch(cmd []string, wd string) (*Process, error) { ...@@ -113,7 +113,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
sys.CloseHandle(sys.Handle(pi.Process)) sys.CloseHandle(sys.Handle(pi.Process))
sys.CloseHandle(sys.Handle(pi.Thread)) sys.CloseHandle(sys.Handle(pi.Thread))
dbp.Pid = int(pi.ProcessId) dbp.pid = int(pi.ProcessId)
return newDebugProcess(dbp, argv0Go) return newDebugProcess(dbp, argv0Go)
} }
...@@ -135,11 +135,11 @@ func newDebugProcess(dbp *Process, exepath string) (*Process, error) { ...@@ -135,11 +135,11 @@ func newDebugProcess(dbp *Process, exepath string) (*Process, error) {
} }
if tid == 0 { if tid == 0 {
dbp.postExit() dbp.postExit()
return nil, ProcessExitedError{Pid: dbp.Pid, Status: exitCode} return nil, ProcessExitedError{Pid: dbp.pid, Status: exitCode}
} }
// Suspend all threads so that the call to _ContinueDebugEvent will // Suspend all threads so that the call to _ContinueDebugEvent will
// not resume the target. // not resume the target.
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
_, err := _SuspendThread(thread.os.hThread) _, err := _SuspendThread(thread.os.hThread)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -147,7 +147,7 @@ func newDebugProcess(dbp *Process, exepath string) (*Process, error) { ...@@ -147,7 +147,7 @@ func newDebugProcess(dbp *Process, exepath string) (*Process, error) {
} }
dbp.execPtraceFunc(func() { dbp.execPtraceFunc(func() {
err = _ContinueDebugEvent(uint32(dbp.Pid), uint32(dbp.os.breakThread), _DBG_CONTINUE) err = _ContinueDebugEvent(uint32(dbp.pid), uint32(dbp.os.breakThread), _DBG_CONTINUE)
}) })
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -209,7 +209,7 @@ func (dbp *Process) Kill() error { ...@@ -209,7 +209,7 @@ func (dbp *Process) Kill() error {
if dbp.exited { if dbp.exited {
return nil return nil
} }
if !dbp.Threads[dbp.Pid].Stopped() { if !dbp.threads[dbp.pid].Stopped() {
return errors.New("process must be stopped in order to kill it") return errors.New("process must be stopped in order to kill it")
} }
// TODO: Should not have to ignore failures here, // TODO: Should not have to ignore failures here,
...@@ -231,7 +231,7 @@ func (dbp *Process) updateThreadList() error { ...@@ -231,7 +231,7 @@ func (dbp *Process) updateThreadList() error {
} }
func (dbp *Process) addThread(hThread syscall.Handle, threadID int, attach, suspendNewThreads bool) (*Thread, error) { func (dbp *Process) addThread(hThread syscall.Handle, threadID int, attach, suspendNewThreads bool) (*Thread, error) {
if thread, ok := dbp.Threads[threadID]; ok { if thread, ok := dbp.threads[threadID]; ok {
return thread, nil return thread, nil
} }
thread := &Thread{ thread := &Thread{
...@@ -240,7 +240,7 @@ func (dbp *Process) addThread(hThread syscall.Handle, threadID int, attach, susp ...@@ -240,7 +240,7 @@ func (dbp *Process) addThread(hThread syscall.Handle, threadID int, attach, susp
os: new(OSSpecificDetails), os: new(OSSpecificDetails),
} }
thread.os.hThread = hThread thread.os.hThread = hThread
dbp.Threads[threadID] = thread dbp.threads[threadID] = thread
if dbp.CurrentThread == nil { if dbp.CurrentThread == nil {
dbp.SwitchThread(thread.ID) dbp.SwitchThread(thread.ID)
} }
...@@ -488,7 +488,7 @@ func (dbp *Process) waitForDebugEvent(flags waitForDebugEventFlags) (threadID, e ...@@ -488,7 +488,7 @@ func (dbp *Process) waitForDebugEvent(flags waitForDebugEventFlags) (threadID, e
} }
break break
case _EXIT_THREAD_DEBUG_EVENT: case _EXIT_THREAD_DEBUG_EVENT:
delete(dbp.Threads, int(debugEvent.ThreadId)) delete(dbp.threads, int(debugEvent.ThreadId))
break break
case _OUTPUT_DEBUG_STRING_EVENT: case _OUTPUT_DEBUG_STRING_EVENT:
//TODO: Handle debug output strings //TODO: Handle debug output strings
...@@ -547,9 +547,9 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) { ...@@ -547,9 +547,9 @@ func (dbp *Process) trapWait(pid int) (*Thread, error) {
} }
if tid == 0 { if tid == 0 {
dbp.postExit() dbp.postExit()
return nil, ProcessExitedError{Pid: dbp.Pid, Status: exitCode} return nil, ProcessExitedError{Pid: dbp.pid, Status: exitCode}
} }
th := dbp.Threads[tid] th := dbp.threads[tid]
return th, nil return th, nil
} }
...@@ -577,7 +577,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error { ...@@ -577,7 +577,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
return err return err
} }
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
thread.running = false thread.running = false
_, err := _SuspendThread(thread.os.hThread) _, err := _SuspendThread(thread.os.hThread)
if err != nil { if err != nil {
...@@ -589,7 +589,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error { ...@@ -589,7 +589,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
var err error var err error
var tid int var tid int
dbp.execPtraceFunc(func() { dbp.execPtraceFunc(func() {
err = _ContinueDebugEvent(uint32(dbp.Pid), uint32(dbp.os.breakThread), _DBG_CONTINUE) err = _ContinueDebugEvent(uint32(dbp.pid), uint32(dbp.os.breakThread), _DBG_CONTINUE)
if err == nil { if err == nil {
tid, _, _ = dbp.waitForDebugEvent(waitSuspendNewThreads) tid, _, _ = dbp.waitForDebugEvent(waitSuspendNewThreads)
} }
...@@ -600,7 +600,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error { ...@@ -600,7 +600,7 @@ func (dbp *Process) setCurrentBreakpoints(trapthread *Thread) error {
if tid == 0 { if tid == 0 {
break break
} }
err = dbp.Threads[tid].SetCurrentBreakpoint() err = dbp.threads[tid].SetCurrentBreakpoint()
if err != nil { if err != nil {
return err return err
} }
...@@ -614,7 +614,7 @@ func (dbp *Process) exitGuard(err error) error { ...@@ -614,7 +614,7 @@ func (dbp *Process) exitGuard(err error) error {
} }
func (dbp *Process) resume() error { func (dbp *Process) resume() error {
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
if thread.CurrentBreakpoint != nil { if thread.CurrentBreakpoint != nil {
if err := thread.StepInstruction(); err != nil { if err := thread.StepInstruction(); err != nil {
return err return err
...@@ -623,7 +623,7 @@ func (dbp *Process) resume() error { ...@@ -623,7 +623,7 @@ func (dbp *Process) resume() error {
} }
} }
for _, thread := range dbp.Threads { for _, thread := range dbp.threads {
thread.running = true thread.running = true
_, err := _ResumeThread(thread.os.hThread) _, err := _ResumeThread(thread.os.hThread)
if err != nil { if err != nil {
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"github.com/derekparker/delve/dwarf/frame" "github.com/derekparker/delve/dwarf/frame"
) )
...@@ -222,7 +223,7 @@ func (dbp *Process) frameInfo(pc, sp uint64, top bool) (Stackframe, error) { ...@@ -222,7 +223,7 @@ func (dbp *Process) frameInfo(pc, sp uint64, top bool) (Stackframe, error) {
if retaddr == 0 { if retaddr == 0 {
return Stackframe{}, NullAddrError{} return Stackframe{}, NullAddrError{}
} }
data, err := dbp.CurrentThread.readMemory(retaddr, dbp.arch.PtrSize()) data, err := dbp.currentThread.readMemory(retaddr, dbp.arch.PtrSize())
if err != nil { if err != nil {
return Stackframe{}, err return Stackframe{}, err
} }
......
...@@ -154,7 +154,7 @@ func topframe(g *G, thread *Thread) (Stackframe, error) { ...@@ -154,7 +154,7 @@ func topframe(g *G, thread *Thread) (Stackframe, error) {
// Continue will take care of setting a breakpoint to the destination // Continue will take care of setting a breakpoint to the destination
// once the CALL is reached. // once the CALL is reached.
func (dbp *Process) next(stepInto bool) error { func (dbp *Process) next(stepInto bool) error {
topframe, err := topframe(dbp.SelectedGoroutine, dbp.CurrentThread) topframe, err := topframe(dbp.selectedGoroutine, dbp.currentThread)
if err != nil { if err != nil {
return err return err
} }
...@@ -167,10 +167,10 @@ func (dbp *Process) next(stepInto bool) error { ...@@ -167,10 +167,10 @@ func (dbp *Process) next(stepInto bool) error {
}() }()
csource := filepath.Ext(topframe.Current.File) != ".go" csource := filepath.Ext(topframe.Current.File) != ".go"
thread := dbp.CurrentThread thread := dbp.currentThread
currentGoroutine := false currentGoroutine := false
if dbp.SelectedGoroutine != nil && dbp.SelectedGoroutine.thread != nil { if dbp.selectedGoroutine != nil && dbp.selectedGoroutine.thread != nil {
thread = dbp.SelectedGoroutine.thread thread = dbp.selectedGoroutine.thread
currentGoroutine = true currentGoroutine = true
} }
...@@ -179,7 +179,7 @@ func (dbp *Process) next(stepInto bool) error { ...@@ -179,7 +179,7 @@ func (dbp *Process) next(stepInto bool) error {
return err return err
} }
cond := sameGoroutineCondition(dbp.SelectedGoroutine) cond := sameGoroutineCondition(dbp.selectedGoroutine)
if stepInto { if stepInto {
for _, instr := range text { for _, instr := range text {
...@@ -215,8 +215,8 @@ func (dbp *Process) next(stepInto bool) error { ...@@ -215,8 +215,8 @@ func (dbp *Process) next(stepInto bool) error {
// Set breakpoint on the most recently deferred function (if any) // Set breakpoint on the most recently deferred function (if any)
var deferpc uint64 = 0 var deferpc uint64 = 0
if dbp.SelectedGoroutine != nil { if dbp.selectedGoroutine != nil {
deferPCEntry := dbp.SelectedGoroutine.DeferPC() deferPCEntry := dbp.selectedGoroutine.DeferPC()
if deferPCEntry != 0 { if deferPCEntry != 0 {
_, _, deferfn := dbp.goSymTable.PCToLine(deferPCEntry) _, _, deferfn := dbp.goSymTable.PCToLine(deferPCEntry)
var err error var err error
...@@ -256,7 +256,7 @@ func (dbp *Process) next(stepInto bool) error { ...@@ -256,7 +256,7 @@ func (dbp *Process) next(stepInto bool) error {
if !covered { if !covered {
fn := dbp.goSymTable.PCToFunc(topframe.Ret) fn := dbp.goSymTable.PCToFunc(topframe.Ret)
if dbp.SelectedGoroutine != nil && fn != nil && fn.Name == "runtime.goexit" { if dbp.selectedGoroutine != nil && fn != nil && fn.Name == "runtime.goexit" {
return nil return nil
} }
} }
...@@ -342,7 +342,7 @@ func (thread *Thread) getGVariable() (*Variable, error) { ...@@ -342,7 +342,7 @@ func (thread *Thread) getGVariable() (*Variable, error) {
if thread.dbp.arch.GStructOffset() == 0 { if thread.dbp.arch.GStructOffset() == 0 {
// GetG was called through SwitchThread / updateThreadList during initialization // GetG was called through SwitchThread / updateThreadList during initialization
// thread.dbp.arch isn't setup yet (it needs a CurrentThread to read global variables from) // thread.dbp.arch isn't setup yet (it needs a current thread to read global variables from)
return nil, fmt.Errorf("g struct offset not initialized") return nil, fmt.Errorf("g struct offset not initialized")
} }
...@@ -490,9 +490,9 @@ func (thread *Thread) onRuntimeBreakpoint() bool { ...@@ -490,9 +490,9 @@ func (thread *Thread) onRuntimeBreakpoint() bool {
// onNextGorutine returns true if this thread is on the goroutine requested by the current 'next' command // onNextGorutine returns true if this thread is on the goroutine requested by the current 'next' command
func (thread *Thread) onNextGoroutine() (bool, error) { func (thread *Thread) onNextGoroutine() (bool, error) {
var bp *Breakpoint var bp *Breakpoint
for i := range thread.dbp.Breakpoints { for i := range thread.dbp.breakpoints {
if thread.dbp.Breakpoints[i].Internal() { if thread.dbp.breakpoints[i].Internal() {
bp = thread.dbp.Breakpoints[i] bp = thread.dbp.breakpoints[i]
break break
} }
} }
......
...@@ -15,7 +15,7 @@ type OSSpecificDetails struct { ...@@ -15,7 +15,7 @@ type OSSpecificDetails struct {
} }
func (t *Thread) halt() (err error) { func (t *Thread) halt() (err error) {
err = sys.Tgkill(t.dbp.Pid, t.ID, sys.SIGSTOP) err = sys.Tgkill(t.dbp.pid, t.ID, sys.SIGSTOP)
if err != nil { if err != nil {
err = fmt.Errorf("halt err %s on thread %d", err, t.ID) err = fmt.Errorf("halt err %s on thread %d", err, t.ID)
return return
...@@ -53,13 +53,13 @@ func (t *Thread) singleStep() (err error) { ...@@ -53,13 +53,13 @@ func (t *Thread) singleStep() (err error) {
if err != nil { if err != nil {
return err return err
} }
if (status == nil || status.Exited()) && wpid == t.dbp.Pid { if (status == nil || status.Exited()) && wpid == t.dbp.pid {
t.dbp.postExit() t.dbp.postExit()
rs := 0 rs := 0
if status != nil { if status != nil {
rs = status.ExitStatus() rs = status.ExitStatus()
} }
return ProcessExitedError{Pid: t.dbp.Pid, Status: rs} return ProcessExitedError{Pid: t.dbp.pid, Status: rs}
} }
if wpid == t.ID && status.StopSignal() == sys.SIGTRAP { if wpid == t.ID && status.StopSignal() == sys.SIGTRAP {
return nil return nil
......
...@@ -57,7 +57,7 @@ func (t *Thread) singleStep() error { ...@@ -57,7 +57,7 @@ func (t *Thread) singleStep() error {
} }
if tid == 0 { if tid == 0 {
t.dbp.postExit() t.dbp.postExit()
return ProcessExitedError{Pid: t.dbp.Pid, Status: exitCode} return ProcessExitedError{Pid: t.dbp.pid, Status: exitCode}
} }
if t.dbp.os.breakThread == t.ID { if t.dbp.os.breakThread == t.ID {
...@@ -65,7 +65,7 @@ func (t *Thread) singleStep() error { ...@@ -65,7 +65,7 @@ func (t *Thread) singleStep() error {
} }
t.dbp.execPtraceFunc(func() { t.dbp.execPtraceFunc(func() {
err = _ContinueDebugEvent(uint32(t.dbp.Pid), uint32(t.dbp.os.breakThread), _DBG_CONTINUE) err = _ContinueDebugEvent(uint32(t.dbp.pid), uint32(t.dbp.os.breakThread), _DBG_CONTINUE)
}) })
} }
...@@ -75,7 +75,7 @@ func (t *Thread) singleStep() error { ...@@ -75,7 +75,7 @@ func (t *Thread) singleStep() error {
} }
t.dbp.execPtraceFunc(func() { t.dbp.execPtraceFunc(func() {
err = _ContinueDebugEvent(uint32(t.dbp.Pid), uint32(t.ID), _DBG_CONTINUE) err = _ContinueDebugEvent(uint32(t.dbp.pid), uint32(t.ID), _DBG_CONTINUE)
}) })
if err != nil { if err != nil {
return err return err
...@@ -98,7 +98,7 @@ func (t *Thread) resume() error { ...@@ -98,7 +98,7 @@ func (t *Thread) resume() error {
t.dbp.execPtraceFunc(func() { t.dbp.execPtraceFunc(func() {
//TODO: Note that we are ignoring the thread we were asked to continue and are continuing the //TODO: Note that we are ignoring the thread we were asked to continue and are continuing the
//thread that we last broke on. //thread that we last broke on.
err = _ContinueDebugEvent(uint32(t.dbp.Pid), uint32(t.ID), _DBG_CONTINUE) err = _ContinueDebugEvent(uint32(t.dbp.pid), uint32(t.ID), _DBG_CONTINUE)
}) })
return err return err
} }
......
...@@ -649,7 +649,7 @@ func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) { ...@@ -649,7 +649,7 @@ func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) {
// EvalPackageVariable will evaluate the package level variable // EvalPackageVariable will evaluate the package level variable
// specified by 'name'. // specified by 'name'.
func (dbp *Process) EvalPackageVariable(name string, cfg LoadConfig) (*Variable, error) { func (dbp *Process) EvalPackageVariable(name string, cfg LoadConfig) (*Variable, error) {
scope := &EvalScope{Thread: dbp.CurrentThread, PC: 0, CFA: 0} scope := &EvalScope{Thread: dbp.currentThread, PC: 0, CFA: 0}
v, err := scope.packageVarAddr(name) v, err := scope.packageVarAddr(name)
if err != nil { if err != nil {
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/derekparker/delve/pkg/target"
"github.com/derekparker/delve/proc" "github.com/derekparker/delve/proc"
"github.com/derekparker/delve/service/api" "github.com/derekparker/delve/service/api"
) )
...@@ -26,9 +27,10 @@ import ( ...@@ -26,9 +27,10 @@ import (
// functionality needed by clients, but not needed in // functionality needed by clients, but not needed in
// lower lever packages such as proc. // lower lever packages such as proc.
type Debugger struct { type Debugger struct {
config *Config config *Config
// TODO(DO NOT MERGE WITHOUT) rename to targetMutex
processMutex sync.Mutex processMutex sync.Mutex
process *proc.Process target target.Interface
} }
// Config provides the configuration to start a Debugger. // Config provides the configuration to start a Debugger.
...@@ -61,7 +63,7 @@ func New(config *Config) (*Debugger, error) { ...@@ -61,7 +63,7 @@ func New(config *Config) (*Debugger, error) {
if err != nil { if err != nil {
return nil, attachErrorMessage(d.config.AttachPid, err) return nil, attachErrorMessage(d.config.AttachPid, err)
} }
d.process = p d.target = p
} else { } else {
log.Printf("launching process with args: %v", d.config.ProcessArgs) log.Printf("launching process with args: %v", d.config.ProcessArgs)
p, err := proc.Launch(d.config.ProcessArgs, d.config.WorkingDir) p, err := proc.Launch(d.config.ProcessArgs, d.config.WorkingDir)
...@@ -71,7 +73,7 @@ func New(config *Config) (*Debugger, error) { ...@@ -71,7 +73,7 @@ func New(config *Config) (*Debugger, error) {
} }
return nil, err return nil, err
} }
d.process = p d.target = p
} }
return d, nil return d, nil
} }
...@@ -79,13 +81,13 @@ func New(config *Config) (*Debugger, error) { ...@@ -79,13 +81,13 @@ func New(config *Config) (*Debugger, error) {
// ProcessPid returns the PID of the process // ProcessPid returns the PID of the process
// the debugger is debugging. // the debugger is debugging.
func (d *Debugger) ProcessPid() int { func (d *Debugger) ProcessPid() int {
return d.process.Pid return d.target.Pid()
} }
// LastModified returns the time that the process' executable was last // LastModified returns the time that the process' executable was last
// modified. // modified.
func (d *Debugger) LastModified() time.Time { func (d *Debugger) LastModified() time.Time {
return d.process.LastModified return d.target.LastModified()
} }
// Detach detaches from the target process. // Detach detaches from the target process.
...@@ -100,9 +102,9 @@ func (d *Debugger) Detach(kill bool) error { ...@@ -100,9 +102,9 @@ func (d *Debugger) Detach(kill bool) error {
func (d *Debugger) detach(kill bool) error { func (d *Debugger) detach(kill bool) error {
if d.config.AttachPid != 0 { if d.config.AttachPid != 0 {
return d.process.Detach(kill) return d.target.Detach(kill)
} }
return d.process.Kill() return d.target.Kill()
} }
// Restart will restart the target process, first killing // Restart will restart the target process, first killing
...@@ -111,9 +113,9 @@ func (d *Debugger) Restart() ([]api.DiscardedBreakpoint, error) { ...@@ -111,9 +113,9 @@ func (d *Debugger) Restart() ([]api.DiscardedBreakpoint, error) {
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
if !d.process.Exited() { if !d.target.Exited() {
if d.process.Running() { if d.target.Running() {
d.process.Halt() d.target.Halt()
} }
// Ensure the process is in a PTRACE_STOP. // Ensure the process is in a PTRACE_STOP.
if err := stopProcess(d.ProcessPid()); err != nil { if err := stopProcess(d.ProcessPid()); err != nil {
...@@ -147,7 +149,7 @@ func (d *Debugger) Restart() ([]api.DiscardedBreakpoint, error) { ...@@ -147,7 +149,7 @@ func (d *Debugger) Restart() ([]api.DiscardedBreakpoint, error) {
return nil, err return nil, err
} }
} }
d.process = p d.target = p
return discarded, nil return discarded, nil
} }
...@@ -159,7 +161,7 @@ func (d *Debugger) State() (*api.DebuggerState, error) { ...@@ -159,7 +161,7 @@ func (d *Debugger) State() (*api.DebuggerState, error) {
} }
func (d *Debugger) state() (*api.DebuggerState, error) { func (d *Debugger) state() (*api.DebuggerState, error) {
if d.process.Exited() { if d.target.Exited() {
return nil, proc.ProcessExitedError{Pid: d.ProcessPid()} return nil, proc.ProcessExitedError{Pid: d.ProcessPid()}
} }
...@@ -168,24 +170,24 @@ func (d *Debugger) state() (*api.DebuggerState, error) { ...@@ -168,24 +170,24 @@ func (d *Debugger) state() (*api.DebuggerState, error) {
goroutine *api.Goroutine goroutine *api.Goroutine
) )
if d.process.SelectedGoroutine != nil { if d.target.SelectedGoroutine() != nil {
goroutine = api.ConvertGoroutine(d.process.SelectedGoroutine) goroutine = api.ConvertGoroutine(d.target.SelectedGoroutine())
} }
state = &api.DebuggerState{ state = &api.DebuggerState{
SelectedGoroutine: goroutine, SelectedGoroutine: goroutine,
Exited: d.process.Exited(), Exited: d.target.Exited(),
} }
for i := range d.process.Threads { for i := range d.target.Threads() {
th := api.ConvertThread(d.process.Threads[i]) th := api.ConvertThread(d.target.Threads()[i])
state.Threads = append(state.Threads, th) state.Threads = append(state.Threads, th)
if i == d.process.CurrentThread.ID { if i == d.target.CurrentThread().ID {
state.CurrentThread = th state.CurrentThread = th
} }
} }
for _, bp := range d.process.Breakpoints { for _, bp := range d.target.Breakpoints() {
if bp.Internal() { if bp.Internal() {
state.NextInProgress = true state.NextInProgress = true
break break
...@@ -221,19 +223,19 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin ...@@ -221,19 +223,19 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// Accept fileName which is case-insensitive and slash-insensitive match // Accept fileName which is case-insensitive and slash-insensitive match
fileNameNormalized := strings.ToLower(filepath.ToSlash(fileName)) fileNameNormalized := strings.ToLower(filepath.ToSlash(fileName))
for symFile := range d.process.Sources() { for symFile := range d.target.Sources() {
if fileNameNormalized == strings.ToLower(filepath.ToSlash(symFile)) { if fileNameNormalized == strings.ToLower(filepath.ToSlash(symFile)) {
fileName = symFile fileName = symFile
break break
} }
} }
} }
addr, err = d.process.FindFileLocation(fileName, requestedBp.Line) addr, err = d.target.FindFileLocation(fileName, requestedBp.Line)
case len(requestedBp.FunctionName) > 0: case len(requestedBp.FunctionName) > 0:
if requestedBp.Line >= 0 { if requestedBp.Line >= 0 {
addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, false, requestedBp.Line) addr, err = d.target.FindFunctionLocation(requestedBp.FunctionName, false, requestedBp.Line)
} else { } else {
addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, true, 0) addr, err = d.target.FindFunctionLocation(requestedBp.FunctionName, true, 0)
} }
default: default:
addr = requestedBp.Addr addr = requestedBp.Addr
...@@ -243,12 +245,12 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin ...@@ -243,12 +245,12 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
return nil, err return nil, err
} }
bp, err := d.process.SetBreakpoint(addr, proc.UserBreakpoint, nil) bp, err := d.target.SetBreakpoint(addr, proc.UserBreakpoint, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := copyBreakpointInfo(bp, requestedBp); err != nil { if err := copyBreakpointInfo(bp, requestedBp); err != nil {
if _, err1 := d.process.ClearBreakpoint(bp.Addr); err1 != nil { if _, err1 := d.target.ClearBreakpoint(bp.Addr); err1 != nil {
err = fmt.Errorf("error while creating breakpoint: %v, additionally the breakpoint could not be properly rolled back: %v", err, err1) err = fmt.Errorf("error while creating breakpoint: %v, additionally the breakpoint could not be properly rolled back: %v", err, err1)
} }
return nil, err return nil, err
...@@ -273,7 +275,7 @@ func (d *Debugger) AmendBreakpoint(amend *api.Breakpoint) error { ...@@ -273,7 +275,7 @@ func (d *Debugger) AmendBreakpoint(amend *api.Breakpoint) error {
} }
func (d *Debugger) CancelNext() error { func (d *Debugger) CancelNext() error {
return d.process.ClearInternalBreakpoints() return d.target.ClearInternalBreakpoints()
} }
func copyBreakpointInfo(bp *proc.Breakpoint, requested *api.Breakpoint) (err error) { func copyBreakpointInfo(bp *proc.Breakpoint, requested *api.Breakpoint) (err error) {
...@@ -297,7 +299,7 @@ func (d *Debugger) ClearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint ...@@ -297,7 +299,7 @@ func (d *Debugger) ClearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
var clearedBp *api.Breakpoint var clearedBp *api.Breakpoint
bp, err := d.process.ClearBreakpoint(requestedBp.Addr) bp, err := d.target.ClearBreakpoint(requestedBp.Addr)
if err != nil { if err != nil {
return nil, fmt.Errorf("Can't clear breakpoint @%x: %s", requestedBp.Addr, err) return nil, fmt.Errorf("Can't clear breakpoint @%x: %s", requestedBp.Addr, err)
} }
...@@ -315,7 +317,7 @@ func (d *Debugger) Breakpoints() []*api.Breakpoint { ...@@ -315,7 +317,7 @@ func (d *Debugger) Breakpoints() []*api.Breakpoint {
func (d *Debugger) breakpoints() []*api.Breakpoint { func (d *Debugger) breakpoints() []*api.Breakpoint {
bps := []*api.Breakpoint{} bps := []*api.Breakpoint{}
for _, bp := range d.process.Breakpoints { for _, bp := range d.target.Breakpoints() {
if bp.Internal() { if bp.Internal() {
continue continue
} }
...@@ -337,7 +339,7 @@ func (d *Debugger) FindBreakpoint(id int) *api.Breakpoint { ...@@ -337,7 +339,7 @@ func (d *Debugger) FindBreakpoint(id int) *api.Breakpoint {
} }
func (d *Debugger) findBreakpoint(id int) *proc.Breakpoint { func (d *Debugger) findBreakpoint(id int) *proc.Breakpoint {
for _, bp := range d.process.Breakpoints { for _, bp := range d.target.Breakpoints() {
if bp.ID == id { if bp.ID == id {
return bp return bp
} }
...@@ -366,11 +368,11 @@ func (d *Debugger) Threads() ([]*api.Thread, error) { ...@@ -366,11 +368,11 @@ func (d *Debugger) Threads() ([]*api.Thread, error) {
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
if d.process.Exited() { if d.target.Exited() {
return nil, &proc.ProcessExitedError{} return nil, &proc.ProcessExitedError{}
} }
threads := []*api.Thread{} threads := []*api.Thread{}
for _, th := range d.process.Threads { for _, th := range d.target.Threads() {
threads = append(threads, api.ConvertThread(th)) threads = append(threads, api.ConvertThread(th))
} }
return threads, nil return threads, nil
...@@ -381,11 +383,11 @@ func (d *Debugger) FindThread(id int) (*api.Thread, error) { ...@@ -381,11 +383,11 @@ func (d *Debugger) FindThread(id int) (*api.Thread, error) {
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
if d.process.Exited() { if d.target.Exited() {
return nil, &proc.ProcessExitedError{} return nil, &proc.ProcessExitedError{}
} }
for _, th := range d.process.Threads { for _, th := range d.target.Threads() {
if th.ID == id { if th.ID == id {
return api.ConvertThread(th), nil return api.ConvertThread(th), nil
} }
...@@ -401,7 +403,7 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er ...@@ -401,7 +403,7 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
// RequestManualStop does not invoke any ptrace syscalls, so it's safe to // RequestManualStop does not invoke any ptrace syscalls, so it's safe to
// access the process directly. // access the process directly.
log.Print("halting") log.Print("halting")
err = d.process.RequestManualStop() err = d.target.RequestManualStop()
} }
d.processMutex.Lock() d.processMutex.Lock()
...@@ -410,7 +412,7 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er ...@@ -410,7 +412,7 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
switch command.Name { switch command.Name {
case api.Continue: case api.Continue:
log.Print("continuing") log.Print("continuing")
err = d.process.Continue() err = d.target.Continue()
if err != nil { if err != nil {
if exitedErr, exited := err.(proc.ProcessExitedError); exited { if exitedErr, exited := err.(proc.ProcessExitedError); exited {
state := &api.DebuggerState{} state := &api.DebuggerState{}
...@@ -430,22 +432,22 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er ...@@ -430,22 +432,22 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
case api.Next: case api.Next:
log.Print("nexting") log.Print("nexting")
err = d.process.Next() err = d.target.Next()
case api.Step: case api.Step:
log.Print("stepping") log.Print("stepping")
err = d.process.Step() err = d.target.Step()
case api.StepInstruction: case api.StepInstruction:
log.Print("single stepping") log.Print("single stepping")
err = d.process.StepInstruction() err = d.target.StepInstruction()
case api.StepOut: case api.StepOut:
log.Print("step out") log.Print("step out")
err = d.process.StepOut() err = d.target.StepOut()
case api.SwitchThread: case api.SwitchThread:
log.Printf("switching to thread %d", command.ThreadID) log.Printf("switching to thread %d", command.ThreadID)
err = d.process.SwitchThread(command.ThreadID) err = d.target.SwitchThread(command.ThreadID)
case api.SwitchGoroutine: case api.SwitchGoroutine:
log.Printf("switching to goroutine %d", command.GoroutineID) log.Printf("switching to goroutine %d", command.GoroutineID)
err = d.process.SwitchGoroutine(command.GoroutineID) err = d.target.SwitchGoroutine(command.GoroutineID)
case api.Halt: case api.Halt:
// RequestManualStop already called // RequestManualStop already called
} }
...@@ -470,7 +472,7 @@ func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error ...@@ -470,7 +472,7 @@ func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error
state.Threads[i].BreakpointInfo = bpi state.Threads[i].BreakpointInfo = bpi
if bp.Goroutine { if bp.Goroutine {
g, err := d.process.CurrentThread.GetG() g, err := d.target.CurrentThread().GetG()
if err != nil { if err != nil {
return err return err
} }
...@@ -478,7 +480,7 @@ func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error ...@@ -478,7 +480,7 @@ func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error
} }
if bp.Stacktrace > 0 { if bp.Stacktrace > 0 {
rawlocs, err := d.process.CurrentThread.Stacktrace(bp.Stacktrace) rawlocs, err := d.target.CurrentThread().Stacktrace(bp.Stacktrace)
if err != nil { if err != nil {
return err return err
} }
...@@ -488,7 +490,7 @@ func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error ...@@ -488,7 +490,7 @@ func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error
} }
} }
s, err := d.process.Threads[state.Threads[i].ID].Scope() s, err := d.target.Threads()[state.Threads[i].ID].Scope()
if err != nil { if err != nil {
return err return err
} }
...@@ -529,7 +531,7 @@ func (d *Debugger) Sources(filter string) ([]string, error) { ...@@ -529,7 +531,7 @@ func (d *Debugger) Sources(filter string) ([]string, error) {
} }
files := []string{} files := []string{}
for f := range d.process.Sources() { for f := range d.target.Sources() {
if regex.Match([]byte(f)) { if regex.Match([]byte(f)) {
files = append(files, f) files = append(files, f)
} }
...@@ -542,7 +544,7 @@ func (d *Debugger) Functions(filter string) ([]string, error) { ...@@ -542,7 +544,7 @@ func (d *Debugger) Functions(filter string) ([]string, error) {
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
return regexFilterFuncs(filter, d.process.Funcs()) return regexFilterFuncs(filter, d.target.Funcs())
} }
func (d *Debugger) Types(filter string) ([]string, error) { func (d *Debugger) Types(filter string) ([]string, error) {
...@@ -554,7 +556,7 @@ func (d *Debugger) Types(filter string) ([]string, error) { ...@@ -554,7 +556,7 @@ func (d *Debugger) Types(filter string) ([]string, error) {
return nil, fmt.Errorf("invalid filter argument: %s", err.Error()) return nil, fmt.Errorf("invalid filter argument: %s", err.Error())
} }
types, err := d.process.Types() types, err := d.target.Types()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -596,7 +598,7 @@ func (d *Debugger) PackageVariables(threadID int, filter string, cfg proc.LoadCo ...@@ -596,7 +598,7 @@ func (d *Debugger) PackageVariables(threadID int, filter string, cfg proc.LoadCo
} }
vars := []api.Variable{} vars := []api.Variable{}
thread, found := d.process.Threads[threadID] thread, found := d.target.Threads()[threadID]
if !found { if !found {
return nil, fmt.Errorf("couldn't find thread %d", threadID) return nil, fmt.Errorf("couldn't find thread %d", threadID)
} }
...@@ -621,7 +623,7 @@ func (d *Debugger) Registers(threadID int, floatingPoint bool) (api.Registers, e ...@@ -621,7 +623,7 @@ func (d *Debugger) Registers(threadID int, floatingPoint bool) (api.Registers, e
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
thread, found := d.process.Threads[threadID] thread, found := d.target.Threads()[threadID]
if !found { if !found {
return nil, fmt.Errorf("couldn't find thread %d", threadID) return nil, fmt.Errorf("couldn't find thread %d", threadID)
} }
...@@ -645,7 +647,7 @@ func (d *Debugger) LocalVariables(scope api.EvalScope, cfg proc.LoadConfig) ([]a ...@@ -645,7 +647,7 @@ func (d *Debugger) LocalVariables(scope api.EvalScope, cfg proc.LoadConfig) ([]a
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
s, err := d.process.ConvertEvalScope(scope.GoroutineID, scope.Frame) s, err := d.target.ConvertEvalScope(scope.GoroutineID, scope.Frame)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -661,7 +663,7 @@ func (d *Debugger) FunctionArguments(scope api.EvalScope, cfg proc.LoadConfig) ( ...@@ -661,7 +663,7 @@ func (d *Debugger) FunctionArguments(scope api.EvalScope, cfg proc.LoadConfig) (
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
s, err := d.process.ConvertEvalScope(scope.GoroutineID, scope.Frame) s, err := d.target.ConvertEvalScope(scope.GoroutineID, scope.Frame)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -678,7 +680,7 @@ func (d *Debugger) EvalVariableInScope(scope api.EvalScope, symbol string, cfg p ...@@ -678,7 +680,7 @@ func (d *Debugger) EvalVariableInScope(scope api.EvalScope, symbol string, cfg p
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
s, err := d.process.ConvertEvalScope(scope.GoroutineID, scope.Frame) s, err := d.target.ConvertEvalScope(scope.GoroutineID, scope.Frame)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -695,7 +697,7 @@ func (d *Debugger) SetVariableInScope(scope api.EvalScope, symbol, value string) ...@@ -695,7 +697,7 @@ func (d *Debugger) SetVariableInScope(scope api.EvalScope, symbol, value string)
d.processMutex.Lock() d.processMutex.Lock()
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
s, err := d.process.ConvertEvalScope(scope.GoroutineID, scope.Frame) s, err := d.target.ConvertEvalScope(scope.GoroutineID, scope.Frame)
if err != nil { if err != nil {
return err return err
} }
...@@ -708,7 +710,7 @@ func (d *Debugger) Goroutines() ([]*api.Goroutine, error) { ...@@ -708,7 +710,7 @@ func (d *Debugger) Goroutines() ([]*api.Goroutine, error) {
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
goroutines := []*api.Goroutine{} goroutines := []*api.Goroutine{}
gs, err := d.process.GoroutinesInfo() gs, err := d.target.GoroutinesInfo()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -727,13 +729,13 @@ func (d *Debugger) Stacktrace(goroutineID, depth int, cfg *proc.LoadConfig) ([]a ...@@ -727,13 +729,13 @@ func (d *Debugger) Stacktrace(goroutineID, depth int, cfg *proc.LoadConfig) ([]a
var rawlocs []proc.Stackframe var rawlocs []proc.Stackframe
g, err := d.process.FindGoroutine(goroutineID) g, err := d.target.FindGoroutine(goroutineID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if g == nil { if g == nil {
rawlocs, err = d.process.CurrentThread.Stacktrace(depth) rawlocs, err = d.target.CurrentThread().Stacktrace(depth)
} else { } else {
rawlocs, err = g.Stacktrace(depth) rawlocs, err = g.Stacktrace(depth)
} }
...@@ -750,7 +752,7 @@ func (d *Debugger) convertStacktrace(rawlocs []proc.Stackframe, cfg *proc.LoadCo ...@@ -750,7 +752,7 @@ func (d *Debugger) convertStacktrace(rawlocs []proc.Stackframe, cfg *proc.LoadCo
frame := api.Stackframe{Location: api.ConvertLocation(rawlocs[i].Call)} frame := api.Stackframe{Location: api.ConvertLocation(rawlocs[i].Call)}
if cfg != nil { if cfg != nil {
var err error var err error
scope := rawlocs[i].Scope(d.process.CurrentThread) scope := rawlocs[i].Scope(d.target.CurrentThread())
locals, err := scope.LocalVariables(*cfg) locals, err := scope.LocalVariables(*cfg)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -779,11 +781,11 @@ func (d *Debugger) FindLocation(scope api.EvalScope, locStr string) ([]api.Locat ...@@ -779,11 +781,11 @@ func (d *Debugger) FindLocation(scope api.EvalScope, locStr string) ([]api.Locat
return nil, err return nil, err
} }
s, _ := d.process.ConvertEvalScope(scope.GoroutineID, scope.Frame) s, _ := d.target.ConvertEvalScope(scope.GoroutineID, scope.Frame)
locs, err := loc.Find(d, s, locStr) locs, err := loc.Find(d, s, locStr)
for i := range locs { for i := range locs {
file, line, fn := d.process.PCToLine(locs[i].PC) file, line, fn := d.target.PCToLine(locs[i].PC)
locs[i].File = file locs[i].File = file
locs[i].Line = line locs[i].Line = line
locs[i].Function = api.ConvertFunction(fn) locs[i].Function = api.ConvertFunction(fn)
...@@ -798,7 +800,7 @@ func (d *Debugger) Disassemble(scope api.EvalScope, startPC, endPC uint64, flavo ...@@ -798,7 +800,7 @@ func (d *Debugger) Disassemble(scope api.EvalScope, startPC, endPC uint64, flavo
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
if endPC == 0 { if endPC == 0 {
_, _, fn := d.process.PCToLine(startPC) _, _, fn := d.target.PCToLine(startPC)
if fn == nil { if fn == nil {
return nil, fmt.Errorf("Address 0x%x does not belong to any function", startPC) return nil, fmt.Errorf("Address 0x%x does not belong to any function", startPC)
} }
...@@ -807,9 +809,9 @@ func (d *Debugger) Disassemble(scope api.EvalScope, startPC, endPC uint64, flavo ...@@ -807,9 +809,9 @@ func (d *Debugger) Disassemble(scope api.EvalScope, startPC, endPC uint64, flavo
} }
currentGoroutine := true currentGoroutine := true
thread := d.process.CurrentThread thread := d.target.CurrentThread()
if s, err := d.process.ConvertEvalScope(scope.GoroutineID, scope.Frame); err == nil { if s, err := d.target.ConvertEvalScope(scope.GoroutineID, scope.Frame); err == nil {
thread = s.Thread thread = s.Thread
if scope.GoroutineID != -1 { if scope.GoroutineID != -1 {
g, _ := s.Thread.GetG() g, _ := s.Thread.GetG()
......
...@@ -243,14 +243,14 @@ func (spec *FuncLocationSpec) Match(sym *gosym.Sym) bool { ...@@ -243,14 +243,14 @@ func (spec *FuncLocationSpec) Match(sym *gosym.Sym) bool {
} }
func (loc *RegexLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) { func (loc *RegexLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
funcs := d.process.Funcs() funcs := d.target.Funcs()
matches, err := regexFilterFuncs(loc.FuncRegex, funcs) matches, err := regexFilterFuncs(loc.FuncRegex, funcs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
r := make([]api.Location, 0, len(matches)) r := make([]api.Location, 0, len(matches))
for i := range matches { for i := range matches {
addr, err := d.process.FindFunctionLocation(matches[i], true, 0) addr, err := d.target.FindFunctionLocation(matches[i], true, 0)
if err == nil { if err == nil {
r = append(r, api.Location{PC: addr}) r = append(r, api.Location{PC: addr})
} }
...@@ -278,8 +278,8 @@ func (loc *AddrLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr str ...@@ -278,8 +278,8 @@ func (loc *AddrLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr str
addr, _ := constant.Uint64Val(v.Value) addr, _ := constant.Uint64Val(v.Value)
return []api.Location{{PC: addr}}, nil return []api.Location{{PC: addr}}, nil
case reflect.Func: case reflect.Func:
_, _, fn := d.process.PCToLine(uint64(v.Base)) _, _, fn := d.target.PCToLine(uint64(v.Base))
pc, err := d.process.FirstPCAfterPrologue(fn, false) pc, err := d.target.FirstPCAfterPrologue(fn, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -327,8 +327,8 @@ func (ale AmbiguousLocationError) Error() string { ...@@ -327,8 +327,8 @@ func (ale AmbiguousLocationError) Error() string {
} }
func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) { func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
funcs := d.process.Funcs() funcs := d.target.Funcs()
files := d.process.Sources() files := d.target.Sources()
candidates := []string{} candidates := []string{}
for file := range files { for file := range files {
...@@ -366,12 +366,12 @@ func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s ...@@ -366,12 +366,12 @@ func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s
if loc.LineOffset < 0 { if loc.LineOffset < 0 {
return nil, fmt.Errorf("Malformed breakpoint location, no line offset specified") return nil, fmt.Errorf("Malformed breakpoint location, no line offset specified")
} }
addr, err = d.process.FindFileLocation(candidates[0], loc.LineOffset) addr, err = d.target.FindFileLocation(candidates[0], loc.LineOffset)
} else { } else {
if loc.LineOffset < 0 { if loc.LineOffset < 0 {
addr, err = d.process.FindFunctionLocation(candidates[0], true, 0) addr, err = d.target.FindFunctionLocation(candidates[0], true, 0)
} else { } else {
addr, err = d.process.FindFunctionLocation(candidates[0], false, loc.LineOffset) addr, err = d.target.FindFunctionLocation(candidates[0], false, loc.LineOffset)
} }
} }
if err != nil { if err != nil {
...@@ -390,11 +390,11 @@ func (loc *OffsetLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s ...@@ -390,11 +390,11 @@ func (loc *OffsetLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s
if scope == nil { if scope == nil {
return nil, fmt.Errorf("could not determine current location (scope is nil)") return nil, fmt.Errorf("could not determine current location (scope is nil)")
} }
file, line, fn := d.process.PCToLine(scope.PC) file, line, fn := d.target.PCToLine(scope.PC)
if fn == nil { if fn == nil {
return nil, fmt.Errorf("could not determine current location") return nil, fmt.Errorf("could not determine current location")
} }
addr, err := d.process.FindFileLocation(file, line+loc.Offset) addr, err := d.target.FindFileLocation(file, line+loc.Offset)
return []api.Location{{PC: addr}}, err return []api.Location{{PC: addr}}, err
} }
...@@ -402,10 +402,10 @@ func (loc *LineLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr str ...@@ -402,10 +402,10 @@ func (loc *LineLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr str
if scope == nil { if scope == nil {
return nil, fmt.Errorf("could not determine current location (scope is nil)") return nil, fmt.Errorf("could not determine current location (scope is nil)")
} }
file, _, fn := d.process.PCToLine(scope.PC) file, _, fn := d.target.PCToLine(scope.PC)
if fn == nil { if fn == nil {
return nil, fmt.Errorf("could not determine current location") return nil, fmt.Errorf("could not determine current location")
} }
addr, err := d.process.FindFileLocation(file, loc.Line) addr, err := d.target.FindFileLocation(file, loc.Line)
return []api.Location{{PC: addr}}, err return []api.Location{{PC: addr}}, err
} }
...@@ -54,7 +54,7 @@ func assertVariable(t *testing.T, variable *proc.Variable, expected varTest) { ...@@ -54,7 +54,7 @@ func assertVariable(t *testing.T, variable *proc.Variable, expected varTest) {
} }
func evalVariable(p *proc.Process, symbol string, cfg proc.LoadConfig) (*proc.Variable, error) { func evalVariable(p *proc.Process, symbol string, cfg proc.LoadConfig) (*proc.Variable, error) {
scope, err := p.CurrentThread.Scope() scope, err := p.CurrentThread().Scope()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -68,7 +68,7 @@ func (tc *varTest) alternateVarTest() varTest { ...@@ -68,7 +68,7 @@ func (tc *varTest) alternateVarTest() varTest {
} }
func setVariable(p *proc.Process, symbol, value string) error { func setVariable(p *proc.Process, symbol, value string) error {
scope, err := p.CurrentThread.Scope() scope, err := p.CurrentThread().Scope()
if err != nil { if err != nil {
return err return err
} }
...@@ -348,7 +348,7 @@ func TestLocalVariables(t *testing.T) { ...@@ -348,7 +348,7 @@ func TestLocalVariables(t *testing.T) {
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
for _, tc := range testcases { for _, tc := range testcases {
scope, err := p.CurrentThread.Scope() scope, err := p.CurrentThread().Scope()
assertNoError(err, t, "AsScope()") assertNoError(err, t, "AsScope()")
vars, err := tc.fn(scope, pnormalLoadConfig) vars, err := tc.fn(scope, pnormalLoadConfig)
assertNoError(err, t, "LocalVariables() returned an error") assertNoError(err, t, "LocalVariables() returned an error")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册