mirror of
https://github.com/beego/bee.git
synced 2025-02-19 14:27:12 +00:00
Use Delve v0.12.1 instead of master
This commit is contained in:
parent
abf3c41032
commit
4dd6983d3c
@ -7,7 +7,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/util"
|
||||
"github.com/derekparker/delve/dwarf/util"
|
||||
)
|
||||
|
||||
type parsefunc func(*parseContext) parsefunc
|
@ -5,7 +5,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/util"
|
||||
"github.com/derekparker/delve/dwarf/util"
|
||||
)
|
||||
|
||||
type CurrentFrameAddress struct {
|
@ -4,7 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/util"
|
||||
"github.com/derekparker/delve/dwarf/util"
|
||||
)
|
||||
|
||||
type DebugLinePrologue struct {
|
@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/util"
|
||||
"github.com/derekparker/delve/dwarf/util"
|
||||
)
|
||||
|
||||
type Location struct {
|
||||
@ -27,11 +27,6 @@ type StateMachine struct {
|
||||
endSeq bool
|
||||
lastWasStandard bool
|
||||
lastDelta int
|
||||
// valid is true if the current value of the state machine is the address of
|
||||
// an instruction (using the terminology used by DWARF spec the current
|
||||
// value of the state machine should be appended to the matrix representing
|
||||
// the compilation unit)
|
||||
valid bool
|
||||
}
|
||||
|
||||
type opcodefn func(*StateMachine, *bytes.Buffer)
|
||||
@ -96,9 +91,7 @@ func (dbl *DebugLines) AllPCsForFileLine(f string, l int) (pcs []uint64) {
|
||||
}
|
||||
if sm.line == l && sm.file == f && sm.address != lastAddr {
|
||||
foundFile = true
|
||||
if sm.valid {
|
||||
pcs = append(pcs, sm.address)
|
||||
}
|
||||
pcs = append(pcs, sm.address)
|
||||
line := sm.line
|
||||
// Keep going until we're on a different line. We only care about
|
||||
// when a line comes back around (i.e. for loop) so get to next line,
|
||||
@ -130,9 +123,6 @@ func (dbl *DebugLines) AllPCsBetween(begin, end uint64, filename string) ([]uint
|
||||
|
||||
for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
|
||||
findAndExecOpcode(sm, buf, b)
|
||||
if !sm.valid {
|
||||
continue
|
||||
}
|
||||
if sm.address > end {
|
||||
break
|
||||
}
|
||||
@ -167,10 +157,9 @@ func execSpecialOpcode(sm *StateMachine, instr byte) {
|
||||
|
||||
sm.lastDelta = int(sm.dbl.Prologue.LineBase + int8(decoded%sm.dbl.Prologue.LineRange))
|
||||
sm.line += sm.lastDelta
|
||||
sm.address += uint64(decoded/sm.dbl.Prologue.LineRange) * uint64(sm.dbl.Prologue.MinInstrLength)
|
||||
sm.address += uint64(decoded / sm.dbl.Prologue.LineRange)
|
||||
sm.basicBlock = false
|
||||
sm.lastWasStandard = false
|
||||
sm.valid = true
|
||||
}
|
||||
|
||||
func execExtendedOpcode(sm *StateMachine, instr byte, buf *bytes.Buffer) {
|
||||
@ -181,7 +170,6 @@ func execExtendedOpcode(sm *StateMachine, instr byte, buf *bytes.Buffer) {
|
||||
panic(fmt.Sprintf("Encountered unknown extended opcode %#v\n", b))
|
||||
}
|
||||
sm.lastWasStandard = false
|
||||
sm.valid = false
|
||||
|
||||
fn(sm, buf)
|
||||
}
|
||||
@ -192,14 +180,12 @@ func execStandardOpcode(sm *StateMachine, instr byte, buf *bytes.Buffer) {
|
||||
panic(fmt.Sprintf("Encountered unknown standard opcode %#v\n", instr))
|
||||
}
|
||||
sm.lastWasStandard = true
|
||||
sm.valid = false
|
||||
|
||||
fn(sm, buf)
|
||||
}
|
||||
|
||||
func copyfn(sm *StateMachine, buf *bytes.Buffer) {
|
||||
sm.basicBlock = false
|
||||
sm.valid = true
|
||||
}
|
||||
|
||||
func advancepc(sm *StateMachine, buf *bytes.Buffer) {
|
||||
@ -232,7 +218,7 @@ func setbasicblock(sm *StateMachine, buf *bytes.Buffer) {
|
||||
}
|
||||
|
||||
func constaddpc(sm *StateMachine, buf *bytes.Buffer) {
|
||||
sm.address += uint64((255-sm.dbl.Prologue.OpcodeBase)/sm.dbl.Prologue.LineRange) * uint64(sm.dbl.Prologue.MinInstrLength)
|
||||
sm.address += (255 / uint64(sm.dbl.Prologue.LineRange))
|
||||
}
|
||||
|
||||
func fixedadvancepc(sm *StateMachine, buf *bytes.Buffer) {
|
||||
@ -244,7 +230,6 @@ func fixedadvancepc(sm *StateMachine, buf *bytes.Buffer) {
|
||||
|
||||
func endsequence(sm *StateMachine, buf *bytes.Buffer) {
|
||||
sm.endSeq = true
|
||||
sm.valid = true
|
||||
}
|
||||
|
||||
func setaddress(sm *StateMachine, buf *bytes.Buffer) {
|
@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/util"
|
||||
"github.com/derekparker/delve/dwarf/util"
|
||||
)
|
||||
|
||||
const (
|
@ -4,8 +4,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/op"
|
||||
"golang.org/x/debug/dwarf"
|
||||
"github.com/derekparker/delve/dwarf/op"
|
||||
)
|
||||
|
||||
type Reader struct {
|
84
vendor/github.com/derekparker/delve/pkg/target/target.go
generated
vendored
84
vendor/github.com/derekparker/delve/pkg/target/target.go
generated
vendored
@ -1,84 +0,0 @@
|
||||
package target
|
||||
|
||||
import (
|
||||
"debug/gosym"
|
||||
"go/ast"
|
||||
"time"
|
||||
|
||||
"github.com/derekparker/delve/pkg/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)
|
||||
}
|
||||
|
||||
for len(mem) > 0 {
|
||||
bp, atbp := thread.dbp.breakpoints[pc]
|
||||
bp, atbp := thread.dbp.Breakpoints[pc]
|
||||
if atbp {
|
||||
for i := range bp.OriginalData {
|
||||
mem[i] = bp.OriginalData[i]
|
@ -3,7 +3,6 @@ package proc
|
||||
import (
|
||||
"debug/gosym"
|
||||
"encoding/binary"
|
||||
|
||||
"rsc.io/x86/x86asm"
|
||||
)
|
||||
|
||||
@ -146,7 +145,7 @@ func init() {
|
||||
// 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
|
||||
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 {
|
||||
return fn.Entry, err
|
||||
}
|
@ -3,7 +3,6 @@ package proc
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/constant"
|
||||
@ -12,12 +11,10 @@ import (
|
||||
"go/token"
|
||||
"reflect"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/reader"
|
||||
"github.com/derekparker/delve/dwarf/reader"
|
||||
"golang.org/x/debug/dwarf"
|
||||
)
|
||||
|
||||
var OperationOnSpecialFloatError = errors.New("operations on non-finite floats not implemented")
|
||||
|
||||
// EvalExpression returns the value of the given expression.
|
||||
func (scope *EvalScope) EvalExpression(expr string, cfg LoadConfig) (*Variable, error) {
|
||||
t, err := parser.ParseExpr(expr)
|
||||
@ -691,9 +688,6 @@ func (scope *EvalScope) evalUnary(node *ast.UnaryExpr) (*Variable, error) {
|
||||
if xv.Unreadable != nil {
|
||||
return nil, xv.Unreadable
|
||||
}
|
||||
if xv.FloatSpecial != 0 {
|
||||
return nil, OperationOnSpecialFloatError
|
||||
}
|
||||
if xv.Value == nil {
|
||||
return nil, fmt.Errorf("operator %s can not be applied to \"%s\"", node.Op.String(), exprToString(node.X))
|
||||
}
|
||||
@ -800,10 +794,6 @@ func (scope *EvalScope) evalBinary(node *ast.BinaryExpr) (*Variable, error) {
|
||||
return nil, yv.Unreadable
|
||||
}
|
||||
|
||||
if xv.FloatSpecial != 0 || yv.FloatSpecial != 0 {
|
||||
return nil, OperationOnSpecialFloatError
|
||||
}
|
||||
|
||||
typ, err := negotiateType(node.Op, xv, yv)
|
||||
if err != nil {
|
||||
return nil, err
|
@ -16,10 +16,6 @@ type GoVersion struct {
|
||||
RC int
|
||||
}
|
||||
|
||||
var (
|
||||
GoVer18Beta = GoVersion{1, 8, -1, 0, 0}
|
||||
)
|
||||
|
||||
func ParseVersionString(ver string) (GoVersion, bool) {
|
||||
var r GoVersion
|
||||
var err1, err2, err3 error
|
@ -13,7 +13,7 @@ type moduleData struct {
|
||||
|
||||
func (dbp *Process) loadModuleData() (err error) {
|
||||
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
|
||||
md, err = scope.packageVarAddr("runtime.firstmoduledata")
|
||||
if err != nil {
|
||||
@ -84,13 +84,13 @@ func (dbp *Process) resolveTypeOff(typeAddr uintptr, off uintptr) (*Variable, er
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -119,7 +119,7 @@ func (dbp *Process) resolveNameOff(typeAddr uintptr, off uintptr) (name, tag str
|
||||
}
|
||||
|
||||
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")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -130,7 +130,7 @@ func (dbp *Process) reflectOffsMapAccess(off uintptr) (*Variable, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.currentThread))
|
||||
return reflectOffsm.mapAccess(newConstant(constant.MakeUint64(uint64(off)), dbp.CurrentThread))
|
||||
}
|
||||
|
||||
const (
|
||||
@ -142,7 +142,7 @@ const (
|
||||
|
||||
func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32, err error) {
|
||||
off := addr
|
||||
namedata, err := dbp.currentThread.readMemory(off, 3)
|
||||
namedata, err := dbp.CurrentThread.readMemory(off, 3)
|
||||
off += 3
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
@ -150,7 +150,7 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32,
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
@ -159,14 +159,14 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32,
|
||||
name = string(rawstr)
|
||||
|
||||
if namedata[0]&nameflagHasTag != 0 {
|
||||
taglendata, err := dbp.currentThread.readMemory(off, 2)
|
||||
taglendata, err := dbp.CurrentThread.readMemory(off, 2)
|
||||
off += 2
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
@ -176,7 +176,7 @@ func (dbp *Process) loadName(addr uintptr) (name, tag string, pkgpathoff int32,
|
||||
}
|
||||
|
||||
if namedata[0]&nameflagHasPkg != 0 {
|
||||
pkgdata, err := dbp.currentThread.readMemory(off, 4)
|
||||
pkgdata, err := dbp.CurrentThread.readMemory(off, 4)
|
||||
if err != nil {
|
||||
return "", "", 0, err
|
||||
}
|
@ -16,32 +16,32 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/frame"
|
||||
"github.com/derekparker/delve/pkg/dwarf/line"
|
||||
"github.com/derekparker/delve/pkg/dwarf/reader"
|
||||
"github.com/derekparker/delve/dwarf/frame"
|
||||
"github.com/derekparker/delve/dwarf/line"
|
||||
"github.com/derekparker/delve/dwarf/reader"
|
||||
"golang.org/x/debug/dwarf"
|
||||
)
|
||||
|
||||
// Process represents all of the information the debugger
|
||||
// is holding onto regarding the process we are debugging.
|
||||
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
|
||||
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.
|
||||
// Maps instruction address to Breakpoint struct.
|
||||
breakpoints map[uint64]*Breakpoint
|
||||
Breakpoints map[uint64]*Breakpoint
|
||||
|
||||
// List of threads mapped as such: pid -> *Thread
|
||||
threads map[int]*Thread
|
||||
Threads map[int]*Thread
|
||||
|
||||
// Active thread
|
||||
currentThread *Thread
|
||||
CurrentThread *Thread
|
||||
|
||||
// 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
|
||||
selectedGoroutine *G
|
||||
// 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
|
||||
|
||||
// Maps package names to package paths, needed to lookup types inside DWARF info
|
||||
packageMap map[string]string
|
||||
@ -61,18 +61,12 @@ type Process struct {
|
||||
ptraceChan chan func()
|
||||
ptraceDoneChan chan interface{}
|
||||
types map[string]dwarf.Offset
|
||||
functions []functionDebugInfo
|
||||
|
||||
loadModuleDataOnce sync.Once
|
||||
moduleData []moduleData
|
||||
nameOfRuntimeType map[uintptr]nameOfRuntimeTypeEntry
|
||||
}
|
||||
|
||||
type functionDebugInfo struct {
|
||||
lowpc, highpc uint64
|
||||
offset dwarf.Offset
|
||||
}
|
||||
|
||||
var NotExecutableErr = errors.New("not an executable file")
|
||||
|
||||
// New returns an initialized Process struct. Before returning,
|
||||
@ -81,9 +75,9 @@ var NotExecutableErr = errors.New("not an executable file")
|
||||
// `handlePtraceFuncs`.
|
||||
func New(pid int) *Process {
|
||||
dbp := &Process{
|
||||
pid: pid,
|
||||
threads: make(map[int]*Thread),
|
||||
breakpoints: make(map[uint64]*Breakpoint),
|
||||
Pid: pid,
|
||||
Threads: make(map[int]*Thread),
|
||||
Breakpoints: make(map[uint64]*Breakpoint),
|
||||
firstStart: true,
|
||||
os: new(OSProcessDetails),
|
||||
ptraceChan: make(chan func()),
|
||||
@ -112,9 +106,6 @@ func (pe ProcessExitedError) Error() string {
|
||||
|
||||
// Detach from the process being debugged, optionally killing it.
|
||||
func (dbp *Process) Detach(kill bool) (err error) {
|
||||
if dbp.exited {
|
||||
return nil
|
||||
}
|
||||
if dbp.Running() {
|
||||
if err = dbp.Halt(); err != nil {
|
||||
return
|
||||
@ -122,7 +113,7 @@ func (dbp *Process) Detach(kill bool) (err error) {
|
||||
}
|
||||
if !kill {
|
||||
// Clean up any breakpoints we've set.
|
||||
for _, bp := range dbp.breakpoints {
|
||||
for _, bp := range dbp.Breakpoints {
|
||||
if bp != nil {
|
||||
_, err := dbp.ClearBreakpoint(bp.Addr)
|
||||
if err != nil {
|
||||
@ -132,12 +123,12 @@ func (dbp *Process) Detach(kill bool) (err error) {
|
||||
}
|
||||
}
|
||||
dbp.execPtraceFunc(func() {
|
||||
err = PtraceDetach(dbp.pid, 0)
|
||||
err = PtraceDetach(dbp.Pid, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if kill {
|
||||
err = killProcess(dbp.pid)
|
||||
err = killProcess(dbp.Pid)
|
||||
}
|
||||
})
|
||||
return
|
||||
@ -152,7 +143,7 @@ func (dbp *Process) Exited() bool {
|
||||
// Running returns whether the debugged
|
||||
// process is currently executing.
|
||||
func (dbp *Process) Running() bool {
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
if th.running {
|
||||
return true
|
||||
}
|
||||
@ -160,30 +151,6 @@ func (dbp *Process) Running() bool {
|
||||
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
|
||||
// to parse the following information:
|
||||
// * Dwarf .debug_frame section
|
||||
@ -198,7 +165,7 @@ func (dbp *Process) LoadInformation(path string) error {
|
||||
}
|
||||
fi, err := os.Stat(path)
|
||||
if err == nil {
|
||||
dbp.lastModified = fi.ModTime()
|
||||
dbp.LastModified = fi.ModTime()
|
||||
}
|
||||
|
||||
wg.Add(5)
|
||||
@ -206,7 +173,7 @@ func (dbp *Process) LoadInformation(path string) error {
|
||||
go dbp.parseDebugFrame(exe, &wg)
|
||||
go dbp.obtainGoSymbols(exe, &wg)
|
||||
go dbp.parseDebugLineInfo(exe, &wg)
|
||||
go dbp.loadDebugInfoMaps(&wg)
|
||||
go dbp.loadTypeMap(&wg)
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
@ -250,7 +217,7 @@ func (dbp *Process) FindFunctionLocation(funcName string, firstLine bool, lineOf
|
||||
|
||||
// CurrentLocation returns the location of the current thread.
|
||||
func (dbp *Process) CurrentLocation() (*Location, error) {
|
||||
return dbp.currentThread.Location()
|
||||
return dbp.CurrentThread.Location()
|
||||
}
|
||||
|
||||
// RequestManualStop sets the `halt` flag and
|
||||
@ -267,7 +234,7 @@ func (dbp *Process) RequestManualStop() error {
|
||||
// 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.
|
||||
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 {
|
||||
return nil, BreakpointExistsError{bp.File, bp.Line, bp.Addr}
|
||||
@ -296,7 +263,7 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp
|
||||
newBreakpoint.ID = dbp.breakpointIDCounter
|
||||
}
|
||||
|
||||
thread := dbp.threads[tid]
|
||||
thread := dbp.Threads[tid]
|
||||
originalData, err := thread.readMemory(uintptr(addr), dbp.arch.BreakpointSize())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -305,7 +272,7 @@ func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Exp
|
||||
return nil, err
|
||||
}
|
||||
newBreakpoint.OriginalData = originalData
|
||||
dbp.breakpoints[addr] = newBreakpoint
|
||||
dbp.Breakpoints[addr] = newBreakpoint
|
||||
|
||||
return newBreakpoint, nil
|
||||
}
|
||||
@ -320,18 +287,18 @@ func (dbp *Process) ClearBreakpoint(addr uint64) (*Breakpoint, error) {
|
||||
return nil, NoBreakpointError{addr: addr}
|
||||
}
|
||||
|
||||
if _, err := bp.Clear(dbp.currentThread); err != nil {
|
||||
if _, err := bp.Clear(dbp.CurrentThread); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
delete(dbp.breakpoints, addr)
|
||||
delete(dbp.Breakpoints, addr)
|
||||
|
||||
return bp, nil
|
||||
}
|
||||
|
||||
// Status returns the status of the current main thread context.
|
||||
func (dbp *Process) Status() *WaitStatus {
|
||||
return dbp.currentThread.Status
|
||||
return dbp.CurrentThread.Status
|
||||
}
|
||||
|
||||
// Next continues execution until the next source line.
|
||||
@ -339,8 +306,8 @@ func (dbp *Process) Next() (err error) {
|
||||
if dbp.exited {
|
||||
return &ProcessExitedError{}
|
||||
}
|
||||
for i := range dbp.breakpoints {
|
||||
if dbp.breakpoints[i].Internal() {
|
||||
for i := range dbp.Breakpoints {
|
||||
if dbp.Breakpoints[i].Internal() {
|
||||
return fmt.Errorf("next while nexting")
|
||||
}
|
||||
}
|
||||
@ -370,7 +337,7 @@ func (dbp *Process) Continue() error {
|
||||
}
|
||||
|
||||
dbp.allGCache = nil
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
th.clearBreakpointState()
|
||||
}
|
||||
|
||||
@ -389,42 +356,34 @@ func (dbp *Process) Continue() error {
|
||||
}
|
||||
|
||||
switch {
|
||||
case dbp.currentThread.CurrentBreakpoint == nil:
|
||||
case dbp.CurrentThread.CurrentBreakpoint == nil:
|
||||
// runtime.Breakpoint or manual stop
|
||||
if dbp.currentThread.onRuntimeBreakpoint() {
|
||||
// Single-step current thread until we exit runtime.breakpoint and
|
||||
// runtime.Breakpoint.
|
||||
// On go < 1.8 it was sufficient to single-step twice on go1.8 a change
|
||||
// to the compiler requires 4 steps.
|
||||
for {
|
||||
if err = dbp.currentThread.StepInstruction(); err != nil {
|
||||
if dbp.CurrentThread.onRuntimeBreakpoint() {
|
||||
for i := 0; i < 2; i++ {
|
||||
if err = dbp.CurrentThread.StepInstruction(); err != nil {
|
||||
return err
|
||||
}
|
||||
loc, err := dbp.currentThread.Location()
|
||||
if err != nil || loc.Fn == nil || (loc.Fn.Name != "runtime.breakpoint" && loc.Fn.Name != "runtime.Breakpoint") {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return dbp.conditionErrors()
|
||||
case dbp.currentThread.onTriggeredInternalBreakpoint():
|
||||
if dbp.currentThread.CurrentBreakpoint.Kind == StepBreakpoint {
|
||||
case dbp.CurrentThread.onTriggeredInternalBreakpoint():
|
||||
if dbp.CurrentThread.CurrentBreakpoint.Kind == StepBreakpoint {
|
||||
// See description of proc.(*Process).next for the meaning of StepBreakpoints
|
||||
if err := dbp.conditionErrors(); err != nil {
|
||||
return err
|
||||
}
|
||||
pc, err := dbp.currentThread.PC()
|
||||
pc, err := dbp.CurrentThread.PC()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
text, err := dbp.currentThread.Disassemble(pc, pc+maxInstructionLength, true)
|
||||
text, err := dbp.CurrentThread.Disassemble(pc, pc+maxInstructionLength, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// here we either set a breakpoint into the destination of the CALL
|
||||
// instruction or we determined that the called function is hidden,
|
||||
// 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
|
||||
}
|
||||
} else {
|
||||
@ -433,8 +392,8 @@ func (dbp *Process) Continue() error {
|
||||
}
|
||||
return dbp.conditionErrors()
|
||||
}
|
||||
case dbp.currentThread.onTriggeredBreakpoint():
|
||||
onNextGoroutine, err := dbp.currentThread.onNextGoroutine()
|
||||
case dbp.CurrentThread.onTriggeredBreakpoint():
|
||||
onNextGoroutine, err := dbp.CurrentThread.onNextGoroutine()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -453,7 +412,7 @@ func (dbp *Process) Continue() error {
|
||||
|
||||
func (dbp *Process) conditionErrors() error {
|
||||
var condErr error
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
if th.CurrentBreakpoint != nil && th.BreakpointConditionError != nil {
|
||||
if condErr == nil {
|
||||
condErr = th.BreakpointConditionError
|
||||
@ -465,12 +424,12 @@ func (dbp *Process) conditionErrors() error {
|
||||
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 onTriggeredBreakpoint() == true (prioritizing trapthread)
|
||||
// - trapthread
|
||||
func (dbp *Process) pickCurrentThread(trapthread *Thread) error {
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
if th.onTriggeredInternalBreakpoint() {
|
||||
return dbp.SwitchThread(th.ID)
|
||||
}
|
||||
@ -478,7 +437,7 @@ func (dbp *Process) pickCurrentThread(trapthread *Thread) error {
|
||||
if trapthread.onTriggeredBreakpoint() {
|
||||
return dbp.SwitchThread(trapthread.ID)
|
||||
}
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
if th.onTriggeredBreakpoint() {
|
||||
return dbp.SwitchThread(th.ID)
|
||||
}
|
||||
@ -492,8 +451,8 @@ func (dbp *Process) Step() (err error) {
|
||||
if dbp.exited {
|
||||
return &ProcessExitedError{}
|
||||
}
|
||||
for i := range dbp.breakpoints {
|
||||
if dbp.breakpoints[i].Internal() {
|
||||
for i := range dbp.Breakpoints {
|
||||
if dbp.Breakpoints[i].Internal() {
|
||||
return fmt.Errorf("next while nexting")
|
||||
}
|
||||
}
|
||||
@ -533,12 +492,12 @@ func sameGoroutineCondition(g *G) ast.Expr {
|
||||
// asssociated with the selected goroutine. All other
|
||||
// threads will remain stopped.
|
||||
func (dbp *Process) StepInstruction() (err error) {
|
||||
if dbp.selectedGoroutine == nil {
|
||||
if dbp.SelectedGoroutine == nil {
|
||||
return errors.New("cannot single step: no selected goroutine")
|
||||
}
|
||||
if dbp.selectedGoroutine.thread == nil {
|
||||
if dbp.SelectedGoroutine.thread == nil {
|
||||
// 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 dbp.Continue()
|
||||
@ -547,20 +506,20 @@ func (dbp *Process) StepInstruction() (err error) {
|
||||
if dbp.exited {
|
||||
return &ProcessExitedError{}
|
||||
}
|
||||
dbp.selectedGoroutine.thread.clearBreakpointState()
|
||||
err = dbp.selectedGoroutine.thread.StepInstruction()
|
||||
dbp.SelectedGoroutine.thread.clearBreakpointState()
|
||||
err = dbp.SelectedGoroutine.thread.StepInstruction()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dbp.selectedGoroutine.thread.SetCurrentBreakpoint()
|
||||
return dbp.SelectedGoroutine.thread.SetCurrentBreakpoint()
|
||||
}
|
||||
|
||||
// StepOut will continue until the current goroutine exits the
|
||||
// function currently being executed or a deferred function is executed
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -569,16 +528,13 @@ func (dbp *Process) StepOut() error {
|
||||
|
||||
var deferpc uint64 = 0
|
||||
if filepath.Ext(topframe.Current.File) == ".go" {
|
||||
if dbp.selectedGoroutine != nil {
|
||||
deferPCEntry := dbp.selectedGoroutine.DeferPC()
|
||||
if deferPCEntry != 0 {
|
||||
_, _, deferfn := dbp.goSymTable.PCToLine(deferPCEntry)
|
||||
deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pcs = append(pcs, deferpc)
|
||||
if dbp.SelectedGoroutine != nil && dbp.SelectedGoroutine.DeferPC != 0 {
|
||||
_, _, deferfn := dbp.goSymTable.PCToLine(dbp.SelectedGoroutine.DeferPC)
|
||||
deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pcs = append(pcs, deferpc)
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,9 +572,9 @@ func (dbp *Process) SwitchThread(tid int) error {
|
||||
if dbp.exited {
|
||||
return &ProcessExitedError{}
|
||||
}
|
||||
if th, ok := dbp.threads[tid]; ok {
|
||||
dbp.currentThread = th
|
||||
dbp.selectedGoroutine, _ = dbp.currentThread.GetG()
|
||||
if th, ok := dbp.Threads[tid]; ok {
|
||||
dbp.CurrentThread = th
|
||||
dbp.SelectedGoroutine, _ = dbp.CurrentThread.GetG()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("thread %d does not exist", tid)
|
||||
@ -635,13 +591,13 @@ func (dbp *Process) SwitchGoroutine(gid int) error {
|
||||
return err
|
||||
}
|
||||
if g == nil {
|
||||
// user specified -1 and selectedGoroutine is nil
|
||||
// user specified -1 and SelectedGoroutine is nil
|
||||
return nil
|
||||
}
|
||||
if g.thread != nil {
|
||||
return dbp.SwitchThread(g.thread.ID)
|
||||
}
|
||||
dbp.selectedGoroutine = g
|
||||
dbp.SelectedGoroutine = g
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -661,13 +617,13 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
|
||||
rdr = dbp.DwarfReader()
|
||||
)
|
||||
|
||||
for i := range dbp.threads {
|
||||
if dbp.threads[i].blocked() {
|
||||
for i := range dbp.Threads {
|
||||
if dbp.Threads[i].blocked() {
|
||||
continue
|
||||
}
|
||||
g, _ := dbp.threads[i].GetG()
|
||||
g, _ := dbp.Threads[i].GetG()
|
||||
if g != nil {
|
||||
threadg[g.ID] = dbp.threads[i]
|
||||
threadg[g.ID] = dbp.Threads[i]
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,7 +631,7 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allglenBytes, err := dbp.currentThread.readMemory(uintptr(addr), 8)
|
||||
allglenBytes, err := dbp.CurrentThread.readMemory(uintptr(addr), 8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -690,11 +646,11 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
|
||||
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)
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -728,7 +684,7 @@ func (dbp *Process) Halt() (err error) {
|
||||
if dbp.exited {
|
||||
return &ProcessExitedError{}
|
||||
}
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
if err := th.Halt(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -739,18 +695,18 @@ func (dbp *Process) Halt() (err error) {
|
||||
// Registers obtains register values from the
|
||||
// "current" thread of the traced process.
|
||||
func (dbp *Process) Registers() (Registers, error) {
|
||||
return dbp.currentThread.Registers(false)
|
||||
return dbp.CurrentThread.Registers(false)
|
||||
}
|
||||
|
||||
// PC returns the PC of the current thread.
|
||||
func (dbp *Process) PC() (uint64, error) {
|
||||
return dbp.currentThread.PC()
|
||||
return dbp.CurrentThread.PC()
|
||||
}
|
||||
|
||||
// CurrentBreakpoint returns the breakpoint the current thread
|
||||
// is stopped at.
|
||||
func (dbp *Process) CurrentBreakpoint() *Breakpoint {
|
||||
return dbp.currentThread.CurrentBreakpoint
|
||||
return dbp.CurrentThread.CurrentBreakpoint
|
||||
}
|
||||
|
||||
// DwarfReader returns a reader for the dwarf data
|
||||
@ -784,7 +740,7 @@ func (dbp *Process) PCToLine(pc uint64) (string, int, *gosym.Func) {
|
||||
|
||||
// FindBreakpointByID finds the breakpoint for the given ID.
|
||||
func (dbp *Process) FindBreakpointByID(id int) (*Breakpoint, bool) {
|
||||
for _, bp := range dbp.breakpoints {
|
||||
for _, bp := range dbp.Breakpoints {
|
||||
if bp.ID == id {
|
||||
return bp, true
|
||||
}
|
||||
@ -795,11 +751,11 @@ func (dbp *Process) FindBreakpointByID(id int) (*Breakpoint, bool) {
|
||||
// FindBreakpoint finds the breakpoint for the given pc.
|
||||
func (dbp *Process) FindBreakpoint(pc uint64) (*Breakpoint, bool) {
|
||||
// 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
|
||||
}
|
||||
// Directly use addr to lookup breakpoint.
|
||||
if bp, ok := dbp.breakpoints[pc]; ok {
|
||||
if bp, ok := dbp.Breakpoints[pc]; ok {
|
||||
return bp, true
|
||||
}
|
||||
return nil, false
|
||||
@ -809,17 +765,17 @@ func (dbp *Process) FindBreakpoint(pc uint64) (*Breakpoint, bool) {
|
||||
func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, error) {
|
||||
if attach {
|
||||
var err error
|
||||
dbp.execPtraceFunc(func() { err = PtraceAttach(dbp.pid) })
|
||||
dbp.execPtraceFunc(func() { err = PtraceAttach(dbp.Pid) })
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, _, err = dbp.wait(dbp.pid, 0)
|
||||
_, _, err = dbp.wait(dbp.Pid, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
proc, err := os.FindProcess(dbp.pid)
|
||||
proc, err := os.FindProcess(dbp.Pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -840,11 +796,11 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e
|
||||
}
|
||||
|
||||
dbp.arch.SetGStructOffset(ver, isextld)
|
||||
// selectedGoroutine can not be set correctly by the call to updateThreadList
|
||||
// because without calling SetGStructOffset we can not read the G struct of currentThread
|
||||
// SelectedGoroutine can not be set correctly by the call to updateThreadList
|
||||
// because without calling SetGStructOffset we can not read the G struct of CurrentThread
|
||||
// but without calling updateThreadList we can not examine memory to determine
|
||||
// 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)
|
||||
if err == nil {
|
||||
@ -860,7 +816,7 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e
|
||||
}
|
||||
|
||||
func (dbp *Process) ClearInternalBreakpoints() error {
|
||||
for _, bp := range dbp.breakpoints {
|
||||
for _, bp := range dbp.Breakpoints {
|
||||
if !bp.Internal() {
|
||||
continue
|
||||
}
|
||||
@ -868,9 +824,9 @@ func (dbp *Process) ClearInternalBreakpoints() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for i := range dbp.threads {
|
||||
if dbp.threads[i].CurrentBreakpoint != nil && dbp.threads[i].CurrentBreakpoint.Internal() {
|
||||
dbp.threads[i].CurrentBreakpoint = nil
|
||||
for i := range dbp.Threads {
|
||||
if dbp.Threads[i].CurrentBreakpoint != nil && dbp.Threads[i].CurrentBreakpoint.Internal() {
|
||||
dbp.Threads[i].CurrentBreakpoint = nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -928,7 +884,7 @@ func (dbp *Process) getGoInformation() (ver GoVersion, isextld bool, err error)
|
||||
// specified by `gid`.
|
||||
func (dbp *Process) FindGoroutine(gid int) (*G, error) {
|
||||
if gid == -1 {
|
||||
return dbp.selectedGoroutine, nil
|
||||
return dbp.SelectedGoroutine, nil
|
||||
}
|
||||
|
||||
gs, err := dbp.GoroutinesInfo()
|
||||
@ -954,13 +910,13 @@ func (dbp *Process) ConvertEvalScope(gid, frame int) (*EvalScope, error) {
|
||||
return nil, err
|
||||
}
|
||||
if g == nil {
|
||||
return dbp.currentThread.Scope()
|
||||
return dbp.CurrentThread.Scope()
|
||||
}
|
||||
|
||||
var out EvalScope
|
||||
|
||||
if g.thread == nil {
|
||||
out.Thread = dbp.currentThread
|
||||
out.Thread = dbp.CurrentThread
|
||||
} else {
|
||||
out.Thread = g.thread
|
||||
}
|
@ -17,8 +17,8 @@ import (
|
||||
|
||||
"golang.org/x/debug/macho"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/frame"
|
||||
"github.com/derekparker/delve/pkg/dwarf/line"
|
||||
"github.com/derekparker/delve/dwarf/frame"
|
||||
"github.com/derekparker/delve/dwarf/line"
|
||||
sys "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -77,7 +77,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
|
||||
if pid <= 0 {
|
||||
return nil, fmt.Errorf("could not fork/exec")
|
||||
}
|
||||
dbp.pid = pid
|
||||
dbp.Pid = pid
|
||||
for i := range argvSlice {
|
||||
C.free(unsafe.Pointer(argvSlice[i]))
|
||||
}
|
||||
@ -86,7 +86,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
|
||||
// trapWait to wait until the child process calls execve.
|
||||
|
||||
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 {
|
||||
break
|
||||
}
|
||||
@ -100,7 +100,7 @@ func Launch(cmd []string, wd string) (*Process, error) {
|
||||
}
|
||||
|
||||
dbp.allGCache = nil
|
||||
for _, th := range dbp.threads {
|
||||
for _, th := range dbp.Threads {
|
||||
th.clearBreakpointState()
|
||||
}
|
||||
|
||||
@ -152,11 +152,11 @@ func (dbp *Process) Kill() (err error) {
|
||||
if dbp.exited {
|
||||
return nil
|
||||
}
|
||||
err = sys.Kill(-dbp.pid, sys.SIGKILL)
|
||||
err = sys.Kill(-dbp.Pid, sys.SIGKILL)
|
||||
if err != nil {
|
||||
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 {
|
||||
return errors.New("could not resume task")
|
||||
}
|
||||
@ -175,7 +175,7 @@ func (dbp *Process) Kill() (err error) {
|
||||
func (dbp *Process) requestManualStop() (err error) {
|
||||
var (
|
||||
task = C.mach_port_t(dbp.os.task)
|
||||
thread = C.mach_port_t(dbp.currentThread.os.threadAct)
|
||||
thread = C.mach_port_t(dbp.CurrentThread.os.threadAct)
|
||||
exceptionPort = C.mach_port_t(dbp.os.exceptionPort)
|
||||
)
|
||||
kret := C.raise_exception(task, thread, exceptionPort, C.EXC_BREAKPOINT)
|
||||
@ -218,12 +218,12 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error {
|
||||
return couldNotGetThreadList
|
||||
}
|
||||
|
||||
for _, thread := range dbp.threads {
|
||||
for _, thread := range dbp.Threads {
|
||||
thread.os.exists = false
|
||||
}
|
||||
|
||||
for _, port := range list {
|
||||
thread, ok := dbp.threads[int(port)]
|
||||
thread, ok := dbp.Threads[int(port)]
|
||||
if !ok {
|
||||
thread, err = dbp.addThread(int(port), false)
|
||||
if err != nil {
|
||||
@ -233,9 +233,9 @@ func (dbp *Process) updateThreadListForTask(task C.task_t) error {
|
||||
thread.os.exists = true
|
||||
}
|
||||
|
||||
for threadID, thread := range dbp.threads {
|
||||
for threadID, thread := range dbp.Threads {
|
||||
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 {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
thread := &Thread{
|
||||
@ -251,9 +251,9 @@ func (dbp *Process) addThread(port int, attach bool) (*Thread, error) {
|
||||
dbp: dbp,
|
||||
os: new(OSSpecificDetails),
|
||||
}
|
||||
dbp.threads[port] = thread
|
||||
dbp.Threads[port] = thread
|
||||
thread.os.threadAct = C.thread_act_t(port)
|
||||
if dbp.currentThread == nil {
|
||||
if dbp.CurrentThread == nil {
|
||||
dbp.SwitchThread(thread.ID)
|
||||
}
|
||||
return thread, nil
|
||||