mirror of
https://github.com/go-delve/delve.git
synced 2025-10-28 20:53:42 +08:00
Rename thread.Process -> thread.dbp
Process is an incorrect name for the DebuggedProcess struct that the thread is "a part" of. Also, no need to export that field.
This commit is contained in:
@ -124,15 +124,14 @@ func threads(p *proctl.DebuggedProcess, args ...string) error {
|
|||||||
if th == p.CurrentThread {
|
if th == p.CurrentThread {
|
||||||
prefix = "* "
|
prefix = "* "
|
||||||
}
|
}
|
||||||
pc, err := th.PC()
|
loc, err := th.Location()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f, l, fn := th.Process.PCToLine(pc)
|
if loc.Fn != nil {
|
||||||
if fn != nil {
|
fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, loc.PC, loc.File, loc.Line, loc.Fn.Name)
|
||||||
fmt.Printf("%sThread %d at %#v %s:%d %s\n", prefix, th.Id, pc, f, l, fn.Name)
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%sThread %d at %#v\n", prefix, th.Id, pc)
|
fmt.Printf("%sThread %d at %#v\n", prefix, th.Id, loc.PC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -122,7 +122,7 @@ func (dbp *DebuggedProcess) addThread(port int, attach bool) (*ThreadContext, er
|
|||||||
}
|
}
|
||||||
thread := &ThreadContext{
|
thread := &ThreadContext{
|
||||||
Id: port,
|
Id: port,
|
||||||
Process: dbp,
|
dbp: dbp,
|
||||||
os: new(OSSpecificDetails),
|
os: new(OSSpecificDetails),
|
||||||
}
|
}
|
||||||
dbp.Threads[port] = thread
|
dbp.Threads[port] = thread
|
||||||
|
|||||||
@ -101,7 +101,7 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
|
|||||||
|
|
||||||
dbp.Threads[tid] = &ThreadContext{
|
dbp.Threads[tid] = &ThreadContext{
|
||||||
Id: tid,
|
Id: tid,
|
||||||
Process: dbp,
|
dbp: dbp,
|
||||||
os: new(OSSpecificDetails),
|
os: new(OSSpecificDetails),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -443,7 +443,7 @@ func TestFunctionCall(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
f := th.Process.goSymTable.LookupFunc("runtime.getg")
|
f := th.dbp.goSymTable.LookupFunc("runtime.getg")
|
||||||
if f == nil {
|
if f == nil {
|
||||||
t.Fatalf("could not find function %s", "runtime.getg")
|
t.Fatalf("could not find function %s", "runtime.getg")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ func (thread *ThreadContext) ReturnAddress() (uint64, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
locations, err := thread.Process.stacktrace(regs.PC(), regs.SP(), 1)
|
locations, err := thread.dbp.stacktrace(regs.PC(), regs.SP(), 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package proctl
|
package proctl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"debug/gosym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@ -16,14 +17,21 @@ import (
|
|||||||
// on this thread.
|
// on this thread.
|
||||||
type ThreadContext struct {
|
type ThreadContext struct {
|
||||||
Id int
|
Id int
|
||||||
Process *DebuggedProcess
|
|
||||||
Status *sys.WaitStatus
|
Status *sys.WaitStatus
|
||||||
CurrentBreakpoint *BreakPoint
|
CurrentBreakpoint *BreakPoint
|
||||||
|
dbp *DebuggedProcess
|
||||||
singleStepping bool
|
singleStepping bool
|
||||||
running bool
|
running bool
|
||||||
os *OSSpecificDetails
|
os *OSSpecificDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
PC uint64
|
||||||
|
File string
|
||||||
|
Line int
|
||||||
|
Fn *gosym.Func
|
||||||
|
}
|
||||||
|
|
||||||
// Continue the execution of this thread. This method takes
|
// Continue the execution of this thread. This method takes
|
||||||
// software breakpoints into consideration and ensures that
|
// software breakpoints into consideration and ensures that
|
||||||
// we step over any breakpoints. It will restore the instruction,
|
// we step over any breakpoints. It will restore the instruction,
|
||||||
@ -36,7 +44,7 @@ func (thread *ThreadContext) Continue() error {
|
|||||||
|
|
||||||
// Check whether we are stopped at a breakpoint, and
|
// Check whether we are stopped at a breakpoint, and
|
||||||
// if so, single step over it before continuing.
|
// if so, single step over it before continuing.
|
||||||
if _, ok := thread.Process.BreakPoints[pc]; ok {
|
if _, ok := thread.dbp.BreakPoints[pc]; ok {
|
||||||
if err := thread.Step(); err != nil {
|
if err := thread.Step(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -54,10 +62,10 @@ func (thread *ThreadContext) Step() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
bp, ok := thread.Process.BreakPoints[pc]
|
bp, ok := thread.dbp.BreakPoints[pc]
|
||||||
if ok {
|
if ok {
|
||||||
// Clear the breakpoint so that we can continue execution.
|
// Clear the breakpoint so that we can continue execution.
|
||||||
_, err = thread.Process.Clear(bp.Addr)
|
_, err = thread.dbp.Clear(bp.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -65,7 +73,7 @@ func (thread *ThreadContext) Step() (err error) {
|
|||||||
// Restore breakpoint now that we have passed it.
|
// Restore breakpoint now that we have passed it.
|
||||||
defer func() {
|
defer func() {
|
||||||
var nbp *BreakPoint
|
var nbp *BreakPoint
|
||||||
nbp, err = thread.Process.Break(bp.Addr)
|
nbp, err = thread.dbp.Break(bp.Addr)
|
||||||
nbp.Temp = bp.Temp
|
nbp.Temp = bp.Temp
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -79,7 +87,7 @@ func (thread *ThreadContext) Step() (err error) {
|
|||||||
|
|
||||||
// Call a function named `name`. This is currently _NOT_ safe.
|
// Call a function named `name`. This is currently _NOT_ safe.
|
||||||
func (thread *ThreadContext) CallFn(name string, fn func() error) error {
|
func (thread *ThreadContext) CallFn(name string, fn func() error) error {
|
||||||
f := thread.Process.goSymTable.LookupFunc(name)
|
f := thread.dbp.goSymTable.LookupFunc(name)
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return fmt.Errorf("could not find function %s", name)
|
return fmt.Errorf("could not find function %s", name)
|
||||||
}
|
}
|
||||||
@ -89,7 +97,7 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer thread.Process.Clear(bp.Addr)
|
defer thread.dbp.Clear(bp.Addr)
|
||||||
|
|
||||||
regs, err := thread.saveRegisters()
|
regs, err := thread.saveRegisters()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -110,7 +118,7 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
|
|||||||
if err = thread.Continue(); err != nil {
|
if err = thread.Continue(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
th, err := thread.Process.trapWait(-1)
|
th, err := thread.dbp.trapWait(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -120,17 +128,26 @@ func (thread *ThreadContext) CallFn(name string, fn func() error) error {
|
|||||||
|
|
||||||
// Set breakpoint using this thread.
|
// Set breakpoint using this thread.
|
||||||
func (thread *ThreadContext) Break(addr uint64) (*BreakPoint, error) {
|
func (thread *ThreadContext) Break(addr uint64) (*BreakPoint, error) {
|
||||||
return thread.Process.setBreakpoint(thread.Id, addr, false)
|
return thread.dbp.setBreakpoint(thread.Id, addr, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set breakpoint using this thread.
|
// Set breakpoint using this thread.
|
||||||
func (thread *ThreadContext) TempBreak(addr uint64) (*BreakPoint, error) {
|
func (thread *ThreadContext) TempBreak(addr uint64) (*BreakPoint, error) {
|
||||||
return thread.Process.setBreakpoint(thread.Id, addr, true)
|
return thread.dbp.setBreakpoint(thread.Id, addr, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear breakpoint using this thread.
|
// Clear breakpoint using this thread.
|
||||||
func (thread *ThreadContext) Clear(addr uint64) (*BreakPoint, error) {
|
func (thread *ThreadContext) Clear(addr uint64) (*BreakPoint, error) {
|
||||||
return thread.Process.clearBreakpoint(thread.Id, addr)
|
return thread.dbp.clearBreakpoint(thread.Id, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (thread *ThreadContext) Location() (*Location, error) {
|
||||||
|
pc, err := thread.PC()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f, l, fn := thread.dbp.PCToLine(pc)
|
||||||
|
return &Location{PC: pc, File: f, Line: l, Fn: fn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step to next source line.
|
// Step to next source line.
|
||||||
@ -149,15 +166,18 @@ func (thread *ThreadContext) Next() (err error) {
|
|||||||
|
|
||||||
// Grab info on our current stack frame. Used to determine
|
// Grab info on our current stack frame. Used to determine
|
||||||
// whether we may be stepping outside of the current function.
|
// whether we may be stepping outside of the current function.
|
||||||
fde, err := thread.Process.frameEntries.FDEForPC(curpc)
|
fde, err := thread.dbp.frameEntries.FDEForPC(curpc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current file/line.
|
// Get current file/line.
|
||||||
f, l, _ := thread.Process.goSymTable.PCToLine(curpc)
|
loc, err := thread.Location()
|
||||||
if filepath.Ext(f) == ".go" {
|
if err != nil {
|
||||||
if err = thread.next(curpc, fde, f, l); err != nil {
|
return err
|
||||||
|
}
|
||||||
|
if filepath.Ext(loc.File) == ".go" {
|
||||||
|
if err = thread.next(curpc, fde, loc.File, loc.Line); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -180,7 +200,7 @@ func (ge GoroutineExitingError) Error() string {
|
|||||||
// This version of next uses the AST from the current source file to figure out all of the potential source lines
|
// This version of next uses the AST from the current source file to figure out all of the potential source lines
|
||||||
// we could end up at.
|
// we could end up at.
|
||||||
func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry, file string, line int) error {
|
func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry, file string, line int) error {
|
||||||
lines, err := thread.Process.ast.NextLines(file, line)
|
lines, err := thread.dbp.ast.NextLines(file, line)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(source.NoNodeError); !ok {
|
if _, ok := err.(source.NoNodeError); !ok {
|
||||||
return err
|
return err
|
||||||
@ -194,7 +214,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
|
|||||||
|
|
||||||
pcs := make([]uint64, 0, len(lines))
|
pcs := make([]uint64, 0, len(lines))
|
||||||
for i := range lines {
|
for i := range lines {
|
||||||
pcs = append(pcs, thread.Process.lineInfo.AllPCsForFileLine(file, lines[i])...)
|
pcs = append(pcs, thread.dbp.lineInfo.AllPCsForFileLine(file, lines[i])...)
|
||||||
}
|
}
|
||||||
|
|
||||||
var covered bool
|
var covered bool
|
||||||
@ -206,7 +226,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !covered {
|
if !covered {
|
||||||
fn := thread.Process.goSymTable.PCToFunc(ret)
|
fn := thread.dbp.goSymTable.PCToFunc(ret)
|
||||||
if fn != nil && fn.Name == "runtime.goexit" {
|
if fn != nil && fn.Name == "runtime.goexit" {
|
||||||
g, err := thread.curG()
|
g, err := thread.curG()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -223,7 +243,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
|
|||||||
// the benefit of an AST we can't be sure we're not at a branching statement and thus
|
// the benefit of an AST we can't be sure we're not at a branching statement and thus
|
||||||
// cannot accurately predict where we may end up.
|
// cannot accurately predict where we may end up.
|
||||||
func (thread *ThreadContext) cnext(curpc uint64, fde *frame.FrameDescriptionEntry) error {
|
func (thread *ThreadContext) cnext(curpc uint64, fde *frame.FrameDescriptionEntry) error {
|
||||||
pcs := thread.Process.lineInfo.AllPCsBetween(fde.Begin(), fde.End())
|
pcs := thread.dbp.lineInfo.AllPCsBetween(fde.Begin(), fde.End())
|
||||||
ret, err := thread.ReturnAddress()
|
ret, err := thread.ReturnAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -237,7 +257,7 @@ func (thread *ThreadContext) setNextTempBreakpoints(curpc uint64, pcs []uint64)
|
|||||||
if pcs[i] == curpc || pcs[i] == curpc-1 {
|
if pcs[i] == curpc || pcs[i] == curpc-1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, err := thread.Process.TempBreak(pcs[i]); err != nil {
|
if _, err := thread.dbp.TempBreak(pcs[i]); err != nil {
|
||||||
if err, ok := err.(BreakPointExistsError); !ok {
|
if err, ok := err.(BreakPointExistsError); !ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -262,7 +282,7 @@ func (thread *ThreadContext) curG() (*G, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
g, err = parseG(thread, regs.SP()+uint64(thread.Process.arch.PtrSize()))
|
g, err = parseG(thread, regs.SP()+uint64(thread.dbp.arch.PtrSize()))
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
return g, err
|
return g, err
|
||||||
|
|||||||
@ -26,7 +26,7 @@ func (t *ThreadContext) singleStep() error {
|
|||||||
if kret != C.KERN_SUCCESS {
|
if kret != C.KERN_SUCCESS {
|
||||||
return fmt.Errorf("could not single step")
|
return fmt.Errorf("could not single step")
|
||||||
}
|
}
|
||||||
t.Process.trapWait(0)
|
t.dbp.trapWait(0)
|
||||||
kret = C.clear_trap_flag(t.os.thread_act)
|
kret = C.clear_trap_flag(t.os.thread_act)
|
||||||
if kret != C.KERN_SUCCESS {
|
if kret != C.KERN_SUCCESS {
|
||||||
return fmt.Errorf("could not clear CPU trap flag")
|
return fmt.Errorf("could not clear CPU trap flag")
|
||||||
@ -36,7 +36,7 @@ func (t *ThreadContext) singleStep() error {
|
|||||||
|
|
||||||
func (t *ThreadContext) resume() error {
|
func (t *ThreadContext) resume() error {
|
||||||
// TODO(dp) set flag for ptrace stops
|
// TODO(dp) set flag for ptrace stops
|
||||||
if PtraceCont(t.Process.Pid, 0) == nil {
|
if PtraceCont(t.dbp.Pid, 0) == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
kret := C.resume_thread(t.os.thread_act)
|
kret := C.resume_thread(t.os.thread_act)
|
||||||
@ -49,7 +49,7 @@ func (t *ThreadContext) resume() error {
|
|||||||
func (t *ThreadContext) blocked() bool {
|
func (t *ThreadContext) blocked() bool {
|
||||||
// TODO(dp) cache the func pc to remove this lookup
|
// TODO(dp) cache the func pc to remove this lookup
|
||||||
pc, _ := t.PC()
|
pc, _ := t.PC()
|
||||||
fn := t.Process.goSymTable.PCToFunc(pc)
|
fn := t.dbp.goSymTable.PCToFunc(pc)
|
||||||
if fn != nil && (fn.Name == "runtime.mach_semaphore_wait" || fn.Name == "runtime.usleep") {
|
if fn != nil && (fn.Name == "runtime.mach_semaphore_wait" || fn.Name == "runtime.usleep") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ func writeMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error)
|
|||||||
length = C.mach_msg_type_number_t(len(data))
|
length = C.mach_msg_type_number_t(len(data))
|
||||||
)
|
)
|
||||||
|
|
||||||
if ret := C.write_memory(thread.Process.os.task, vm_addr, vm_data, length); ret < 0 {
|
if ret := C.write_memory(thread.dbp.os.task, vm_addr, vm_data, length); ret < 0 {
|
||||||
return 0, fmt.Errorf("could not write memory")
|
return 0, fmt.Errorf("could not write memory")
|
||||||
}
|
}
|
||||||
return len(data), nil
|
return len(data), nil
|
||||||
@ -76,7 +76,7 @@ func readMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
|
|||||||
length = C.mach_msg_type_number_t(len(data))
|
length = C.mach_msg_type_number_t(len(data))
|
||||||
)
|
)
|
||||||
|
|
||||||
ret := C.read_memory(thread.Process.os.task, vm_addr, vm_data, length)
|
ret := C.read_memory(thread.dbp.os.task, vm_addr, vm_data, length)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return 0, fmt.Errorf("could not read memory")
|
return 0, fmt.Errorf("could not read memory")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ func (t *ThreadContext) Halt() error {
|
|||||||
if stopped(t.Id) {
|
if stopped(t.Id) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := sys.Tgkill(t.Process.Pid, t.Id, sys.SIGSTOP)
|
err := sys.Tgkill(t.dbp.Pid, t.Id, sys.SIGSTOP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Halt err %s %d", err, t.Id)
|
return fmt.Errorf("Halt err %s %d", err, t.Id)
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ func (t *ThreadContext) singleStep() error {
|
|||||||
func (t *ThreadContext) blocked() bool {
|
func (t *ThreadContext) blocked() bool {
|
||||||
// TODO(dp) cache the func pc to remove this lookup
|
// TODO(dp) cache the func pc to remove this lookup
|
||||||
pc, _ := t.PC()
|
pc, _ := t.PC()
|
||||||
fn := t.Process.goSymTable.PCToFunc(pc)
|
fn := t.dbp.goSymTable.PCToFunc(pc)
|
||||||
if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) {
|
if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ func (ng NoGError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseG(thread *ThreadContext, addr uint64) (*G, error) {
|
func parseG(thread *ThreadContext, addr uint64) (*G, error) {
|
||||||
gaddrbytes, err := thread.readMemory(uintptr(addr), thread.Process.arch.PtrSize())
|
gaddrbytes, err := thread.readMemory(uintptr(addr), thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error derefing *G %s", err)
|
return nil, fmt.Errorf("error derefing *G %s", err)
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
|
|||||||
return nil, NoGError{tid: thread.Id}
|
return nil, NoGError{tid: thread.Id}
|
||||||
}
|
}
|
||||||
|
|
||||||
rdr := thread.Process.DwarfReader()
|
rdr := thread.dbp.DwarfReader()
|
||||||
rdr.Seek(0)
|
rdr.Seek(0)
|
||||||
entry, err := rdr.SeekToTypeNamed("runtime.g")
|
entry, err := rdr.SeekToTypeNamed("runtime.g")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -107,7 +107,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
|
|||||||
}
|
}
|
||||||
var deferPC uint64
|
var deferPC uint64
|
||||||
// Dereference *defer pointer
|
// Dereference *defer pointer
|
||||||
deferAddrBytes, err := thread.readMemory(uintptr(deferAddr), thread.Process.arch.PtrSize())
|
deferAddrBytes, err := thread.readMemory(uintptr(deferAddr), thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error derefing *G %s", err)
|
return nil, fmt.Errorf("error derefing *G %s", err)
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pc, err := thread.readUintRaw(uintptr(schedAddr+uint64(thread.Process.arch.PtrSize())), 8)
|
pc, err := thread.readUintRaw(uintptr(schedAddr+uint64(thread.dbp.arch.PtrSize())), 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ func parseG(thread *ThreadContext, addr uint64) (*G, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
f, l, fn := thread.Process.goSymTable.PCToLine(gopc)
|
f, l, fn := thread.dbp.goSymTable.PCToLine(gopc)
|
||||||
g := &G{
|
g := &G{
|
||||||
Id: int(goid),
|
Id: int(goid),
|
||||||
GoPC: gopc,
|
GoPC: gopc,
|
||||||
@ -195,7 +195,7 @@ func (thread *ThreadContext) EvalSymbol(name string) (*Variable, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := thread.Process.DwarfReader()
|
reader := thread.dbp.DwarfReader()
|
||||||
|
|
||||||
_, err = reader.SeekToFunction(pc)
|
_, err = reader.SeekToFunction(pc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -243,7 +243,7 @@ func (thread *ThreadContext) FunctionArguments() ([]*Variable, error) {
|
|||||||
|
|
||||||
// PackageVariables returns the name, value, and type of all package variables in the application.
|
// PackageVariables returns the name, value, and type of all package variables in the application.
|
||||||
func (thread *ThreadContext) PackageVariables() ([]*Variable, error) {
|
func (thread *ThreadContext) PackageVariables() ([]*Variable, error) {
|
||||||
reader := thread.Process.DwarfReader()
|
reader := thread.dbp.DwarfReader()
|
||||||
|
|
||||||
vars := make([]*Variable, 0)
|
vars := make([]*Variable, 0)
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, rdr
|
|||||||
return nil, fmt.Errorf("type assertion failed")
|
return nil, fmt.Errorf("type assertion failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
data := thread.Process.dwarf
|
data := thread.dbp.dwarf
|
||||||
t, err := data.Type(offset)
|
t, err := data.Type(offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -349,7 +349,7 @@ func (thread *ThreadContext) extractVariableFromEntry(entry *dwarf.Entry) (*Vari
|
|||||||
return nil, fmt.Errorf("type assertion failed")
|
return nil, fmt.Errorf("type assertion failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
data := thread.Process.dwarf
|
data := thread.dbp.dwarf
|
||||||
t, err := data.Type(offset)
|
t, err := data.Type(offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -375,7 +375,7 @@ func (thread *ThreadContext) executeStackProgram(instructions []byte) (int64, er
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fde, err := thread.Process.frameEntries.FDEForPC(regs.PC())
|
fde, err := thread.dbp.frameEntries.FDEForPC(regs.PC())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -413,7 +413,7 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, rdr
|
|||||||
|
|
||||||
ptraddress := uintptr(address)
|
ptraddress := uintptr(address)
|
||||||
|
|
||||||
ptr, err := thread.readMemory(ptraddress, thread.Process.arch.PtrSize())
|
ptr, err := thread.readMemory(ptraddress, thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -453,7 +453,7 @@ func (thread *ThreadContext) extractValueInternal(instructions []byte, addr int6
|
|||||||
ptraddress := uintptr(addr)
|
ptraddress := uintptr(addr)
|
||||||
switch t := typ.(type) {
|
switch t := typ.(type) {
|
||||||
case *dwarf.PtrType:
|
case *dwarf.PtrType:
|
||||||
ptr, err := thread.readMemory(ptraddress, thread.Process.arch.PtrSize())
|
ptr, err := thread.readMemory(ptraddress, thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -528,14 +528,14 @@ func (thread *ThreadContext) readString(addr uintptr) (string, error) {
|
|||||||
// http://research.swtch.com/godata
|
// http://research.swtch.com/godata
|
||||||
|
|
||||||
// read len
|
// read len
|
||||||
val, err := thread.readMemory(addr+uintptr(thread.Process.arch.PtrSize()), thread.Process.arch.PtrSize())
|
val, err := thread.readMemory(addr+uintptr(thread.dbp.arch.PtrSize()), thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
strlen := int(binary.LittleEndian.Uint64(val))
|
strlen := int(binary.LittleEndian.Uint64(val))
|
||||||
|
|
||||||
// read addr
|
// read addr
|
||||||
val, err = thread.readMemory(addr, thread.Process.arch.PtrSize())
|
val, err = thread.readMemory(addr, thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -559,7 +559,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
|
|||||||
for _, f := range t.Field {
|
for _, f := range t.Field {
|
||||||
switch f.Name {
|
switch f.Name {
|
||||||
case "array":
|
case "array":
|
||||||
val, err := thread.readMemory(addr+uintptr(f.ByteOffset), thread.Process.arch.PtrSize())
|
val, err := thread.readMemory(addr+uintptr(f.ByteOffset), thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -593,7 +593,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
|
|||||||
|
|
||||||
stride := arrayType.Size()
|
stride := arrayType.Size()
|
||||||
if _, ok := arrayType.(*dwarf.PtrType); ok {
|
if _, ok := arrayType.(*dwarf.PtrType); ok {
|
||||||
stride = int64(thread.Process.arch.PtrSize())
|
stride = int64(thread.dbp.arch.PtrSize())
|
||||||
}
|
}
|
||||||
vals, err := thread.readArrayValues(arrayAddr, sliceLen, stride, arrayType)
|
vals, err := thread.readArrayValues(arrayAddr, sliceLen, stride, arrayType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -729,7 +729,7 @@ func (thread *ThreadContext) readBool(addr uintptr) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
|
func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
|
||||||
val, err := thread.readMemory(addr, thread.Process.arch.PtrSize())
|
val, err := thread.readMemory(addr, thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -740,13 +740,13 @@ func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
|
|||||||
return "nil", nil
|
return "nil", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err = thread.readMemory(addr, thread.Process.arch.PtrSize())
|
val, err = thread.readMemory(addr, thread.dbp.arch.PtrSize())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
funcAddr := binary.LittleEndian.Uint64(val)
|
funcAddr := binary.LittleEndian.Uint64(val)
|
||||||
fn := thread.Process.goSymTable.PCToFunc(uint64(funcAddr))
|
fn := thread.dbp.goSymTable.PCToFunc(uint64(funcAddr))
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
return "", fmt.Errorf("could not find function for %#v", funcAddr)
|
return "", fmt.Errorf("could not find function for %#v", funcAddr)
|
||||||
}
|
}
|
||||||
@ -774,7 +774,7 @@ func (thread *ThreadContext) variablesByTag(tag dwarf.Tag) ([]*Variable, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := thread.Process.DwarfReader()
|
reader := thread.dbp.DwarfReader()
|
||||||
|
|
||||||
_, err = reader.SeekToFunction(pc)
|
_, err = reader.SeekToFunction(pc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -474,20 +474,24 @@ func convertBreakPoint(bp *proctl.BreakPoint) *api.BreakPoint {
|
|||||||
|
|
||||||
// convertThread converts an internal thread to an API Thread.
|
// convertThread converts an internal thread to an API Thread.
|
||||||
func convertThread(th *proctl.ThreadContext) *api.Thread {
|
func convertThread(th *proctl.ThreadContext) *api.Thread {
|
||||||
var function *api.Function
|
var (
|
||||||
file, line := "", 0
|
function *api.Function
|
||||||
|
file string
|
||||||
|
line int
|
||||||
|
pc uint64
|
||||||
|
)
|
||||||
|
|
||||||
pc, err := th.PC()
|
loc, err := th.Location()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
f, l, fn := th.Process.PCToLine(pc)
|
pc = loc.PC
|
||||||
file = f
|
file = loc.File
|
||||||
line = l
|
line = loc.Line
|
||||||
if fn != nil {
|
if loc.Fn != nil {
|
||||||
function = &api.Function{
|
function = &api.Function{
|
||||||
Name: fn.Name,
|
Name: loc.Fn.Name,
|
||||||
Type: fn.Type,
|
Type: loc.Fn.Type,
|
||||||
Value: fn.Value,
|
Value: loc.Fn.Value,
|
||||||
GoType: fn.GoType,
|
GoType: loc.Fn.GoType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user