proc: refactoring: merge target into proc
- moved target.Interface into proc as proc.Process - rename proc.IThread to proc.Thread - replaced interfaces DisassembleInfo, Continuable and EvalScopeConvertible with Process. - removed superfluous Gdbserver prefix from types in the gdbserial backend. - removed superfluous Core prefix from types in the core backend.
This commit is contained in:
parent
15bac71979
commit
b6fe5aebaf
@ -95,7 +95,7 @@ func (iae InvalidAddressError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CheckCondition evaluates bp's condition on thread.
|
// CheckCondition evaluates bp's condition on thread.
|
||||||
func (bp *Breakpoint) CheckCondition(thread IThread) (bool, error) {
|
func (bp *Breakpoint) CheckCondition(thread Thread) (bool, error) {
|
||||||
if bp.Cond == nil {
|
if bp.Cond == nil {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func (r *OffsetReaderAt) ReadMemory(buf []byte, addr uintptr) (n int, err error)
|
|||||||
return r.reader.ReadAt(buf, int64(addr-r.offset))
|
return r.reader.ReadAt(buf, int64(addr-r.offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
type CoreProcess struct {
|
type Process struct {
|
||||||
bi proc.BinaryInfo
|
bi proc.BinaryInfo
|
||||||
core *Core
|
core *Core
|
||||||
breakpoints map[uint64]*proc.Breakpoint
|
breakpoints map[uint64]*proc.Breakpoint
|
||||||
@ -151,21 +151,21 @@ type CoreProcess struct {
|
|||||||
allGCache []*proc.G
|
allGCache []*proc.G
|
||||||
}
|
}
|
||||||
|
|
||||||
type CoreThread struct {
|
type Thread struct {
|
||||||
th *LinuxPrStatus
|
th *LinuxPrStatus
|
||||||
p *CoreProcess
|
p *Process
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrWriteCore = errors.New("can not to core process")
|
var ErrWriteCore = errors.New("can not to core process")
|
||||||
var ErrShortRead = errors.New("short read")
|
var ErrShortRead = errors.New("short read")
|
||||||
var ErrContinueCore = errors.New("can not continue execution of core process")
|
var ErrContinueCore = errors.New("can not continue execution of core process")
|
||||||
|
|
||||||
func OpenCore(corePath, exePath string) (*CoreProcess, error) {
|
func OpenCore(corePath, exePath string) (*Process, error) {
|
||||||
core, err := readCore(corePath, exePath)
|
core, err := readCore(corePath, exePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p := &CoreProcess{
|
p := &Process{
|
||||||
core: core,
|
core: core,
|
||||||
breakpoints: make(map[uint64]*proc.Breakpoint),
|
breakpoints: make(map[uint64]*proc.Breakpoint),
|
||||||
bi: proc.NewBinaryInfo("linux", "amd64"),
|
bi: proc.NewBinaryInfo("linux", "amd64"),
|
||||||
@ -191,11 +191,11 @@ func OpenCore(corePath, exePath string) (*CoreProcess, error) {
|
|||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) BinInfo() *proc.BinaryInfo {
|
func (p *Process) BinInfo() *proc.BinaryInfo {
|
||||||
return &p.bi
|
return &p.bi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thread *CoreThread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
|
func (thread *Thread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
|
||||||
n, err = thread.p.core.ReadMemory(data, addr)
|
n, err = thread.p.core.ReadMemory(data, addr)
|
||||||
if err == nil && n != len(data) {
|
if err == nil && n != len(data) {
|
||||||
err = ErrShortRead
|
err = ErrShortRead
|
||||||
@ -203,121 +203,121 @@ func (thread *CoreThread) ReadMemory(data []byte, addr uintptr) (n int, err erro
|
|||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thread *CoreThread) WriteMemory(addr uintptr, data []byte) (int, error) {
|
func (thread *Thread) WriteMemory(addr uintptr, data []byte) (int, error) {
|
||||||
return 0, ErrWriteCore
|
return 0, ErrWriteCore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) Location() (*proc.Location, error) {
|
func (t *Thread) Location() (*proc.Location, error) {
|
||||||
f, l, fn := t.p.bi.PCToLine(t.th.Reg.Rip)
|
f, l, fn := t.p.bi.PCToLine(t.th.Reg.Rip)
|
||||||
return &proc.Location{PC: t.th.Reg.Rip, File: f, Line: l, Fn: fn}, nil
|
return &proc.Location{PC: t.th.Reg.Rip, File: f, Line: l, Fn: fn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) Breakpoint() (*proc.Breakpoint, bool, error) {
|
func (t *Thread) Breakpoint() (*proc.Breakpoint, bool, error) {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) ThreadID() int {
|
func (t *Thread) ThreadID() int {
|
||||||
return int(t.th.Pid)
|
return int(t.th.Pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) Registers(floatingPoint bool) (proc.Registers, error) {
|
func (t *Thread) Registers(floatingPoint bool) (proc.Registers, error) {
|
||||||
//TODO(aarzilli): handle floating point registers
|
//TODO(aarzilli): handle floating point registers
|
||||||
return &t.th.Reg, nil
|
return &t.th.Reg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) Arch() proc.Arch {
|
func (t *Thread) Arch() proc.Arch {
|
||||||
return t.p.bi.Arch
|
return t.p.bi.Arch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) BinInfo() *proc.BinaryInfo {
|
func (t *Thread) BinInfo() *proc.BinaryInfo {
|
||||||
return &t.p.bi
|
return &t.p.bi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) StepInstruction() error {
|
func (t *Thread) StepInstruction() error {
|
||||||
return ErrContinueCore
|
return ErrContinueCore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *CoreThread) Blocked() bool {
|
func (t *Thread) Blocked() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Breakpoints() map[uint64]*proc.Breakpoint {
|
func (p *Process) Breakpoints() map[uint64]*proc.Breakpoint {
|
||||||
return p.breakpoints
|
return p.breakpoints
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) ClearBreakpoint(addr uint64) (*proc.Breakpoint, error) {
|
func (p *Process) ClearBreakpoint(addr uint64) (*proc.Breakpoint, error) {
|
||||||
return nil, proc.NoBreakpointError{Addr: addr}
|
return nil, proc.NoBreakpointError{Addr: addr}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) ClearInternalBreakpoints() error {
|
func (p *Process) ClearInternalBreakpoints() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) ContinueOnce() (proc.IThread, error) {
|
func (p *Process) ContinueOnce() (proc.Thread, error) {
|
||||||
return nil, ErrContinueCore
|
return nil, ErrContinueCore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) StepInstruction() error {
|
func (p *Process) StepInstruction() error {
|
||||||
return ErrContinueCore
|
return ErrContinueCore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) RequestManualStop() error {
|
func (p *Process) RequestManualStop() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) CurrentThread() proc.IThread {
|
func (p *Process) CurrentThread() proc.Thread {
|
||||||
return &CoreThread{p.currentThread, p}
|
return &Thread{p.currentThread, p}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Detach(bool) error {
|
func (p *Process) Detach(bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Exited() bool {
|
func (p *Process) Exited() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) FindFileLocation(fileName string, lineNumber int) (uint64, error) {
|
func (p *Process) FindFileLocation(fileName string, lineNumber int) (uint64, error) {
|
||||||
return proc.FindFileLocation(p.CurrentThread(), p.breakpoints, &p.bi, fileName, lineNumber)
|
return proc.FindFileLocation(p.CurrentThread(), p.breakpoints, &p.bi, fileName, lineNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error) {
|
func (p *Process) FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error) {
|
||||||
return proc.FirstPCAfterPrologue(p.CurrentThread(), p.breakpoints, &p.bi, fn, sameline)
|
return proc.FirstPCAfterPrologue(p.CurrentThread(), p.breakpoints, &p.bi, fn, sameline)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) FindFunctionLocation(funcName string, firstLine bool, lineOffset int) (uint64, error) {
|
func (p *Process) FindFunctionLocation(funcName string, firstLine bool, lineOffset int) (uint64, error) {
|
||||||
return proc.FindFunctionLocation(p.CurrentThread(), p.breakpoints, &p.bi, funcName, firstLine, lineOffset)
|
return proc.FindFunctionLocation(p.CurrentThread(), p.breakpoints, &p.bi, funcName, firstLine, lineOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) AllGCache() *[]*proc.G {
|
func (p *Process) AllGCache() *[]*proc.G {
|
||||||
return &p.allGCache
|
return &p.allGCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Halt() error {
|
func (p *Process) Halt() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Kill() error {
|
func (p *Process) Kill() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Pid() int {
|
func (p *Process) Pid() int {
|
||||||
return p.core.Pid
|
return p.core.Pid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) Running() bool {
|
func (p *Process) Running() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) SelectedGoroutine() *proc.G {
|
func (p *Process) SelectedGoroutine() *proc.G {
|
||||||
return p.selectedGoroutine
|
return p.selectedGoroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) SetBreakpoint(addr uint64, kind proc.BreakpointKind, cond ast.Expr) (*proc.Breakpoint, error) {
|
func (p *Process) SetBreakpoint(addr uint64, kind proc.BreakpointKind, cond ast.Expr) (*proc.Breakpoint, error) {
|
||||||
return nil, ErrWriteCore
|
return nil, ErrWriteCore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) SwitchGoroutine(gid int) error {
|
func (p *Process) SwitchGoroutine(gid int) error {
|
||||||
g, err := proc.FindGoroutine(p, gid)
|
g, err := proc.FindGoroutine(p, gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -333,7 +333,7 @@ func (p *CoreProcess) SwitchGoroutine(gid int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) SwitchThread(tid int) error {
|
func (p *Process) SwitchThread(tid int) error {
|
||||||
if th, ok := p.core.Threads[tid]; ok {
|
if th, ok := p.core.Threads[tid]; ok {
|
||||||
p.currentThread = th
|
p.currentThread = th
|
||||||
p.selectedGoroutine, _ = proc.GetG(p.CurrentThread())
|
p.selectedGoroutine, _ = proc.GetG(p.CurrentThread())
|
||||||
@ -342,15 +342,15 @@ func (p *CoreProcess) SwitchThread(tid int) error {
|
|||||||
return fmt.Errorf("thread %d does not exist", tid)
|
return fmt.Errorf("thread %d does not exist", tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) ThreadList() []proc.IThread {
|
func (p *Process) ThreadList() []proc.Thread {
|
||||||
r := make([]proc.IThread, 0, len(p.core.Threads))
|
r := make([]proc.Thread, 0, len(p.core.Threads))
|
||||||
for _, v := range p.core.Threads {
|
for _, v := range p.core.Threads {
|
||||||
r = append(r, &CoreThread{v, p})
|
r = append(r, &Thread{v, p})
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *CoreProcess) FindThread(threadID int) (proc.IThread, bool) {
|
func (p *Process) FindThread(threadID int) (proc.Thread, bool) {
|
||||||
t, ok := p.core.Threads[threadID]
|
t, ok := p.core.Threads[threadID]
|
||||||
return &CoreThread{t, p}, ok
|
return &Thread{t, p}, ok
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ func (r *LinuxCoreRegisters) Get(n int) (uint64, error) {
|
|||||||
return 0, proc.UnknownRegisterError
|
return 0, proc.UnknownRegisterError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LinuxCoreRegisters) SetPC(proc.IThread, uint64) error {
|
func (r *LinuxCoreRegisters) SetPC(proc.Thread, uint64) error {
|
||||||
return errors.New("not supported")
|
return errors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,18 +16,11 @@ const (
|
|||||||
IntelFlavour
|
IntelFlavour
|
||||||
)
|
)
|
||||||
|
|
||||||
// DisassembleInfo is the subset of target.Interface used by Disassemble.
|
|
||||||
type DisassembleInfo interface {
|
|
||||||
CurrentThread() IThread
|
|
||||||
Breakpoints() map[uint64]*Breakpoint
|
|
||||||
BinInfo() *BinaryInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disassemble disassembles target memory between startPC and endPC, marking
|
// Disassemble disassembles target memory between startPC and endPC, marking
|
||||||
// the current instruction being executed in goroutine g.
|
// the current instruction being executed in goroutine g.
|
||||||
// If currentGoroutine is set and thread is stopped at a CALL instruction Disassemble will evaluate the argument of the CALL instruction using the thread's registers
|
// If currentGoroutine is set and thread is stopped at a CALL instruction Disassemble will evaluate the argument of the CALL instruction using the thread's registers
|
||||||
// Be aware that the Bytes field of each returned instruction is a slice of a larger array of size endPC - startPC
|
// Be aware that the Bytes field of each returned instruction is a slice of a larger array of size endPC - startPC
|
||||||
func Disassemble(dbp DisassembleInfo, g *G, startPC, endPC uint64) ([]AsmInstruction, error) {
|
func Disassemble(dbp Process, g *G, startPC, endPC uint64) ([]AsmInstruction, error) {
|
||||||
if g == nil {
|
if g == nil {
|
||||||
ct := dbp.CurrentThread()
|
ct := dbp.CurrentThread()
|
||||||
regs, _ := ct.Registers(false)
|
regs, _ := ct.Registers(false)
|
||||||
|
@ -93,14 +93,14 @@ const (
|
|||||||
|
|
||||||
const heartbeatInterval = 10 * time.Second
|
const heartbeatInterval = 10 * time.Second
|
||||||
|
|
||||||
// GdbserverProcess implements target.Interface using a connection to a
|
// Process implements proc.Process using a connection to a debugger stub
|
||||||
// debugger stub that understands Gdb Remote Serial Protocol.
|
// that understands Gdb Remote Serial Protocol.
|
||||||
type GdbserverProcess struct {
|
type Process struct {
|
||||||
bi proc.BinaryInfo
|
bi proc.BinaryInfo
|
||||||
conn gdbConn
|
conn gdbConn
|
||||||
|
|
||||||
threads map[int]*GdbserverThread
|
threads map[int]*Thread
|
||||||
currentThread *GdbserverThread
|
currentThread *Thread
|
||||||
selectedGoroutine *proc.G
|
selectedGoroutine *proc.G
|
||||||
|
|
||||||
exited bool
|
exited bool
|
||||||
@ -120,15 +120,15 @@ type GdbserverProcess struct {
|
|||||||
allGCache []*proc.G
|
allGCache []*proc.G
|
||||||
}
|
}
|
||||||
|
|
||||||
// GdbserverThread is a thread of GdbserverProcess.
|
// Thread is a thread.
|
||||||
type GdbserverThread struct {
|
type Thread struct {
|
||||||
ID int
|
ID int
|
||||||
strID string
|
strID string
|
||||||
regs gdbRegisters
|
regs gdbRegisters
|
||||||
CurrentBreakpoint *proc.Breakpoint
|
CurrentBreakpoint *proc.Breakpoint
|
||||||
BreakpointConditionMet bool
|
BreakpointConditionMet bool
|
||||||
BreakpointConditionError error
|
BreakpointConditionError error
|
||||||
p *GdbserverProcess
|
p *Process
|
||||||
setbp bool // thread was stopped because of a breakpoint
|
setbp bool // thread was stopped because of a breakpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,12 +150,12 @@ type gdbRegister struct {
|
|||||||
regnum int
|
regnum int
|
||||||
}
|
}
|
||||||
|
|
||||||
// GdbserverConnect creates a GdbserverProcess connected to address addr.
|
// Connect creates a GdbserverProcess connected to address addr.
|
||||||
// Path and pid are, respectively, the path to the executable of the target
|
// Path and pid are, respectively, the path to the executable of the target
|
||||||
// program and the PID of the target process, both are optional, however
|
// program and the PID of the target process, both are optional, however
|
||||||
// some stubs do not provide ways to determine path and pid automatically
|
// some stubs do not provide ways to determine path and pid automatically
|
||||||
// and GdbserverConnect will be unable to function without knowing them.
|
// and Connect will be unable to function without knowing them.
|
||||||
func GdbserverConnect(addr string, path string, pid int, attempts int) (*GdbserverProcess, error) {
|
func Connect(addr string, path string, pid int, attempts int) (*Process, error) {
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < attempts; i++ {
|
for i := 0; i < attempts; i++ {
|
||||||
@ -169,14 +169,14 @@ func GdbserverConnect(addr string, path string, pid int, attempts int) (*Gdbserv
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &GdbserverProcess{
|
p := &Process{
|
||||||
conn: gdbConn{
|
conn: gdbConn{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
maxTransmitAttempts: maxTransmitAttempts,
|
maxTransmitAttempts: maxTransmitAttempts,
|
||||||
inbuf: make([]byte, 0, initialInputBufferSize),
|
inbuf: make([]byte, 0, initialInputBufferSize),
|
||||||
},
|
},
|
||||||
|
|
||||||
threads: make(map[int]*GdbserverThread),
|
threads: make(map[int]*Thread),
|
||||||
bi: proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH),
|
bi: proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH),
|
||||||
breakpoints: make(map[uint64]*proc.Breakpoint),
|
breakpoints: make(map[uint64]*proc.Breakpoint),
|
||||||
gcmdok: true,
|
gcmdok: true,
|
||||||
@ -296,7 +296,7 @@ const debugserverExecutable = "/Library/Developer/CommandLineTools/Library/Priva
|
|||||||
// LLDBLaunch starts an instance of lldb-server and connects to it, asking
|
// LLDBLaunch starts an instance of lldb-server and connects to it, asking
|
||||||
// it to launch the specified target program with the specified arguments
|
// it to launch the specified target program with the specified arguments
|
||||||
// (cmd) on the specified directory wd.
|
// (cmd) on the specified directory wd.
|
||||||
func LLDBLaunch(cmd []string, wd string) (*GdbserverProcess, error) {
|
func LLDBLaunch(cmd []string, wd string) (*Process, error) {
|
||||||
// check that the argument to Launch is an executable file
|
// check that the argument to Launch is an executable file
|
||||||
if fi, staterr := os.Stat(cmd[0]); staterr == nil && (fi.Mode()&0111) == 0 {
|
if fi, staterr := os.Stat(cmd[0]); staterr == nil && (fi.Mode()&0111) == 0 {
|
||||||
return nil, proc.NotExecutableErr
|
return nil, proc.NotExecutableErr
|
||||||
@ -338,7 +338,7 @@ func LLDBLaunch(cmd []string, wd string) (*GdbserverProcess, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := GdbserverConnect(port, cmd[0], 0, 10)
|
p, err := Connect(port, cmd[0], 0, 10)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ func LLDBLaunch(cmd []string, wd string) (*GdbserverProcess, error) {
|
|||||||
// Path is path to the target's executable, path only needs to be specified
|
// Path is path to the target's executable, path only needs to be specified
|
||||||
// for some stubs that do not provide an automated way of determining it
|
// for some stubs that do not provide an automated way of determining it
|
||||||
// (for example debugserver).
|
// (for example debugserver).
|
||||||
func LLDBAttach(pid int, path string) (*GdbserverProcess, error) {
|
func LLDBAttach(pid int, path string) (*Process, error) {
|
||||||
port := unusedPort()
|
port := unusedPort()
|
||||||
isDebugserver := false
|
isDebugserver := false
|
||||||
var proc *exec.Cmd
|
var proc *exec.Cmd
|
||||||
@ -375,7 +375,7 @@ func LLDBAttach(pid int, path string) (*GdbserverProcess, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := GdbserverConnect(port, path, pid, 10)
|
p, err := Connect(port, path, pid, 10)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -389,7 +389,7 @@ func LLDBAttach(pid int, path string) (*GdbserverProcess, error) {
|
|||||||
// loadProcessInfo uses qProcessInfo to load the inferior's PID and
|
// loadProcessInfo uses qProcessInfo to load the inferior's PID and
|
||||||
// executable path. This command is not supported by all stubs and not all
|
// executable path. This command is not supported by all stubs and not all
|
||||||
// stubs will report both the PID and executable path.
|
// stubs will report both the PID and executable path.
|
||||||
func (p *GdbserverProcess) loadProcessInfo(pid int) (int, string, error) {
|
func (p *Process) loadProcessInfo(pid int) (int, string, error) {
|
||||||
pi, err := p.conn.queryProcessInfo(pid)
|
pi, err := p.conn.queryProcessInfo(pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, "", err
|
return 0, "", err
|
||||||
@ -401,56 +401,56 @@ func (p *GdbserverProcess) loadProcessInfo(pid int) (int, string, error) {
|
|||||||
return pid, pi["name"], nil
|
return pid, pi["name"], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) BinInfo() *proc.BinaryInfo {
|
func (p *Process) BinInfo() *proc.BinaryInfo {
|
||||||
return &p.bi
|
return &p.bi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Pid() int {
|
func (p *Process) Pid() int {
|
||||||
return int(p.conn.pid)
|
return int(p.conn.pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Exited() bool {
|
func (p *Process) Exited() bool {
|
||||||
return p.exited
|
return p.exited
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Running() bool {
|
func (p *Process) Running() bool {
|
||||||
return p.conn.running
|
return p.conn.running
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) FindFileLocation(fileName string, lineNumber int) (uint64, error) {
|
func (p *Process) FindFileLocation(fileName string, lineNumber int) (uint64, error) {
|
||||||
return proc.FindFileLocation(p.CurrentThread(), p.breakpoints, &p.bi, fileName, lineNumber)
|
return proc.FindFileLocation(p.CurrentThread(), p.breakpoints, &p.bi, fileName, lineNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error) {
|
func (p *Process) FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error) {
|
||||||
return proc.FirstPCAfterPrologue(p.CurrentThread(), p.breakpoints, &p.bi, fn, sameline)
|
return proc.FirstPCAfterPrologue(p.CurrentThread(), p.breakpoints, &p.bi, fn, sameline)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) FindFunctionLocation(funcName string, firstLine bool, lineOffset int) (uint64, error) {
|
func (p *Process) FindFunctionLocation(funcName string, firstLine bool, lineOffset int) (uint64, error) {
|
||||||
return proc.FindFunctionLocation(p.CurrentThread(), p.breakpoints, &p.bi, funcName, firstLine, lineOffset)
|
return proc.FindFunctionLocation(p.CurrentThread(), p.breakpoints, &p.bi, funcName, firstLine, lineOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) FindThread(threadID int) (proc.IThread, bool) {
|
func (p *Process) FindThread(threadID int) (proc.Thread, bool) {
|
||||||
thread, ok := p.threads[threadID]
|
thread, ok := p.threads[threadID]
|
||||||
return thread, ok
|
return thread, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) ThreadList() []proc.IThread {
|
func (p *Process) ThreadList() []proc.Thread {
|
||||||
r := make([]proc.IThread, 0, len(p.threads))
|
r := make([]proc.Thread, 0, len(p.threads))
|
||||||
for _, thread := range p.threads {
|
for _, thread := range p.threads {
|
||||||
r = append(r, thread)
|
r = append(r, thread)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) CurrentThread() proc.IThread {
|
func (p *Process) CurrentThread() proc.Thread {
|
||||||
return p.currentThread
|
return p.currentThread
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) AllGCache() *[]*proc.G {
|
func (p *Process) AllGCache() *[]*proc.G {
|
||||||
return &p.allGCache
|
return &p.allGCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) SelectedGoroutine() *proc.G {
|
func (p *Process) SelectedGoroutine() *proc.G {
|
||||||
return p.selectedGoroutine
|
return p.selectedGoroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ const (
|
|||||||
stopSignal = 0x13
|
stopSignal = 0x13
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *GdbserverProcess) ContinueOnce() (proc.IThread, error) {
|
func (p *Process) ContinueOnce() (proc.Thread, error) {
|
||||||
if p.exited {
|
if p.exited {
|
||||||
return nil, &proc.ProcessExitedError{Pid: p.conn.pid}
|
return nil, &proc.ProcessExitedError{Pid: p.conn.pid}
|
||||||
}
|
}
|
||||||
@ -544,7 +544,7 @@ continueLoop:
|
|||||||
return nil, fmt.Errorf("could not find thread %s", threadID)
|
return nil, fmt.Errorf("could not find thread %s", threadID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) StepInstruction() error {
|
func (p *Process) StepInstruction() error {
|
||||||
if p.selectedGoroutine == nil {
|
if p.selectedGoroutine == nil {
|
||||||
return errors.New("cannot single step: no selected goroutine")
|
return errors.New("cannot single step: no selected goroutine")
|
||||||
}
|
}
|
||||||
@ -558,15 +558,15 @@ func (p *GdbserverProcess) StepInstruction() error {
|
|||||||
if p.exited {
|
if p.exited {
|
||||||
return &proc.ProcessExitedError{Pid: p.conn.pid}
|
return &proc.ProcessExitedError{Pid: p.conn.pid}
|
||||||
}
|
}
|
||||||
p.selectedGoroutine.Thread.(*GdbserverThread).clearBreakpointState()
|
p.selectedGoroutine.Thread.(*Thread).clearBreakpointState()
|
||||||
err := p.selectedGoroutine.Thread.(*GdbserverThread).StepInstruction()
|
err := p.selectedGoroutine.Thread.(*Thread).StepInstruction()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return p.selectedGoroutine.Thread.(*GdbserverThread).SetCurrentBreakpoint()
|
return p.selectedGoroutine.Thread.(*Thread).SetCurrentBreakpoint()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) SwitchThread(tid int) error {
|
func (p *Process) SwitchThread(tid int) error {
|
||||||
if th, ok := p.threads[tid]; ok {
|
if th, ok := p.threads[tid]; ok {
|
||||||
p.currentThread = th
|
p.currentThread = th
|
||||||
p.selectedGoroutine, _ = proc.GetG(p.CurrentThread())
|
p.selectedGoroutine, _ = proc.GetG(p.CurrentThread())
|
||||||
@ -575,7 +575,7 @@ func (p *GdbserverProcess) SwitchThread(tid int) error {
|
|||||||
return fmt.Errorf("thread %d does not exist", tid)
|
return fmt.Errorf("thread %d does not exist", tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) SwitchGoroutine(gid int) error {
|
func (p *Process) SwitchGoroutine(gid int) error {
|
||||||
g, err := proc.FindGoroutine(p, gid)
|
g, err := proc.FindGoroutine(p, gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -591,17 +591,17 @@ func (p *GdbserverProcess) SwitchGoroutine(gid int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) RequestManualStop() error {
|
func (p *Process) RequestManualStop() error {
|
||||||
p.ctrlC = true
|
p.ctrlC = true
|
||||||
return p.conn.sendCtrlC()
|
return p.conn.sendCtrlC()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Halt() error {
|
func (p *Process) Halt() error {
|
||||||
p.ctrlC = true
|
p.ctrlC = true
|
||||||
return p.conn.sendCtrlC()
|
return p.conn.sendCtrlC()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Kill() error {
|
func (p *Process) Kill() error {
|
||||||
if p.exited {
|
if p.exited {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -613,7 +613,7 @@ func (p *GdbserverProcess) Kill() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Detach(kill bool) error {
|
func (p *Process) Detach(kill bool) error {
|
||||||
if kill {
|
if kill {
|
||||||
if err := p.Kill(); err != nil {
|
if err := p.Kill(); err != nil {
|
||||||
if _, exited := err.(proc.ProcessExitedError); !exited {
|
if _, exited := err.(proc.ProcessExitedError); !exited {
|
||||||
@ -633,11 +633,11 @@ func (p *GdbserverProcess) Detach(kill bool) error {
|
|||||||
return p.bi.Close()
|
return p.bi.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) Breakpoints() map[uint64]*proc.Breakpoint {
|
func (p *Process) Breakpoints() map[uint64]*proc.Breakpoint {
|
||||||
return p.breakpoints
|
return p.breakpoints
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) {
|
func (p *Process) FindBreakpoint(pc uint64) (*proc.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 := p.breakpoints[pc-uint64(p.bi.Arch.BreakpointSize())]; ok {
|
if bp, ok := p.breakpoints[pc-uint64(p.bi.Arch.BreakpointSize())]; ok {
|
||||||
return bp, true
|
return bp, true
|
||||||
@ -649,7 +649,7 @@ func (p *GdbserverProcess) FindBreakpoint(pc uint64) (*proc.Breakpoint, bool) {
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) SetBreakpoint(addr uint64, kind proc.BreakpointKind, cond ast.Expr) (*proc.Breakpoint, error) {
|
func (p *Process) SetBreakpoint(addr uint64, kind proc.BreakpointKind, cond ast.Expr) (*proc.Breakpoint, error) {
|
||||||
if bp, ok := p.breakpoints[addr]; ok {
|
if bp, ok := p.breakpoints[addr]; ok {
|
||||||
return nil, proc.BreakpointExistsError{bp.File, bp.Line, bp.Addr}
|
return nil, proc.BreakpointExistsError{bp.File, bp.Line, bp.Addr}
|
||||||
}
|
}
|
||||||
@ -683,7 +683,7 @@ func (p *GdbserverProcess) SetBreakpoint(addr uint64, kind proc.BreakpointKind,
|
|||||||
return newBreakpoint, nil
|
return newBreakpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) ClearBreakpoint(addr uint64) (*proc.Breakpoint, error) {
|
func (p *Process) ClearBreakpoint(addr uint64) (*proc.Breakpoint, error) {
|
||||||
if p.exited {
|
if p.exited {
|
||||||
return nil, &proc.ProcessExitedError{Pid: p.conn.pid}
|
return nil, &proc.ProcessExitedError{Pid: p.conn.pid}
|
||||||
}
|
}
|
||||||
@ -701,7 +701,7 @@ func (p *GdbserverProcess) ClearBreakpoint(addr uint64) (*proc.Breakpoint, error
|
|||||||
return bp, nil
|
return bp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) ClearInternalBreakpoints() error {
|
func (p *Process) ClearInternalBreakpoints() error {
|
||||||
for _, bp := range p.breakpoints {
|
for _, bp := range p.breakpoints {
|
||||||
if !bp.Internal() {
|
if !bp.Internal() {
|
||||||
continue
|
continue
|
||||||
@ -719,7 +719,7 @@ func (p *GdbserverProcess) ClearInternalBreakpoints() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type threadUpdater struct {
|
type threadUpdater struct {
|
||||||
p *GdbserverProcess
|
p *Process
|
||||||
seen map[int]bool
|
seen map[int]bool
|
||||||
done bool
|
done bool
|
||||||
}
|
}
|
||||||
@ -743,7 +743,7 @@ func (tu *threadUpdater) Add(threads []string) error {
|
|||||||
tid := int(n)
|
tid := int(n)
|
||||||
tu.seen[tid] = true
|
tu.seen[tid] = true
|
||||||
if _, found := tu.p.threads[tid]; !found {
|
if _, found := tu.p.threads[tid]; !found {
|
||||||
tu.p.threads[tid] = &GdbserverThread{ID: tid, strID: threadID, p: tu.p}
|
tu.p.threads[tid] = &Thread{ID: tid, strID: threadID, p: tu.p}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -776,7 +776,7 @@ func (tu *threadUpdater) Finish() {
|
|||||||
// this happens the threadUpdater will know that we have already updated the
|
// this happens the threadUpdater will know that we have already updated the
|
||||||
// thread list and the first step of updateThreadList will be skipped.
|
// thread list and the first step of updateThreadList will be skipped.
|
||||||
// Registers are always reloaded.
|
// Registers are always reloaded.
|
||||||
func (p *GdbserverProcess) updateThreadList(tu *threadUpdater) error {
|
func (p *Process) updateThreadList(tu *threadUpdater) error {
|
||||||
if !tu.done {
|
if !tu.done {
|
||||||
first := true
|
first := true
|
||||||
for {
|
for {
|
||||||
@ -818,7 +818,7 @@ func (p *GdbserverProcess) updateThreadList(tu *threadUpdater) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GdbserverProcess) setCurrentBreakpoints() error {
|
func (p *Process) setCurrentBreakpoints() error {
|
||||||
if p.threadStopInfo {
|
if p.threadStopInfo {
|
||||||
for _, th := range p.threads {
|
for _, th := range p.threads {
|
||||||
if th.setbp {
|
if th.setbp {
|
||||||
@ -842,7 +842,7 @@ func (p *GdbserverProcess) setCurrentBreakpoints() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
|
func (t *Thread) ReadMemory(data []byte, addr uintptr) (n int, err error) {
|
||||||
err = t.p.conn.readMemory(data, addr)
|
err = t.p.conn.readMemory(data, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -850,11 +850,11 @@ func (t *GdbserverThread) ReadMemory(data []byte, addr uintptr) (n int, err erro
|
|||||||
return len(data), nil
|
return len(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) WriteMemory(addr uintptr, data []byte) (written int, err error) {
|
func (t *Thread) WriteMemory(addr uintptr, data []byte) (written int, err error) {
|
||||||
return t.p.conn.writeMemory(addr, data)
|
return t.p.conn.writeMemory(addr, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) Location() (*proc.Location, error) {
|
func (t *Thread) Location() (*proc.Location, error) {
|
||||||
regs, err := t.Registers(false)
|
regs, err := t.Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -864,27 +864,27 @@ func (t *GdbserverThread) Location() (*proc.Location, error) {
|
|||||||
return &proc.Location{PC: pc, File: f, Line: l, Fn: fn}, nil
|
return &proc.Location{PC: pc, File: f, Line: l, Fn: fn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) Breakpoint() (breakpoint *proc.Breakpoint, active bool, condErr error) {
|
func (t *Thread) Breakpoint() (breakpoint *proc.Breakpoint, active bool, condErr error) {
|
||||||
return t.CurrentBreakpoint, (t.CurrentBreakpoint != nil && t.BreakpointConditionMet), t.BreakpointConditionError
|
return t.CurrentBreakpoint, (t.CurrentBreakpoint != nil && t.BreakpointConditionMet), t.BreakpointConditionError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) ThreadID() int {
|
func (t *Thread) ThreadID() int {
|
||||||
return t.ID
|
return t.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) Registers(floatingPoint bool) (proc.Registers, error) {
|
func (t *Thread) Registers(floatingPoint bool) (proc.Registers, error) {
|
||||||
return &t.regs, nil
|
return &t.regs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) Arch() proc.Arch {
|
func (t *Thread) Arch() proc.Arch {
|
||||||
return t.p.bi.Arch
|
return t.p.bi.Arch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) BinInfo() *proc.BinaryInfo {
|
func (t *Thread) BinInfo() *proc.BinaryInfo {
|
||||||
return &t.p.bi
|
return &t.p.bi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) stepInstruction(tu *threadUpdater) error {
|
func (t *Thread) stepInstruction(tu *threadUpdater) error {
|
||||||
pc := t.regs.PC()
|
pc := t.regs.PC()
|
||||||
if _, atbp := t.p.breakpoints[pc]; atbp {
|
if _, atbp := t.p.breakpoints[pc]; atbp {
|
||||||
err := t.p.conn.clearBreakpoint(pc)
|
err := t.p.conn.clearBreakpoint(pc)
|
||||||
@ -897,14 +897,14 @@ func (t *GdbserverThread) stepInstruction(tu *threadUpdater) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) StepInstruction() error {
|
func (t *Thread) StepInstruction() error {
|
||||||
if err := t.stepInstruction(&threadUpdater{p: t.p}); err != nil {
|
if err := t.stepInstruction(&threadUpdater{p: t.p}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return t.reloadRegisters()
|
return t.reloadRegisters()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) Blocked() bool {
|
func (t *Thread) Blocked() bool {
|
||||||
regs, err := t.Registers(false)
|
regs, err := t.Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -928,7 +928,7 @@ func (t *GdbserverThread) Blocked() bool {
|
|||||||
// loadGInstr returns the correct MOV instruction for the current
|
// loadGInstr returns the correct MOV instruction for the current
|
||||||
// OS/architecture that can be executed to load the address of G from an
|
// OS/architecture that can be executed to load the address of G from an
|
||||||
// inferior's thread.
|
// inferior's thread.
|
||||||
func (p *GdbserverProcess) loadGInstr() []byte {
|
func (p *Process) loadGInstr() []byte {
|
||||||
switch p.bi.GOOS {
|
switch p.bi.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
//TODO(aarzilli): implement
|
//TODO(aarzilli): implement
|
||||||
@ -956,7 +956,7 @@ func (p *GdbserverProcess) loadGInstr() []byte {
|
|||||||
// It will also load the address of the thread's G.
|
// It will also load the address of the thread's G.
|
||||||
// Loading the address of G can be done in one of two ways reloadGAlloc, if
|
// Loading the address of G can be done in one of two ways reloadGAlloc, if
|
||||||
// the stub can allocate memory, or reloadGAtPC, if the stub can't.
|
// the stub can allocate memory, or reloadGAtPC, if the stub can't.
|
||||||
func (t *GdbserverThread) reloadRegisters() error {
|
func (t *Thread) reloadRegisters() error {
|
||||||
if t.regs.regs == nil {
|
if t.regs.regs == nil {
|
||||||
t.regs.regs = make(map[string]gdbRegister)
|
t.regs.regs = make(map[string]gdbRegister)
|
||||||
t.regs.regsInfo = t.p.conn.regsInfo
|
t.regs.regsInfo = t.p.conn.regsInfo
|
||||||
@ -996,7 +996,7 @@ func (t *GdbserverThread) reloadRegisters() error {
|
|||||||
return t.reloadGAtPC()
|
return t.reloadGAtPC()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) writeSomeRegisters(regNames ...string) error {
|
func (t *Thread) writeSomeRegisters(regNames ...string) error {
|
||||||
if t.p.gcmdok {
|
if t.p.gcmdok {
|
||||||
return t.p.conn.writeRegisters(t.strID, t.regs.buf)
|
return t.p.conn.writeRegisters(t.strID, t.regs.buf)
|
||||||
}
|
}
|
||||||
@ -1008,7 +1008,7 @@ func (t *GdbserverThread) writeSomeRegisters(regNames ...string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) readSomeRegisters(regNames ...string) error {
|
func (t *Thread) readSomeRegisters(regNames ...string) error {
|
||||||
if t.p.gcmdok {
|
if t.p.gcmdok {
|
||||||
return t.p.conn.readRegisters(t.strID, t.regs.buf)
|
return t.p.conn.readRegisters(t.strID, t.regs.buf)
|
||||||
}
|
}
|
||||||
@ -1024,7 +1024,7 @@ func (t *GdbserverThread) readSomeRegisters(regNames ...string) error {
|
|||||||
// reloadGAtPC overwrites the instruction that the thread is stopped at with
|
// reloadGAtPC overwrites the instruction that the thread is stopped at with
|
||||||
// the MOV instruction used to load current G, executes this single
|
// the MOV instruction used to load current G, executes this single
|
||||||
// instruction and then puts everything back the way it was.
|
// instruction and then puts everything back the way it was.
|
||||||
func (t *GdbserverThread) reloadGAtPC() error {
|
func (t *Thread) reloadGAtPC() error {
|
||||||
movinstr := t.p.loadGInstr()
|
movinstr := t.p.loadGInstr()
|
||||||
|
|
||||||
if t.Blocked() {
|
if t.Blocked() {
|
||||||
@ -1098,7 +1098,7 @@ func (t *GdbserverThread) reloadGAtPC() error {
|
|||||||
// t.p.loadGInstrAddr must point to valid memory on the inferior, containing
|
// t.p.loadGInstrAddr must point to valid memory on the inferior, containing
|
||||||
// a MOV instruction that loads the address of the current G in the RCX
|
// a MOV instruction that loads the address of the current G in the RCX
|
||||||
// register.
|
// register.
|
||||||
func (t *GdbserverThread) reloadGAlloc() error {
|
func (t *Thread) reloadGAlloc() error {
|
||||||
if t.Blocked() {
|
if t.Blocked() {
|
||||||
t.regs.tls = 0
|
t.regs.tls = 0
|
||||||
t.regs.gaddr = 0
|
t.regs.gaddr = 0
|
||||||
@ -1140,14 +1140,14 @@ func (t *GdbserverThread) reloadGAlloc() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *GdbserverThread) clearBreakpointState() {
|
func (t *Thread) clearBreakpointState() {
|
||||||
t.setbp = false
|
t.setbp = false
|
||||||
t.CurrentBreakpoint = nil
|
t.CurrentBreakpoint = nil
|
||||||
t.BreakpointConditionMet = false
|
t.BreakpointConditionMet = false
|
||||||
t.BreakpointConditionError = nil
|
t.BreakpointConditionError = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thread *GdbserverThread) SetCurrentBreakpoint() error {
|
func (thread *Thread) SetCurrentBreakpoint() error {
|
||||||
thread.CurrentBreakpoint = nil
|
thread.CurrentBreakpoint = nil
|
||||||
regs, err := thread.Registers(false)
|
regs, err := thread.Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1369,9 +1369,9 @@ func (regs *gdbRegisters) Get(n int) (uint64, error) {
|
|||||||
return 0, proc.UnknownRegisterError
|
return 0, proc.UnknownRegisterError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (regs *gdbRegisters) SetPC(thread proc.IThread, pc uint64) error {
|
func (regs *gdbRegisters) SetPC(thread proc.Thread, pc uint64) error {
|
||||||
regs.setPC(pc)
|
regs.setPC(pc)
|
||||||
t := thread.(*GdbserverThread)
|
t := thread.(*Thread)
|
||||||
if t.p.gcmdok {
|
if t.p.gcmdok {
|
||||||
return t.p.conn.writeRegisters(t.strID, t.regs.buf)
|
return t.p.conn.writeRegisters(t.strID, t.regs.buf)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
package target
|
package proc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"debug/gosym"
|
"debug/gosym"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
|
||||||
"github.com/derekparker/delve/pkg/proc"
|
|
||||||
"github.com/derekparker/delve/pkg/proc/core"
|
|
||||||
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
|
||||||
"github.com/derekparker/delve/pkg/proc/native"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Target represents the target of the debugger. This
|
// Process represents the target of the debugger. This
|
||||||
// target could be a system process, core file, etc.
|
// target could be a system process, core file, etc.
|
||||||
type Interface interface {
|
type Process interface {
|
||||||
Info
|
Info
|
||||||
ProcessManipulation
|
ProcessManipulation
|
||||||
BreakpointManipulation
|
BreakpointManipulation
|
||||||
@ -23,7 +18,7 @@ type Info interface {
|
|||||||
Pid() int
|
Pid() int
|
||||||
Exited() bool
|
Exited() bool
|
||||||
Running() bool
|
Running() bool
|
||||||
BinInfo() *proc.BinaryInfo
|
BinInfo() *BinaryInfo
|
||||||
|
|
||||||
ThreadInfo
|
ThreadInfo
|
||||||
GoroutineInfo
|
GoroutineInfo
|
||||||
@ -56,19 +51,19 @@ type Info interface {
|
|||||||
// ThreadInfo is an interface for getting information on active threads
|
// ThreadInfo is an interface for getting information on active threads
|
||||||
// in the process.
|
// in the process.
|
||||||
type ThreadInfo interface {
|
type ThreadInfo interface {
|
||||||
FindThread(threadID int) (proc.IThread, bool)
|
FindThread(threadID int) (Thread, bool)
|
||||||
ThreadList() []proc.IThread
|
ThreadList() []Thread
|
||||||
CurrentThread() proc.IThread
|
CurrentThread() Thread
|
||||||
}
|
}
|
||||||
|
|
||||||
// GoroutineInfo is an interface for getting information on running goroutines.
|
// GoroutineInfo is an interface for getting information on running goroutines.
|
||||||
type GoroutineInfo interface {
|
type GoroutineInfo interface {
|
||||||
SelectedGoroutine() *proc.G
|
SelectedGoroutine() *G
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessManipulation is an interface for changing the execution state of a process.
|
// ProcessManipulation is an interface for changing the execution state of a process.
|
||||||
type ProcessManipulation interface {
|
type ProcessManipulation interface {
|
||||||
ContinueOnce() (trapthread proc.IThread, err error)
|
ContinueOnce() (trapthread Thread, err error)
|
||||||
StepInstruction() error
|
StepInstruction() error
|
||||||
SwitchThread(int) error
|
SwitchThread(int) error
|
||||||
SwitchGoroutine(int) error
|
SwitchGoroutine(int) error
|
||||||
@ -80,18 +75,14 @@ type ProcessManipulation interface {
|
|||||||
|
|
||||||
// BreakpointManipulation is an interface for managing breakpoints.
|
// BreakpointManipulation is an interface for managing breakpoints.
|
||||||
type BreakpointManipulation interface {
|
type BreakpointManipulation interface {
|
||||||
Breakpoints() map[uint64]*proc.Breakpoint
|
Breakpoints() map[uint64]*Breakpoint
|
||||||
SetBreakpoint(addr uint64, kind proc.BreakpointKind, cond ast.Expr) (*proc.Breakpoint, error)
|
SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Expr) (*Breakpoint, error)
|
||||||
ClearBreakpoint(addr uint64) (*proc.Breakpoint, error)
|
ClearBreakpoint(addr uint64) (*Breakpoint, error)
|
||||||
ClearInternalBreakpoints() error
|
ClearInternalBreakpoints() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// VariableEval is an interface for dealing with eval scopes.
|
// VariableEval is an interface for dealing with eval scopes.
|
||||||
type VariableEval interface {
|
type VariableEval interface {
|
||||||
FrameToScope(proc.Stackframe) *proc.EvalScope
|
FrameToScope(Stackframe) *EvalScope
|
||||||
ConvertEvalScope(gid, frame int) (*proc.EvalScope, error)
|
ConvertEvalScope(gid, frame int) (*EvalScope, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Interface = &native.Process{}
|
|
||||||
var _ Interface = &core.CoreProcess{}
|
|
||||||
var _ Interface = &gdbserial.GdbserverProcess{}
|
|
@ -126,20 +126,20 @@ func (dbp *Process) SelectedGoroutine() *proc.G {
|
|||||||
return dbp.selectedGoroutine
|
return dbp.selectedGoroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *Process) ThreadList() []proc.IThread {
|
func (dbp *Process) ThreadList() []proc.Thread {
|
||||||
r := make([]proc.IThread, 0, len(dbp.threads))
|
r := make([]proc.Thread, 0, len(dbp.threads))
|
||||||
for _, v := range dbp.threads {
|
for _, v := range dbp.threads {
|
||||||
r = append(r, v)
|
r = append(r, v)
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *Process) FindThread(threadID int) (proc.IThread, bool) {
|
func (dbp *Process) FindThread(threadID int) (proc.Thread, bool) {
|
||||||
th, ok := dbp.threads[threadID]
|
th, ok := dbp.threads[threadID]
|
||||||
return th, ok
|
return th, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *Process) CurrentThread() proc.IThread {
|
func (dbp *Process) CurrentThread() proc.Thread {
|
||||||
return dbp.currentThread
|
return dbp.currentThread
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ func (dbp *Process) Status() *WaitStatus {
|
|||||||
return dbp.currentThread.Status
|
return dbp.currentThread.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *Process) ContinueOnce() (proc.IThread, error) {
|
func (dbp *Process) ContinueOnce() (proc.Thread, error) {
|
||||||
if dbp.exited {
|
if dbp.exited {
|
||||||
return nil, &proc.ProcessExitedError{}
|
return nil, &proc.ProcessExitedError{}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ func (r *Regs) GAddr() (uint64, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetPC sets the RIP register to the value specified by `pc`.
|
// SetPC sets the RIP register to the value specified by `pc`.
|
||||||
func (r *Regs) SetPC(t proc.IThread, pc uint64) error {
|
func (r *Regs) SetPC(t proc.Thread, pc uint64) error {
|
||||||
thread := t.(*Thread)
|
thread := t.(*Thread)
|
||||||
kret := C.set_pc(thread.os.threadAct, C.uint64_t(pc))
|
kret := C.set_pc(thread.os.threadAct, C.uint64_t(pc))
|
||||||
if kret != C.KERN_SUCCESS {
|
if kret != C.KERN_SUCCESS {
|
||||||
|
@ -90,7 +90,7 @@ func (r *Regs) GAddr() (uint64, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetPC sets RIP to the value specified by 'pc'.
|
// SetPC sets RIP to the value specified by 'pc'.
|
||||||
func (r *Regs) SetPC(t proc.IThread, pc uint64) (err error) {
|
func (r *Regs) SetPC(t proc.Thread, pc uint64) (err error) {
|
||||||
thread := t.(*Thread)
|
thread := t.(*Thread)
|
||||||
r.regs.SetPC(pc)
|
r.regs.SetPC(pc)
|
||||||
thread.dbp.execPtraceFunc(func() { err = sys.PtraceSetRegs(thread.ID, r.regs) })
|
thread.dbp.execPtraceFunc(func() { err = sys.PtraceSetRegs(thread.ID, r.regs) })
|
||||||
|
@ -131,7 +131,7 @@ func (r *Regs) GAddr() (uint64, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetPC sets the RIP register to the value specified by `pc`.
|
// SetPC sets the RIP register to the value specified by `pc`.
|
||||||
func (r *Regs) SetPC(t proc.IThread, pc uint64) error {
|
func (r *Regs) SetPC(t proc.Thread, pc uint64) error {
|
||||||
thread := t.(*Thread)
|
thread := t.(*Thread)
|
||||||
context := newCONTEXT()
|
context := newCONTEXT()
|
||||||
context.ContextFlags = _CONTEXT_ALL
|
context.ContextFlags = _CONTEXT_ALL
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package proc
|
package proc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"debug/gosym"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -70,7 +69,7 @@ func FindFunctionLocation(mem MemoryReadWriter, breakpoints map[uint64]*Breakpoi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next continues execution until the next source line.
|
// Next continues execution until the next source line.
|
||||||
func Next(dbp Continuable) (err error) {
|
func Next(dbp Process) (err error) {
|
||||||
if dbp.Exited() {
|
if dbp.Exited() {
|
||||||
return &ProcessExitedError{}
|
return &ProcessExitedError{}
|
||||||
}
|
}
|
||||||
@ -92,26 +91,10 @@ func Next(dbp Continuable) (err error) {
|
|||||||
return Continue(dbp)
|
return Continue(dbp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continuable is the subinterface of target.Interface used to implement
|
|
||||||
// Continue/Next/etc.
|
|
||||||
type Continuable interface {
|
|
||||||
ContinueOnce() (trapthread IThread, err error)
|
|
||||||
CurrentThread() IThread
|
|
||||||
SelectedGoroutine() *G
|
|
||||||
Breakpoints() map[uint64]*Breakpoint
|
|
||||||
ThreadList() []IThread
|
|
||||||
SwitchThread(int) error
|
|
||||||
BinInfo() *BinaryInfo
|
|
||||||
ClearInternalBreakpoints() error
|
|
||||||
FirstPCAfterPrologue(fn *gosym.Func, sameline bool) (uint64, error)
|
|
||||||
SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Expr) (*Breakpoint, error)
|
|
||||||
Exited() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue continues execution of the debugged
|
// Continue continues execution of the debugged
|
||||||
// process. It will continue until it hits a breakpoint
|
// process. It will continue until it hits a breakpoint
|
||||||
// or is otherwise stopped.
|
// or is otherwise stopped.
|
||||||
func Continue(dbp Continuable) error {
|
func Continue(dbp Process) error {
|
||||||
for {
|
for {
|
||||||
trapthread, err := dbp.ContinueOnce()
|
trapthread, err := dbp.ContinueOnce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -191,7 +174,7 @@ func Continue(dbp Continuable) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func conditionErrors(threads []IThread) error {
|
func conditionErrors(threads []Thread) error {
|
||||||
var condErr error
|
var condErr error
|
||||||
for _, th := range threads {
|
for _, th := range threads {
|
||||||
if bp, _, bperr := th.Breakpoint(); bp != nil && bperr != nil {
|
if bp, _, bperr := th.Breakpoint(); bp != nil && bperr != nil {
|
||||||
@ -209,7 +192,7 @@ func conditionErrors(threads []IThread) error {
|
|||||||
// - 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 pickCurrentThread(dbp Continuable, trapthread IThread, threads []IThread) error {
|
func pickCurrentThread(dbp Process, trapthread Thread, threads []Thread) error {
|
||||||
for _, th := range threads {
|
for _, th := range threads {
|
||||||
if bp, active, _ := th.Breakpoint(); active && bp.Internal() {
|
if bp, active, _ := th.Breakpoint(); active && bp.Internal() {
|
||||||
return dbp.SwitchThread(th.ThreadID())
|
return dbp.SwitchThread(th.ThreadID())
|
||||||
@ -228,7 +211,7 @@ func pickCurrentThread(dbp Continuable, trapthread IThread, threads []IThread) e
|
|||||||
|
|
||||||
// Step will continue until another source line is reached.
|
// Step will continue until another source line is reached.
|
||||||
// Will step into functions.
|
// Will step into functions.
|
||||||
func Step(dbp Continuable) (err error) {
|
func Step(dbp Process) (err error) {
|
||||||
if dbp.Exited() {
|
if dbp.Exited() {
|
||||||
return &ProcessExitedError{}
|
return &ProcessExitedError{}
|
||||||
}
|
}
|
||||||
@ -271,7 +254,7 @@ func SameGoroutineCondition(g *G) ast.Expr {
|
|||||||
|
|
||||||
// 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 StepOut(dbp Continuable) error {
|
func StepOut(dbp Process) error {
|
||||||
selg := dbp.SelectedGoroutine()
|
selg := dbp.SelectedGoroutine()
|
||||||
curthread := dbp.CurrentThread()
|
curthread := dbp.CurrentThread()
|
||||||
cond := SameGoroutineCondition(selg)
|
cond := SameGoroutineCondition(selg)
|
||||||
@ -335,7 +318,7 @@ type AllGCache interface {
|
|||||||
|
|
||||||
// GoroutinesInfo returns an array of G structures representing the information
|
// GoroutinesInfo returns an array of G structures representing the information
|
||||||
// Delve cares about from the internal runtime G structure.
|
// Delve cares about from the internal runtime G structure.
|
||||||
func GoroutinesInfo(dbp EvalScopeConvertible) ([]*G, error) {
|
func GoroutinesInfo(dbp Process) ([]*G, error) {
|
||||||
if dbp.Exited() {
|
if dbp.Exited() {
|
||||||
return nil, &ProcessExitedError{}
|
return nil, &ProcessExitedError{}
|
||||||
}
|
}
|
||||||
@ -346,7 +329,7 @@ func GoroutinesInfo(dbp EvalScopeConvertible) ([]*G, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
threadg = map[int]IThread{}
|
threadg = map[int]Thread{}
|
||||||
allg []*G
|
allg []*G
|
||||||
rdr = dbp.BinInfo().DwarfReader()
|
rdr = dbp.BinInfo().DwarfReader()
|
||||||
)
|
)
|
||||||
@ -416,7 +399,7 @@ func GoroutinesInfo(dbp EvalScopeConvertible) ([]*G, error) {
|
|||||||
return allg, nil
|
return allg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGoInformation(p Continuable) (ver GoVersion, isextld bool, err error) {
|
func GetGoInformation(p Process) (ver GoVersion, isextld bool, err error) {
|
||||||
scope := &EvalScope{0, 0, p.CurrentThread(), nil, p.BinInfo()}
|
scope := &EvalScope{0, 0, p.CurrentThread(), nil, p.BinInfo()}
|
||||||
vv, err := scope.packageVarAddr("runtime.buildVersion")
|
vv, err := scope.packageVarAddr("runtime.buildVersion")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -450,7 +433,7 @@ func GetGoInformation(p Continuable) (ver GoVersion, isextld bool, err error) {
|
|||||||
|
|
||||||
// FindGoroutine returns a G struct representing the goroutine
|
// FindGoroutine returns a G struct representing the goroutine
|
||||||
// specified by `gid`.
|
// specified by `gid`.
|
||||||
func FindGoroutine(dbp EvalScopeConvertible, gid int) (*G, error) {
|
func FindGoroutine(dbp Process, gid int) (*G, error) {
|
||||||
if gid == -1 {
|
if gid == -1 {
|
||||||
return dbp.SelectedGoroutine(), nil
|
return dbp.SelectedGoroutine(), nil
|
||||||
}
|
}
|
||||||
@ -467,19 +450,9 @@ func FindGoroutine(dbp EvalScopeConvertible, gid int) (*G, error) {
|
|||||||
return nil, fmt.Errorf("Unknown goroutine %d", gid)
|
return nil, fmt.Errorf("Unknown goroutine %d", gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EvalScopeConvertible is a subset of target.Interface with the methods
|
|
||||||
// used by ConvertEvalScope/GoroutinesInfo/etc.
|
|
||||||
type EvalScopeConvertible interface {
|
|
||||||
Exited() bool
|
|
||||||
SelectedGoroutine() *G
|
|
||||||
CurrentThread() IThread
|
|
||||||
BinInfo() *BinaryInfo
|
|
||||||
ThreadList() []IThread
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertEvalScope returns a new EvalScope in the context of the
|
// ConvertEvalScope returns a new EvalScope in the context of the
|
||||||
// specified goroutine ID and stack frame.
|
// specified goroutine ID and stack frame.
|
||||||
func ConvertEvalScope(dbp EvalScopeConvertible, gid, frame int) (*EvalScope, error) {
|
func ConvertEvalScope(dbp Process, gid, frame int) (*EvalScope, error) {
|
||||||
ct := dbp.CurrentThread()
|
ct := dbp.CurrentThread()
|
||||||
g, err := FindGoroutine(dbp, gid)
|
g, err := FindGoroutine(dbp, gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -511,6 +484,6 @@ func ConvertEvalScope(dbp EvalScopeConvertible, gid, frame int) (*EvalScope, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FrameToScope returns a new EvalScope for this frame
|
// FrameToScope returns a new EvalScope for this frame
|
||||||
func FrameToScope(p EvalScopeConvertible, frame Stackframe) *EvalScope {
|
func FrameToScope(p Process, frame Stackframe) *EvalScope {
|
||||||
return &EvalScope{frame.Current.PC, frame.CFA, p.CurrentThread(), nil, p.BinInfo()}
|
return &EvalScope{frame.Current.PC, frame.CFA, p.CurrentThread(), nil, p.BinInfo()}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
||||||
"github.com/derekparker/delve/pkg/proc/native"
|
"github.com/derekparker/delve/pkg/proc/native"
|
||||||
protest "github.com/derekparker/delve/pkg/proc/test"
|
protest "github.com/derekparker/delve/pkg/proc/test"
|
||||||
"github.com/derekparker/delve/pkg/target"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var normalLoadConfig = proc.LoadConfig{true, 1, 64, 64, -1}
|
var normalLoadConfig = proc.LoadConfig{true, 1, 64, 64, -1}
|
||||||
@ -46,9 +45,9 @@ func TestMain(m *testing.M) {
|
|||||||
os.Exit(protest.RunTestsWithFixtures(m))
|
os.Exit(protest.RunTestsWithFixtures(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
func withTestProcess(name string, t testing.TB, fn func(p target.Interface, fixture protest.Fixture)) {
|
func withTestProcess(name string, t testing.TB, fn func(p proc.Process, fixture protest.Fixture)) {
|
||||||
fixture := protest.BuildFixture(name)
|
fixture := protest.BuildFixture(name)
|
||||||
var p target.Interface
|
var p proc.Process
|
||||||
var err error
|
var err error
|
||||||
switch testBackend {
|
switch testBackend {
|
||||||
case "native":
|
case "native":
|
||||||
@ -70,9 +69,9 @@ func withTestProcess(name string, t testing.TB, fn func(p target.Interface, fixt
|
|||||||
fn(p, fixture)
|
fn(p, fixture)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withTestProcessArgs(name string, t testing.TB, wd string, fn func(p target.Interface, fixture protest.Fixture), args []string) {
|
func withTestProcessArgs(name string, t testing.TB, wd string, fn func(p proc.Process, fixture protest.Fixture), args []string) {
|
||||||
fixture := protest.BuildFixture(name)
|
fixture := protest.BuildFixture(name)
|
||||||
var p target.Interface
|
var p proc.Process
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch testBackend {
|
switch testBackend {
|
||||||
@ -95,7 +94,7 @@ func withTestProcessArgs(name string, t testing.TB, wd string, fn func(p target.
|
|||||||
fn(p, fixture)
|
fn(p, fixture)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRegisters(p target.Interface, t *testing.T) proc.Registers {
|
func getRegisters(p proc.Process, t *testing.T) proc.Registers {
|
||||||
regs, err := p.CurrentThread().Registers(false)
|
regs, err := p.CurrentThread().Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Registers():", err)
|
t.Fatal("Registers():", err)
|
||||||
@ -118,7 +117,7 @@ func assertNoError(err error, t testing.TB, s string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentPC(p target.Interface, t *testing.T) uint64 {
|
func currentPC(p proc.Process, t *testing.T) uint64 {
|
||||||
regs, err := p.CurrentThread().Registers(false)
|
regs, err := p.CurrentThread().Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -127,14 +126,14 @@ func currentPC(p target.Interface, t *testing.T) uint64 {
|
|||||||
return regs.PC()
|
return regs.PC()
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentLineNumber(p target.Interface, t *testing.T) (string, int) {
|
func currentLineNumber(p proc.Process, t *testing.T) (string, int) {
|
||||||
pc := currentPC(p, t)
|
pc := currentPC(p, t)
|
||||||
f, l, _ := p.BinInfo().PCToLine(pc)
|
f, l, _ := p.BinInfo().PCToLine(pc)
|
||||||
return f, l
|
return f, l
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExit(t *testing.T) {
|
func TestExit(t *testing.T) {
|
||||||
withTestProcess("continuetestprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("continuetestprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
pe, ok := err.(proc.ProcessExitedError)
|
pe, ok := err.(proc.ProcessExitedError)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -150,7 +149,7 @@ func TestExit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExitAfterContinue(t *testing.T) {
|
func TestExitAfterContinue(t *testing.T) {
|
||||||
withTestProcess("continuetestprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("continuetestprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.sayhi")
|
_, err := setFunctionBreakpoint(p, "main.sayhi")
|
||||||
assertNoError(err, t, "setFunctionBreakpoint()")
|
assertNoError(err, t, "setFunctionBreakpoint()")
|
||||||
assertNoError(proc.Continue(p), t, "First Continue()")
|
assertNoError(proc.Continue(p), t, "First Continue()")
|
||||||
@ -168,7 +167,7 @@ func TestExitAfterContinue(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func setFunctionBreakpoint(p target.Interface, fname string) (*proc.Breakpoint, error) {
|
func setFunctionBreakpoint(p proc.Process, fname string) (*proc.Breakpoint, error) {
|
||||||
addr, err := p.FindFunctionLocation(fname, true, 0)
|
addr, err := p.FindFunctionLocation(fname, true, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -176,7 +175,7 @@ func setFunctionBreakpoint(p target.Interface, fname string) (*proc.Breakpoint,
|
|||||||
return p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
return p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setFileBreakpoint(p target.Interface, t *testing.T, fixture protest.Fixture, lineno int) *proc.Breakpoint {
|
func setFileBreakpoint(p proc.Process, t *testing.T, fixture protest.Fixture, lineno int) *proc.Breakpoint {
|
||||||
addr, err := p.FindFileLocation(fixture.Source, lineno)
|
addr, err := p.FindFileLocation(fixture.Source, lineno)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("FindFileLocation: %v", err)
|
t.Fatalf("FindFileLocation: %v", err)
|
||||||
@ -190,7 +189,7 @@ func setFileBreakpoint(p target.Interface, t *testing.T, fixture protest.Fixture
|
|||||||
|
|
||||||
func TestHalt(t *testing.T) {
|
func TestHalt(t *testing.T) {
|
||||||
stopChan := make(chan interface{})
|
stopChan := make(chan interface{})
|
||||||
withTestProcess("loopprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("loopprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.loop")
|
_, err := setFunctionBreakpoint(p, "main.loop")
|
||||||
assertNoError(err, t, "SetBreakpoint")
|
assertNoError(err, t, "SetBreakpoint")
|
||||||
assertNoError(proc.Continue(p), t, "Continue")
|
assertNoError(proc.Continue(p), t, "Continue")
|
||||||
@ -235,7 +234,7 @@ func TestHalt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStep(t *testing.T) {
|
func TestStep(t *testing.T) {
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
helloworldaddr, err := p.FindFunctionLocation("main.helloworld", false, 0)
|
helloworldaddr, err := p.FindFunctionLocation("main.helloworld", false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation")
|
assertNoError(err, t, "FindFunctionLocation")
|
||||||
|
|
||||||
@ -257,7 +256,7 @@ func TestStep(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBreakpoint(t *testing.T) {
|
func TestBreakpoint(t *testing.T) {
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
helloworldaddr, err := p.FindFunctionLocation("main.helloworld", false, 0)
|
helloworldaddr, err := p.FindFunctionLocation("main.helloworld", false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation")
|
assertNoError(err, t, "FindFunctionLocation")
|
||||||
|
|
||||||
@ -281,7 +280,7 @@ func TestBreakpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBreakpointInSeperateGoRoutine(t *testing.T) {
|
func TestBreakpointInSeperateGoRoutine(t *testing.T) {
|
||||||
withTestProcess("testthreads", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testthreads", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
fnentry, err := p.FindFunctionLocation("main.anotherthread", false, 0)
|
fnentry, err := p.FindFunctionLocation("main.anotherthread", false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation")
|
assertNoError(err, t, "FindFunctionLocation")
|
||||||
|
|
||||||
@ -302,7 +301,7 @@ func TestBreakpointInSeperateGoRoutine(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBreakpointWithNonExistantFunction(t *testing.T) {
|
func TestBreakpointWithNonExistantFunction(t *testing.T) {
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := p.SetBreakpoint(0, proc.UserBreakpoint, nil)
|
_, err := p.SetBreakpoint(0, proc.UserBreakpoint, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Should not be able to break at non existant function")
|
t.Fatal("Should not be able to break at non existant function")
|
||||||
@ -311,7 +310,7 @@ func TestBreakpointWithNonExistantFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClearBreakpointBreakpoint(t *testing.T) {
|
func TestClearBreakpointBreakpoint(t *testing.T) {
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
fnentry, err := p.FindFunctionLocation("main.sleepytime", false, 0)
|
fnentry, err := p.FindFunctionLocation("main.sleepytime", false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation")
|
assertNoError(err, t, "FindFunctionLocation")
|
||||||
bp, err := p.SetBreakpoint(fnentry, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(fnentry, proc.UserBreakpoint, nil)
|
||||||
@ -338,7 +337,7 @@ type nextTest struct {
|
|||||||
begin, end int
|
begin, end int
|
||||||
}
|
}
|
||||||
|
|
||||||
func countBreakpoints(p target.Interface) int {
|
func countBreakpoints(p proc.Process) int {
|
||||||
bpcount := 0
|
bpcount := 0
|
||||||
for _, bp := range p.Breakpoints() {
|
for _, bp := range p.Breakpoints() {
|
||||||
if bp.ID >= 0 {
|
if bp.ID >= 0 {
|
||||||
@ -356,7 +355,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func testseq(program string, contFunc contFunc, testcases []nextTest, initialLocation string, t *testing.T) {
|
func testseq(program string, contFunc contFunc, testcases []nextTest, initialLocation string, t *testing.T) {
|
||||||
withTestProcess(program, t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess(program, t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
var bp *proc.Breakpoint
|
var bp *proc.Breakpoint
|
||||||
var err error
|
var err error
|
||||||
if initialLocation != "" {
|
if initialLocation != "" {
|
||||||
@ -456,7 +455,7 @@ func TestNextConcurrent(t *testing.T) {
|
|||||||
{9, 10},
|
{9, 10},
|
||||||
{10, 11},
|
{10, 11},
|
||||||
}
|
}
|
||||||
withTestProcess("parallel_next", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("parallel_next", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.sayhi")
|
bp, err := setFunctionBreakpoint(p, "main.sayhi")
|
||||||
assertNoError(err, t, "SetBreakpoint")
|
assertNoError(err, t, "SetBreakpoint")
|
||||||
assertNoError(proc.Continue(p), t, "Continue")
|
assertNoError(proc.Continue(p), t, "Continue")
|
||||||
@ -497,7 +496,7 @@ func TestNextConcurrentVariant2(t *testing.T) {
|
|||||||
{9, 10},
|
{9, 10},
|
||||||
{10, 11},
|
{10, 11},
|
||||||
}
|
}
|
||||||
withTestProcess("parallel_next", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("parallel_next", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.sayhi")
|
_, err := setFunctionBreakpoint(p, "main.sayhi")
|
||||||
assertNoError(err, t, "SetBreakpoint")
|
assertNoError(err, t, "SetBreakpoint")
|
||||||
assertNoError(proc.Continue(p), t, "Continue")
|
assertNoError(proc.Continue(p), t, "Continue")
|
||||||
@ -566,7 +565,7 @@ func TestNextNetHTTP(t *testing.T) {
|
|||||||
{11, 12},
|
{11, 12},
|
||||||
{12, 13},
|
{12, 13},
|
||||||
}
|
}
|
||||||
withTestProcess("testnextnethttp", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testnextnethttp", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
go func() {
|
go func() {
|
||||||
for !p.Running() {
|
for !p.Running() {
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
@ -602,7 +601,7 @@ func TestNextNetHTTP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRuntimeBreakpoint(t *testing.T) {
|
func TestRuntimeBreakpoint(t *testing.T) {
|
||||||
withTestProcess("testruntimebreakpoint", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testruntimebreakpoint", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -617,7 +616,7 @@ func TestRuntimeBreakpoint(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func returnAddress(thread proc.IThread) (uint64, error) {
|
func returnAddress(thread proc.Thread) (uint64, error) {
|
||||||
locations, err := proc.ThreadStacktrace(thread, 2)
|
locations, err := proc.ThreadStacktrace(thread, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -629,7 +628,7 @@ func returnAddress(thread proc.IThread) (uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFindReturnAddress(t *testing.T) {
|
func TestFindReturnAddress(t *testing.T) {
|
||||||
withTestProcess("testnextprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testnextprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
start, _, err := p.BinInfo().LineToPC(fixture.Source, 24)
|
start, _, err := p.BinInfo().LineToPC(fixture.Source, 24)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -654,7 +653,7 @@ func TestFindReturnAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFindReturnAddressTopOfStackFn(t *testing.T) {
|
func TestFindReturnAddressTopOfStackFn(t *testing.T) {
|
||||||
withTestProcess("testreturnaddress", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testreturnaddress", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
fnName := "runtime.rt0_go"
|
fnName := "runtime.rt0_go"
|
||||||
fnentry, err := p.FindFunctionLocation(fnName, false, 0)
|
fnentry, err := p.FindFunctionLocation(fnName, false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation")
|
assertNoError(err, t, "FindFunctionLocation")
|
||||||
@ -671,7 +670,7 @@ func TestFindReturnAddressTopOfStackFn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSwitchThread(t *testing.T) {
|
func TestSwitchThread(t *testing.T) {
|
||||||
withTestProcess("testnextprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testnextprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
// With invalid thread id
|
// With invalid thread id
|
||||||
err := p.SwitchThread(-1)
|
err := p.SwitchThread(-1)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -721,7 +720,7 @@ func TestCGONext(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("cgotest", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("cgotest", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
pc, err := p.FindFunctionLocation("main.main", true, 0)
|
pc, err := p.FindFunctionLocation("main.main", true, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -760,7 +759,7 @@ func TestStacktrace(t *testing.T) {
|
|||||||
{{4, "main.stacktraceme"}, {8, "main.func1"}, {16, "main.main"}},
|
{{4, "main.stacktraceme"}, {8, "main.func1"}, {16, "main.main"}},
|
||||||
{{4, "main.stacktraceme"}, {8, "main.func1"}, {12, "main.func2"}, {17, "main.main"}},
|
{{4, "main.stacktraceme"}, {8, "main.func1"}, {12, "main.func2"}, {17, "main.main"}},
|
||||||
}
|
}
|
||||||
withTestProcess("stacktraceprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("stacktraceprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.stacktraceme")
|
bp, err := setFunctionBreakpoint(p, "main.stacktraceme")
|
||||||
assertNoError(err, t, "BreakByLocation()")
|
assertNoError(err, t, "BreakByLocation()")
|
||||||
|
|
||||||
@ -791,7 +790,7 @@ func TestStacktrace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStacktrace2(t *testing.T) {
|
func TestStacktrace2(t *testing.T) {
|
||||||
withTestProcess("retstack", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("retstack", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
|
|
||||||
locations, err := proc.ThreadStacktrace(p.CurrentThread(), 40)
|
locations, err := proc.ThreadStacktrace(p.CurrentThread(), 40)
|
||||||
@ -842,7 +841,7 @@ func TestStacktraceGoroutine(t *testing.T) {
|
|||||||
mainStack := []loc{{13, "main.stacktraceme"}, {26, "main.main"}}
|
mainStack := []loc{{13, "main.stacktraceme"}, {26, "main.main"}}
|
||||||
agoroutineStacks := [][]loc{[]loc{{8, "main.agoroutine"}}, []loc{{9, "main.agoroutine"}}, []loc{{10, "main.agoroutine"}}}
|
agoroutineStacks := [][]loc{[]loc{{8, "main.agoroutine"}}, []loc{{9, "main.agoroutine"}}, []loc{{10, "main.agoroutine"}}}
|
||||||
|
|
||||||
withTestProcess("goroutinestackprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("goroutinestackprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.stacktraceme")
|
bp, err := setFunctionBreakpoint(p, "main.stacktraceme")
|
||||||
assertNoError(err, t, "BreakByLocation()")
|
assertNoError(err, t, "BreakByLocation()")
|
||||||
|
|
||||||
@ -905,7 +904,7 @@ func TestKill(t *testing.T) {
|
|||||||
// k command presumably works but leaves the process around?
|
// k command presumably works but leaves the process around?
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
if err := p.Kill(); err != nil {
|
if err := p.Kill(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -921,7 +920,7 @@ func TestKill(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGSupportFunc(name string, t *testing.T, p target.Interface, fixture protest.Fixture) {
|
func testGSupportFunc(name string, t *testing.T, p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.main")
|
bp, err := setFunctionBreakpoint(p, "main.main")
|
||||||
assertNoError(err, t, name+": BreakByLocation()")
|
assertNoError(err, t, name+": BreakByLocation()")
|
||||||
|
|
||||||
@ -940,7 +939,7 @@ func testGSupportFunc(name string, t *testing.T, p target.Interface, fixture pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetG(t *testing.T) {
|
func TestGetG(t *testing.T) {
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
testGSupportFunc("nocgo", t, p, fixture)
|
testGSupportFunc("nocgo", t, p, fixture)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -952,13 +951,13 @@ func TestGetG(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("cgotest", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("cgotest", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
testGSupportFunc("cgo", t, p, fixture)
|
testGSupportFunc("cgo", t, p, fixture)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContinueMulti(t *testing.T) {
|
func TestContinueMulti(t *testing.T) {
|
||||||
withTestProcess("integrationprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("integrationprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp1, err := setFunctionBreakpoint(p, "main.main")
|
bp1, err := setFunctionBreakpoint(p, "main.main")
|
||||||
assertNoError(err, t, "BreakByLocation()")
|
assertNoError(err, t, "BreakByLocation()")
|
||||||
|
|
||||||
@ -1021,7 +1020,7 @@ func TestParseVersionString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBreakpointOnFunctionEntry(t *testing.T) {
|
func TestBreakpointOnFunctionEntry(t *testing.T) {
|
||||||
withTestProcess("testprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, err := p.FindFunctionLocation("main.main", false, 0)
|
addr, err := p.FindFunctionLocation("main.main", false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation()")
|
assertNoError(err, t, "FindFunctionLocation()")
|
||||||
_, err = p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1035,7 +1034,7 @@ func TestBreakpointOnFunctionEntry(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestProcessReceivesSIGCHLD(t *testing.T) {
|
func TestProcessReceivesSIGCHLD(t *testing.T) {
|
||||||
withTestProcess("sigchldprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("sigchldprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
_, ok := err.(proc.ProcessExitedError)
|
_, ok := err.(proc.ProcessExitedError)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -1045,7 +1044,7 @@ func TestProcessReceivesSIGCHLD(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue239(t *testing.T) {
|
func TestIssue239(t *testing.T) {
|
||||||
withTestProcess("is sue239", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("is sue239", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
pos, _, err := p.BinInfo().LineToPC(fixture.Source, 17)
|
pos, _, err := p.BinInfo().LineToPC(fixture.Source, 17)
|
||||||
assertNoError(err, t, "LineToPC()")
|
assertNoError(err, t, "LineToPC()")
|
||||||
_, err = p.SetBreakpoint(pos, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(pos, proc.UserBreakpoint, nil)
|
||||||
@ -1054,7 +1053,7 @@ func TestIssue239(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalVariable(p target.Interface, symbol string) (*proc.Variable, error) {
|
func evalVariable(p proc.Process, symbol string) (*proc.Variable, error) {
|
||||||
scope, err := proc.GoroutineScope(p.CurrentThread())
|
scope, err := proc.GoroutineScope(p.CurrentThread())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1063,7 +1062,7 @@ func evalVariable(p target.Interface, symbol string) (*proc.Variable, error) {
|
|||||||
return scope.EvalVariable(symbol, normalLoadConfig)
|
return scope.EvalVariable(symbol, normalLoadConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setVariable(p target.Interface, symbol, value string) error {
|
func setVariable(p proc.Process, symbol, value string) error {
|
||||||
scope, err := proc.GoroutineScope(p.CurrentThread())
|
scope, err := proc.GoroutineScope(p.CurrentThread())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1107,7 +1106,7 @@ func TestVariableEvaluation(t *testing.T) {
|
|||||||
{"ba", reflect.Slice, nil, 200, 200, 64},
|
{"ba", reflect.Slice, nil, 200, 200, 64},
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
|
|
||||||
for _, tc := range testcases {
|
for _, tc := range testcases {
|
||||||
@ -1157,7 +1156,7 @@ func TestVariableEvaluation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFrameEvaluation(t *testing.T) {
|
func TestFrameEvaluation(t *testing.T) {
|
||||||
withTestProcess("goroutinestackprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("goroutinestackprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.stacktraceme")
|
_, err := setFunctionBreakpoint(p, "main.stacktraceme")
|
||||||
assertNoError(err, t, "setFunctionBreakpoint")
|
assertNoError(err, t, "setFunctionBreakpoint")
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
@ -1224,7 +1223,7 @@ func TestFrameEvaluation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPointerSetting(t *testing.T) {
|
func TestPointerSetting(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
|
|
||||||
pval := func(n int64) {
|
pval := func(n int64) {
|
||||||
@ -1253,7 +1252,7 @@ func TestPointerSetting(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestVariableFunctionScoping(t *testing.T) {
|
func TestVariableFunctionScoping(t *testing.T) {
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue() returned an error")
|
assertNoError(err, t, "Continue() returned an error")
|
||||||
|
|
||||||
@ -1278,7 +1277,7 @@ func TestVariableFunctionScoping(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRecursiveStructure(t *testing.T) {
|
func TestRecursiveStructure(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
v, err := evalVariable(p, "aas")
|
v, err := evalVariable(p, "aas")
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
@ -1288,7 +1287,7 @@ func TestRecursiveStructure(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue316(t *testing.T) {
|
func TestIssue316(t *testing.T) {
|
||||||
// A pointer loop that includes one interface should not send dlv into an infinite loop
|
// A pointer loop that includes one interface should not send dlv into an infinite loop
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
_, err := evalVariable(p, "iface5")
|
_, err := evalVariable(p, "iface5")
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
@ -1297,7 +1296,7 @@ func TestIssue316(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue325(t *testing.T) {
|
func TestIssue325(t *testing.T) {
|
||||||
// nil pointer dereference when evaluating interfaces to function pointers
|
// nil pointer dereference when evaluating interfaces to function pointers
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
iface2fn1v, err := evalVariable(p, "iface2fn1")
|
iface2fn1v, err := evalVariable(p, "iface2fn1")
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
@ -1310,7 +1309,7 @@ func TestIssue325(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBreakpointCounts(t *testing.T) {
|
func TestBreakpointCounts(t *testing.T) {
|
||||||
withTestProcess("bpcountstest", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("bpcountstest", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 12)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 12)
|
||||||
assertNoError(err, t, "LineToPC")
|
assertNoError(err, t, "LineToPC")
|
||||||
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1345,7 +1344,7 @@ func TestBreakpointCounts(t *testing.T) {
|
|||||||
func BenchmarkArray(b *testing.B) {
|
func BenchmarkArray(b *testing.B) {
|
||||||
// each bencharr struct is 128 bytes, bencharr is 64 elements long
|
// each bencharr struct is 128 bytes, bencharr is 64 elements long
|
||||||
b.SetBytes(int64(64 * 128))
|
b.SetBytes(int64(64 * 128))
|
||||||
withTestProcess("testvariables2", b, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", b, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), b, "Continue()")
|
assertNoError(proc.Continue(p), b, "Continue()")
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, err := evalVariable(p, "bencharr")
|
_, err := evalVariable(p, "bencharr")
|
||||||
@ -1361,7 +1360,7 @@ func TestBreakpointCountsWithDetection(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
m := map[int64]int64{}
|
m := map[int64]int64{}
|
||||||
withTestProcess("bpcountstest", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("bpcountstest", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 12)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 12)
|
||||||
assertNoError(err, t, "LineToPC")
|
assertNoError(err, t, "LineToPC")
|
||||||
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1420,7 +1419,7 @@ func BenchmarkArrayPointer(b *testing.B) {
|
|||||||
// each bencharr struct is 128 bytes, benchparr is an array of 64 pointers to bencharr
|
// each bencharr struct is 128 bytes, benchparr is an array of 64 pointers to bencharr
|
||||||
// each read will read 64 bencharr structs plus the 64 pointers of benchparr
|
// each read will read 64 bencharr structs plus the 64 pointers of benchparr
|
||||||
b.SetBytes(int64(64*128 + 64*8))
|
b.SetBytes(int64(64*128 + 64*8))
|
||||||
withTestProcess("testvariables2", b, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", b, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), b, "Continue()")
|
assertNoError(proc.Continue(p), b, "Continue()")
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, err := evalVariable(p, "bencharr")
|
_, err := evalVariable(p, "bencharr")
|
||||||
@ -1434,7 +1433,7 @@ func BenchmarkMap(b *testing.B) {
|
|||||||
// each string key has an average of 9 character
|
// each string key has an average of 9 character
|
||||||
// reading strings and the map structure imposes a overhead that we ignore here
|
// reading strings and the map structure imposes a overhead that we ignore here
|
||||||
b.SetBytes(int64(41 * (2*8 + 9)))
|
b.SetBytes(int64(41 * (2*8 + 9)))
|
||||||
withTestProcess("testvariables2", b, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", b, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), b, "Continue()")
|
assertNoError(proc.Continue(p), b, "Continue()")
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, err := evalVariable(p, "m1")
|
_, err := evalVariable(p, "m1")
|
||||||
@ -1444,7 +1443,7 @@ func BenchmarkMap(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkGoroutinesInfo(b *testing.B) {
|
func BenchmarkGoroutinesInfo(b *testing.B) {
|
||||||
withTestProcess("testvariables2", b, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", b, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), b, "Continue()")
|
assertNoError(proc.Continue(p), b, "Continue()")
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if p, ok := p.(proc.AllGCache); ok {
|
if p, ok := p.(proc.AllGCache); ok {
|
||||||
@ -1459,7 +1458,7 @@ func BenchmarkGoroutinesInfo(b *testing.B) {
|
|||||||
|
|
||||||
func TestIssue262(t *testing.T) {
|
func TestIssue262(t *testing.T) {
|
||||||
// Continue does not work when the current breakpoint is set on a NOP instruction
|
// Continue does not work when the current breakpoint is set on a NOP instruction
|
||||||
withTestProcess("issue262", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue262", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 11)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 11)
|
||||||
assertNoError(err, t, "LineToPC")
|
assertNoError(err, t, "LineToPC")
|
||||||
_, err = p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1481,7 +1480,7 @@ func TestIssue305(t *testing.T) {
|
|||||||
// If 'next' hits a breakpoint on the goroutine it's stepping through
|
// If 'next' hits a breakpoint on the goroutine it's stepping through
|
||||||
// the internal breakpoints aren't cleared preventing further use of
|
// the internal breakpoints aren't cleared preventing further use of
|
||||||
// 'next' command
|
// 'next' command
|
||||||
withTestProcess("issue305", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue305", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 5)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 5)
|
||||||
assertNoError(err, t, "LineToPC()")
|
assertNoError(err, t, "LineToPC()")
|
||||||
_, err = p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1500,7 +1499,7 @@ func TestIssue305(t *testing.T) {
|
|||||||
func TestPointerLoops(t *testing.T) {
|
func TestPointerLoops(t *testing.T) {
|
||||||
// Pointer loops through map entries, pointers and slices
|
// Pointer loops through map entries, pointers and slices
|
||||||
// Regression test for issue #341
|
// Regression test for issue #341
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
for _, expr := range []string{"mapinf", "ptrinf", "sliceinf"} {
|
for _, expr := range []string{"mapinf", "ptrinf", "sliceinf"} {
|
||||||
t.Logf("requesting %s", expr)
|
t.Logf("requesting %s", expr)
|
||||||
@ -1512,7 +1511,7 @@ func TestPointerLoops(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkLocalVariables(b *testing.B) {
|
func BenchmarkLocalVariables(b *testing.B) {
|
||||||
withTestProcess("testvariables", b, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", b, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), b, "Continue() returned an error")
|
assertNoError(proc.Continue(p), b, "Continue() returned an error")
|
||||||
scope, err := proc.GoroutineScope(p.CurrentThread())
|
scope, err := proc.GoroutineScope(p.CurrentThread())
|
||||||
assertNoError(err, b, "Scope()")
|
assertNoError(err, b, "Scope()")
|
||||||
@ -1524,7 +1523,7 @@ func BenchmarkLocalVariables(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCondBreakpoint(t *testing.T) {
|
func TestCondBreakpoint(t *testing.T) {
|
||||||
withTestProcess("parallel_next", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("parallel_next", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 9)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 9)
|
||||||
assertNoError(err, t, "LineToPC")
|
assertNoError(err, t, "LineToPC")
|
||||||
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1548,7 +1547,7 @@ func TestCondBreakpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCondBreakpointError(t *testing.T) {
|
func TestCondBreakpointError(t *testing.T) {
|
||||||
withTestProcess("parallel_next", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("parallel_next", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 9)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 9)
|
||||||
assertNoError(err, t, "LineToPC")
|
assertNoError(err, t, "LineToPC")
|
||||||
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -1593,7 +1592,7 @@ func TestCondBreakpointError(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue356(t *testing.T) {
|
func TestIssue356(t *testing.T) {
|
||||||
// slice with a typedef does not get printed correctly
|
// slice with a typedef does not get printed correctly
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
mmvar, err := evalVariable(p, "mainMenu")
|
mmvar, err := evalVariable(p, "mainMenu")
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
@ -1604,7 +1603,7 @@ func TestIssue356(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepIntoFunction(t *testing.T) {
|
func TestStepIntoFunction(t *testing.T) {
|
||||||
withTestProcess("teststep", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("teststep", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
// Continue until breakpoint
|
// Continue until breakpoint
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
// Step into function
|
// Step into function
|
||||||
@ -1628,7 +1627,7 @@ func TestStepIntoFunction(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue384(t *testing.T) {
|
func TestIssue384(t *testing.T) {
|
||||||
// Crash related to reading uninitialized memory, introduced by the memory prefetching optimization
|
// Crash related to reading uninitialized memory, introduced by the memory prefetching optimization
|
||||||
withTestProcess("issue384", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue384", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
start, _, err := p.BinInfo().LineToPC(fixture.Source, 13)
|
start, _, err := p.BinInfo().LineToPC(fixture.Source, 13)
|
||||||
assertNoError(err, t, "LineToPC()")
|
assertNoError(err, t, "LineToPC()")
|
||||||
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
||||||
@ -1641,7 +1640,7 @@ func TestIssue384(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue332_Part1(t *testing.T) {
|
func TestIssue332_Part1(t *testing.T) {
|
||||||
// Next shouldn't step inside a function call
|
// Next shouldn't step inside a function call
|
||||||
withTestProcess("issue332", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue332", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
start, _, err := p.BinInfo().LineToPC(fixture.Source, 8)
|
start, _, err := p.BinInfo().LineToPC(fixture.Source, 8)
|
||||||
assertNoError(err, t, "LineToPC()")
|
assertNoError(err, t, "LineToPC()")
|
||||||
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
||||||
@ -1667,7 +1666,7 @@ func TestIssue332_Part2(t *testing.T) {
|
|||||||
// In some parts of the prologue, for some functions, the FDE data is incorrect
|
// In some parts of the prologue, for some functions, the FDE data is incorrect
|
||||||
// which leads to 'next' and 'stack' failing with error "could not find FDE for PC: <garbage>"
|
// which leads to 'next' and 'stack' failing with error "could not find FDE for PC: <garbage>"
|
||||||
// because the incorrect FDE data leads to reading the wrong stack address as the return address
|
// because the incorrect FDE data leads to reading the wrong stack address as the return address
|
||||||
withTestProcess("issue332", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue332", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
start, _, err := p.BinInfo().LineToPC(fixture.Source, 8)
|
start, _, err := p.BinInfo().LineToPC(fixture.Source, 8)
|
||||||
assertNoError(err, t, "LineToPC()")
|
assertNoError(err, t, "LineToPC()")
|
||||||
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
||||||
@ -1711,7 +1710,7 @@ func TestIssue332_Part2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue396(t *testing.T) {
|
func TestIssue396(t *testing.T) {
|
||||||
withTestProcess("callme", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("callme", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := p.FindFunctionLocation("main.init", true, -1)
|
_, err := p.FindFunctionLocation("main.init", true, -1)
|
||||||
assertNoError(err, t, "FindFunctionLocation()")
|
assertNoError(err, t, "FindFunctionLocation()")
|
||||||
})
|
})
|
||||||
@ -1719,7 +1718,7 @@ func TestIssue396(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue414(t *testing.T) {
|
func TestIssue414(t *testing.T) {
|
||||||
// Stepping until the program exits
|
// Stepping until the program exits
|
||||||
withTestProcess("math", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("math", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
start, _, err := p.BinInfo().LineToPC(fixture.Source, 9)
|
start, _, err := p.BinInfo().LineToPC(fixture.Source, 9)
|
||||||
assertNoError(err, t, "LineToPC()")
|
assertNoError(err, t, "LineToPC()")
|
||||||
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(start, proc.UserBreakpoint, nil)
|
||||||
@ -1738,7 +1737,7 @@ func TestIssue414(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPackageVariables(t *testing.T) {
|
func TestPackageVariables(t *testing.T) {
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue()")
|
assertNoError(err, t, "Continue()")
|
||||||
scope, err := proc.GoroutineScope(p.CurrentThread())
|
scope, err := proc.GoroutineScope(p.CurrentThread())
|
||||||
@ -1764,14 +1763,14 @@ func TestIssue149(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// setting breakpoint on break statement
|
// setting breakpoint on break statement
|
||||||
withTestProcess("break", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("break", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := p.FindFileLocation(fixture.Source, 8)
|
_, err := p.FindFileLocation(fixture.Source, 8)
|
||||||
assertNoError(err, t, "FindFileLocation()")
|
assertNoError(err, t, "FindFileLocation()")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPanicBreakpoint(t *testing.T) {
|
func TestPanicBreakpoint(t *testing.T) {
|
||||||
withTestProcess("panic", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("panic", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
bp, _, _ := p.CurrentThread().Breakpoint()
|
bp, _, _ := p.CurrentThread().Breakpoint()
|
||||||
if bp == nil || bp.Name != "unrecovered-panic" {
|
if bp == nil || bp.Name != "unrecovered-panic" {
|
||||||
@ -1781,7 +1780,7 @@ func TestPanicBreakpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCmdLineArgs(t *testing.T) {
|
func TestCmdLineArgs(t *testing.T) {
|
||||||
expectSuccess := func(p target.Interface, fixture protest.Fixture) {
|
expectSuccess := func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
bp, _, _ := p.CurrentThread().Breakpoint()
|
bp, _, _ := p.CurrentThread().Breakpoint()
|
||||||
if bp != nil && bp.Name == "unrecovered-panic" {
|
if bp != nil && bp.Name == "unrecovered-panic" {
|
||||||
@ -1797,7 +1796,7 @@ func TestCmdLineArgs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectPanic := func(p target.Interface, fixture protest.Fixture) {
|
expectPanic := func(p proc.Process, fixture protest.Fixture) {
|
||||||
proc.Continue(p)
|
proc.Continue(p)
|
||||||
bp, _, _ := p.CurrentThread().Breakpoint()
|
bp, _, _ := p.CurrentThread().Breakpoint()
|
||||||
if bp == nil || bp.Name != "unrecovered-panic" {
|
if bp == nil || bp.Name != "unrecovered-panic" {
|
||||||
@ -1824,7 +1823,7 @@ func TestIssue462(t *testing.T) {
|
|||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
withTestProcess("testnextnethttp", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testnextnethttp", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
go func() {
|
go func() {
|
||||||
for !p.Running() {
|
for !p.Running() {
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(50 * time.Millisecond)
|
||||||
@ -1850,7 +1849,7 @@ func TestIssue462(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNextParked(t *testing.T) {
|
func TestNextParked(t *testing.T) {
|
||||||
withTestProcess("parallel_next", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("parallel_next", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.sayhi")
|
bp, err := setFunctionBreakpoint(p, "main.sayhi")
|
||||||
assertNoError(err, t, "SetBreakpoint()")
|
assertNoError(err, t, "SetBreakpoint()")
|
||||||
|
|
||||||
@ -1887,7 +1886,7 @@ func TestNextParked(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepParked(t *testing.T) {
|
func TestStepParked(t *testing.T) {
|
||||||
withTestProcess("parallel_next", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("parallel_next", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.sayhi")
|
bp, err := setFunctionBreakpoint(p, "main.sayhi")
|
||||||
assertNoError(err, t, "SetBreakpoint()")
|
assertNoError(err, t, "SetBreakpoint()")
|
||||||
|
|
||||||
@ -1990,7 +1989,7 @@ func TestUnsupportedArch(t *testing.T) {
|
|||||||
func TestIssue573(t *testing.T) {
|
func TestIssue573(t *testing.T) {
|
||||||
// calls to runtime.duffzero and runtime.duffcopy jump directly into the middle
|
// calls to runtime.duffzero and runtime.duffcopy jump directly into the middle
|
||||||
// of the function and the internal breakpoint set by StepInto may be missed.
|
// of the function and the internal breakpoint set by StepInto may be missed.
|
||||||
withTestProcess("issue573", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue573", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
fentry, _ := p.FindFunctionLocation("main.foo", false, 0)
|
fentry, _ := p.FindFunctionLocation("main.foo", false, 0)
|
||||||
_, err := p.SetBreakpoint(fentry, proc.UserBreakpoint, nil)
|
_, err := p.SetBreakpoint(fentry, proc.UserBreakpoint, nil)
|
||||||
assertNoError(err, t, "SetBreakpoint()")
|
assertNoError(err, t, "SetBreakpoint()")
|
||||||
@ -2002,7 +2001,7 @@ func TestIssue573(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTestvariables2Prologue(t *testing.T) {
|
func TestTestvariables2Prologue(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addrEntry, err := p.FindFunctionLocation("main.main", false, 0)
|
addrEntry, err := p.FindFunctionLocation("main.main", false, 0)
|
||||||
assertNoError(err, t, "FindFunctionLocation - entrypoint")
|
assertNoError(err, t, "FindFunctionLocation - entrypoint")
|
||||||
addrPrologue, err := p.FindFunctionLocation("main.main", true, 0)
|
addrPrologue, err := p.FindFunctionLocation("main.main", true, 0)
|
||||||
@ -2112,7 +2111,7 @@ func TestStepIgnorePrivateRuntime(t *testing.T) {
|
|||||||
func TestIssue561(t *testing.T) {
|
func TestIssue561(t *testing.T) {
|
||||||
// Step fails to make progress when PC is at a CALL instruction
|
// Step fails to make progress when PC is at a CALL instruction
|
||||||
// where a breakpoint is also set.
|
// where a breakpoint is also set.
|
||||||
withTestProcess("issue561", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue561", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
setFileBreakpoint(p, t, fixture, 10)
|
setFileBreakpoint(p, t, fixture, 10)
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
assertNoError(proc.Step(p), t, "Step()")
|
assertNoError(proc.Step(p), t, "Step()")
|
||||||
@ -2124,7 +2123,7 @@ func TestIssue561(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepOut(t *testing.T) {
|
func TestStepOut(t *testing.T) {
|
||||||
withTestProcess("testnextprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testnextprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp, err := setFunctionBreakpoint(p, "main.helloworld")
|
bp, err := setFunctionBreakpoint(p, "main.helloworld")
|
||||||
assertNoError(err, t, "SetBreakpoint()")
|
assertNoError(err, t, "SetBreakpoint()")
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
@ -2145,7 +2144,7 @@ func TestStepOut(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepConcurrentDirect(t *testing.T) {
|
func TestStepConcurrentDirect(t *testing.T) {
|
||||||
withTestProcess("teststepconcurrent", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("teststepconcurrent", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
pc, err := p.FindFileLocation(fixture.Source, 37)
|
pc, err := p.FindFileLocation(fixture.Source, 37)
|
||||||
assertNoError(err, t, "FindFileLocation()")
|
assertNoError(err, t, "FindFileLocation()")
|
||||||
bp, err := p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
||||||
@ -2209,7 +2208,7 @@ func TestStepConcurrentDirect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextInProgress(p target.Interface) bool {
|
func nextInProgress(p proc.Process) bool {
|
||||||
for _, bp := range p.Breakpoints() {
|
for _, bp := range p.Breakpoints() {
|
||||||
if bp.Internal() {
|
if bp.Internal() {
|
||||||
return true
|
return true
|
||||||
@ -2219,7 +2218,7 @@ func nextInProgress(p target.Interface) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepConcurrentPtr(t *testing.T) {
|
func TestStepConcurrentPtr(t *testing.T) {
|
||||||
withTestProcess("teststepconcurrent", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("teststepconcurrent", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
pc, err := p.FindFileLocation(fixture.Source, 24)
|
pc, err := p.FindFileLocation(fixture.Source, 24)
|
||||||
assertNoError(err, t, "FindFileLocation()")
|
assertNoError(err, t, "FindFileLocation()")
|
||||||
_, err = p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
||||||
@ -2298,7 +2297,7 @@ func TestStepConcurrentPtr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStepOutDefer(t *testing.T) {
|
func TestStepOutDefer(t *testing.T) {
|
||||||
withTestProcess("testnextdefer", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testnextdefer", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
pc, err := p.FindFileLocation(fixture.Source, 9)
|
pc, err := p.FindFileLocation(fixture.Source, 9)
|
||||||
assertNoError(err, t, "FindFileLocation()")
|
assertNoError(err, t, "FindFileLocation()")
|
||||||
bp, err := p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
bp, err := p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
||||||
@ -2324,7 +2323,7 @@ func TestStepOutDeferReturnAndDirectCall(t *testing.T) {
|
|||||||
// StepOut should not step into a deferred function if it is called
|
// StepOut should not step into a deferred function if it is called
|
||||||
// directly, only if it is called through a panic.
|
// directly, only if it is called through a panic.
|
||||||
// Here we test the case where the function is called by a deferreturn
|
// Here we test the case where the function is called by a deferreturn
|
||||||
withTestProcess("defercall", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("defercall", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp := setFileBreakpoint(p, t, fixture, 11)
|
bp := setFileBreakpoint(p, t, fixture, 11)
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
p.ClearBreakpoint(bp.Addr)
|
p.ClearBreakpoint(bp.Addr)
|
||||||
@ -2341,7 +2340,7 @@ func TestStepOutDeferReturnAndDirectCall(t *testing.T) {
|
|||||||
const maxInstructionLength uint64 = 15
|
const maxInstructionLength uint64 = 15
|
||||||
|
|
||||||
func TestStepOnCallPtrInstr(t *testing.T) {
|
func TestStepOnCallPtrInstr(t *testing.T) {
|
||||||
withTestProcess("teststepprog", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("teststepprog", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
pc, err := p.FindFileLocation(fixture.Source, 10)
|
pc, err := p.FindFileLocation(fixture.Source, 10)
|
||||||
assertNoError(err, t, "FindFileLocation()")
|
assertNoError(err, t, "FindFileLocation()")
|
||||||
_, err = p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
_, err = p.SetBreakpoint(pc, proc.UserBreakpoint, nil)
|
||||||
@ -2394,7 +2393,7 @@ func TestIssue594(t *testing.T) {
|
|||||||
// back to the target.
|
// back to the target.
|
||||||
// In particular the target should be able to cause a nil pointer
|
// In particular the target should be able to cause a nil pointer
|
||||||
// dereference panic and recover from it.
|
// dereference panic and recover from it.
|
||||||
withTestProcess("issue594", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue594", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
f, ln := currentLineNumber(p, t)
|
f, ln := currentLineNumber(p, t)
|
||||||
if ln != 21 {
|
if ln != 21 {
|
||||||
@ -2407,7 +2406,7 @@ func TestStepOutPanicAndDirectCall(t *testing.T) {
|
|||||||
// StepOut should not step into a deferred function if it is called
|
// StepOut should not step into a deferred function if it is called
|
||||||
// directly, only if it is called through a panic.
|
// directly, only if it is called through a panic.
|
||||||
// Here we test the case where the function is called by a panic
|
// Here we test the case where the function is called by a panic
|
||||||
withTestProcess("defercall", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("defercall", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
bp := setFileBreakpoint(p, t, fixture, 17)
|
bp := setFileBreakpoint(p, t, fixture, 17)
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
p.ClearBreakpoint(bp.Addr)
|
p.ClearBreakpoint(bp.Addr)
|
||||||
@ -2427,7 +2426,7 @@ func TestWorkDir(t *testing.T) {
|
|||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
wd = "/private/tmp"
|
wd = "/private/tmp"
|
||||||
}
|
}
|
||||||
withTestProcessArgs("workdir", t, wd, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcessArgs("workdir", t, wd, func(p proc.Process, fixture protest.Fixture) {
|
||||||
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 14)
|
addr, _, err := p.BinInfo().LineToPC(fixture.Source, 14)
|
||||||
assertNoError(err, t, "LineToPC")
|
assertNoError(err, t, "LineToPC")
|
||||||
p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
p.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||||
@ -2451,7 +2450,7 @@ func TestNegativeIntEvaluation(t *testing.T) {
|
|||||||
{"ni16", "int16", int64(-5)},
|
{"ni16", "int16", int64(-5)},
|
||||||
{"ni32", "int32", int64(-5)},
|
{"ni32", "int32", int64(-5)},
|
||||||
}
|
}
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
for _, tc := range testcases {
|
for _, tc := range testcases {
|
||||||
v, err := evalVariable(p, tc.name)
|
v, err := evalVariable(p, tc.name)
|
||||||
@ -2468,7 +2467,7 @@ func TestNegativeIntEvaluation(t *testing.T) {
|
|||||||
|
|
||||||
func TestIssue683(t *testing.T) {
|
func TestIssue683(t *testing.T) {
|
||||||
// Step panics when source file can not be found
|
// Step panics when source file can not be found
|
||||||
withTestProcess("issue683", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue683", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.main")
|
_, err := setFunctionBreakpoint(p, "main.main")
|
||||||
assertNoError(err, t, "setFunctionBreakpoint()")
|
assertNoError(err, t, "setFunctionBreakpoint()")
|
||||||
assertNoError(proc.Continue(p), t, "First Continue()")
|
assertNoError(proc.Continue(p), t, "First Continue()")
|
||||||
@ -2484,7 +2483,7 @@ func TestIssue683(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue664(t *testing.T) {
|
func TestIssue664(t *testing.T) {
|
||||||
withTestProcess("issue664", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue664", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
setFileBreakpoint(p, t, fixture, 4)
|
setFileBreakpoint(p, t, fixture, 4)
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
assertNoError(proc.Next(p), t, "Next()")
|
assertNoError(proc.Next(p), t, "Next()")
|
||||||
@ -2497,7 +2496,7 @@ func TestIssue664(t *testing.T) {
|
|||||||
|
|
||||||
// Benchmarks (*Processs).Continue + (*Scope).FunctionArguments
|
// Benchmarks (*Processs).Continue + (*Scope).FunctionArguments
|
||||||
func BenchmarkTrace(b *testing.B) {
|
func BenchmarkTrace(b *testing.B) {
|
||||||
withTestProcess("traceperf", b, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("traceperf", b, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.PerfCheck")
|
_, err := setFunctionBreakpoint(p, "main.PerfCheck")
|
||||||
assertNoError(err, b, "setFunctionBreakpoint()")
|
assertNoError(err, b, "setFunctionBreakpoint()")
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@ -2517,7 +2516,7 @@ func TestNextInDeferReturn(t *testing.T) {
|
|||||||
// instruction leaves the curg._defer field non-nil but with curg._defer.fn
|
// instruction leaves the curg._defer field non-nil but with curg._defer.fn
|
||||||
// field being nil.
|
// field being nil.
|
||||||
// We need to deal with this without panicing.
|
// We need to deal with this without panicing.
|
||||||
withTestProcess("defercall", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("defercall", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "runtime.deferreturn")
|
_, err := setFunctionBreakpoint(p, "runtime.deferreturn")
|
||||||
assertNoError(err, t, "setFunctionBreakpoint()")
|
assertNoError(err, t, "setFunctionBreakpoint()")
|
||||||
assertNoError(proc.Continue(p), t, "First Continue()")
|
assertNoError(proc.Continue(p), t, "First Continue()")
|
||||||
@ -2553,7 +2552,7 @@ func TestStacktraceWithBarriers(t *testing.T) {
|
|||||||
defer os.Setenv("GODEBUG", godebugOld)
|
defer os.Setenv("GODEBUG", godebugOld)
|
||||||
os.Setenv("GODEBUG", "gcrescanstacks=1")
|
os.Setenv("GODEBUG", "gcrescanstacks=1")
|
||||||
|
|
||||||
withTestProcess("binarytrees", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("binarytrees", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
// We want to get a user goroutine with a stack barrier, to get that we execute the program until runtime.gcInstallStackBarrier is executed AND the goroutine it was executed onto contains a call to main.bottomUpTree
|
// We want to get a user goroutine with a stack barrier, to get that we execute the program until runtime.gcInstallStackBarrier is executed AND the goroutine it was executed onto contains a call to main.bottomUpTree
|
||||||
_, err := setFunctionBreakpoint(p, "runtime.gcInstallStackBarrier")
|
_, err := setFunctionBreakpoint(p, "runtime.gcInstallStackBarrier")
|
||||||
assertNoError(err, t, "setFunctionBreakpoint()")
|
assertNoError(err, t, "setFunctionBreakpoint()")
|
||||||
@ -2664,7 +2663,7 @@ func TestAttachDetach(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var p target.Interface
|
var p proc.Process
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch testBackend {
|
switch testBackend {
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
|
|
||||||
"github.com/derekparker/delve/pkg/proc"
|
"github.com/derekparker/delve/pkg/proc"
|
||||||
protest "github.com/derekparker/delve/pkg/proc/test"
|
protest "github.com/derekparker/delve/pkg/proc/test"
|
||||||
"github.com/derekparker/delve/pkg/target"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIssue419(t *testing.T) {
|
func TestIssue419(t *testing.T) {
|
||||||
@ -19,7 +18,7 @@ func TestIssue419(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// SIGINT directed at the inferior should be passed along not swallowed by delve
|
// SIGINT directed at the inferior should be passed along not swallowed by delve
|
||||||
withTestProcess("issue419", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("issue419", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
_, err := setFunctionBreakpoint(p, "main.main")
|
_, err := setFunctionBreakpoint(p, "main.main")
|
||||||
assertNoError(err, t, "SetBreakpoint()")
|
assertNoError(err, t, "SetBreakpoint()")
|
||||||
assertNoError(proc.Continue(p), t, "Continue()")
|
assertNoError(proc.Continue(p), t, "Continue()")
|
||||||
|
@ -23,7 +23,7 @@ type Registers interface {
|
|||||||
// GAddr returns the address of the G variable if it is known, 0 and false otherwise
|
// GAddr returns the address of the G variable if it is known, 0 and false otherwise
|
||||||
GAddr() (uint64, bool)
|
GAddr() (uint64, bool)
|
||||||
Get(int) (uint64, error)
|
Get(int) (uint64, error)
|
||||||
SetPC(IThread, uint64) error
|
SetPC(Thread, uint64) error
|
||||||
Slice() []Register
|
Slice() []Register
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ type Stackframe struct {
|
|||||||
|
|
||||||
// Stacktrace returns the stack trace for thread.
|
// Stacktrace returns the stack trace for thread.
|
||||||
// Note the locations in the array are return addresses not call addresses.
|
// Note the locations in the array are return addresses not call addresses.
|
||||||
func ThreadStacktrace(thread IThread, depth int) ([]Stackframe, error) {
|
func ThreadStacktrace(thread Thread, depth int) ([]Stackframe, error) {
|
||||||
regs, err := thread.Registers(false)
|
regs, err := thread.Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"golang.org/x/debug/dwarf"
|
"golang.org/x/debug/dwarf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IThread represents a thread.
|
// Thread represents a thread.
|
||||||
type IThread interface {
|
type Thread interface {
|
||||||
MemoryReadWriter
|
MemoryReadWriter
|
||||||
Location() (*Location, error)
|
Location() (*Location, error)
|
||||||
// Breakpoint will return the breakpoint that this thread is stopped at or
|
// Breakpoint will return the breakpoint that this thread is stopped at or
|
||||||
@ -52,7 +52,7 @@ func (tbe ThreadBlockedError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns topmost frame of g or thread if g is nil
|
// returns topmost frame of g or thread if g is nil
|
||||||
func topframe(g *G, thread IThread) (Stackframe, error) {
|
func topframe(g *G, thread Thread) (Stackframe, error) {
|
||||||
var frames []Stackframe
|
var frames []Stackframe
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ func topframe(g *G, thread IThread) (Stackframe, error) {
|
|||||||
// a breakpoint of kind StepBreakpoint is set on the CALL instruction,
|
// a breakpoint of kind StepBreakpoint is set on the CALL instruction,
|
||||||
// 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 next(dbp Continuable, stepInto bool) error {
|
func next(dbp Process, stepInto bool) error {
|
||||||
selg := dbp.SelectedGoroutine()
|
selg := dbp.SelectedGoroutine()
|
||||||
curthread := dbp.CurrentThread()
|
curthread := dbp.CurrentThread()
|
||||||
topframe, err := topframe(selg, curthread)
|
topframe, err := topframe(selg, curthread)
|
||||||
@ -206,7 +206,7 @@ func next(dbp Continuable, stepInto bool) error {
|
|||||||
return setInternalBreakpoints(dbp, topframe.Current.PC, pcs, NextBreakpoint, cond)
|
return setInternalBreakpoints(dbp, topframe.Current.PC, pcs, NextBreakpoint, cond)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setStepIntoBreakpoint(dbp Continuable, text []AsmInstruction, cond ast.Expr) error {
|
func setStepIntoBreakpoint(dbp Process, text []AsmInstruction, cond ast.Expr) error {
|
||||||
if len(text) <= 0 {
|
if len(text) <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ func setStepIntoBreakpoint(dbp Continuable, text []AsmInstruction, cond ast.Expr
|
|||||||
|
|
||||||
// setInternalBreakpoints sets a breakpoint to all addresses specified in pcs
|
// setInternalBreakpoints sets a breakpoint to all addresses specified in pcs
|
||||||
// skipping over curpc and curpc-1
|
// skipping over curpc and curpc-1
|
||||||
func setInternalBreakpoints(dbp Continuable, curpc uint64, pcs []uint64, kind BreakpointKind, cond ast.Expr) error {
|
func setInternalBreakpoints(dbp Process, curpc uint64, pcs []uint64, kind BreakpointKind, cond ast.Expr) error {
|
||||||
for i := range pcs {
|
for i := range pcs {
|
||||||
if pcs[i] == curpc || pcs[i] == curpc-1 {
|
if pcs[i] == curpc || pcs[i] == curpc-1 {
|
||||||
continue
|
continue
|
||||||
@ -263,7 +263,7 @@ func setInternalBreakpoints(dbp Continuable, curpc uint64, pcs []uint64, kind Br
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGVariable(thread IThread) (*Variable, error) {
|
func getGVariable(thread Thread) (*Variable, error) {
|
||||||
arch := thread.Arch()
|
arch := thread.Arch()
|
||||||
regs, err := thread.Registers(false)
|
regs, err := thread.Registers(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -289,7 +289,7 @@ func getGVariable(thread IThread) (*Variable, error) {
|
|||||||
return newGVariable(thread, uintptr(gaddr), arch.DerefTLS())
|
return newGVariable(thread, uintptr(gaddr), arch.DerefTLS())
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGVariable(thread IThread, gaddr uintptr, deref bool) (*Variable, error) {
|
func newGVariable(thread Thread, gaddr uintptr, deref bool) (*Variable, error) {
|
||||||
typ, err := thread.BinInfo().findType("runtime.g")
|
typ, err := thread.BinInfo().findType("runtime.g")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -320,7 +320,7 @@ func newGVariable(thread IThread, gaddr uintptr, deref bool) (*Variable, error)
|
|||||||
//
|
//
|
||||||
// In order to get around all this craziness, we read the address of the G structure for
|
// In order to get around all this craziness, we read the address of the G structure for
|
||||||
// the current thread from the thread local storage area.
|
// the current thread from the thread local storage area.
|
||||||
func GetG(thread IThread) (g *G, err error) {
|
func GetG(thread Thread) (g *G, err error) {
|
||||||
gaddr, err := getGVariable(thread)
|
gaddr, err := getGVariable(thread)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -337,7 +337,7 @@ func GetG(thread IThread) (g *G, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ThreadScope returns an EvalScope for this thread.
|
// ThreadScope returns an EvalScope for this thread.
|
||||||
func ThreadScope(thread IThread) (*EvalScope, error) {
|
func ThreadScope(thread Thread) (*EvalScope, error) {
|
||||||
locations, err := ThreadStacktrace(thread, 0)
|
locations, err := ThreadStacktrace(thread, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -349,7 +349,7 @@ func ThreadScope(thread IThread) (*EvalScope, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GoroutineScope returns an EvalScope for the goroutine running on this thread.
|
// GoroutineScope returns an EvalScope for the goroutine running on this thread.
|
||||||
func GoroutineScope(thread IThread) (*EvalScope, error) {
|
func GoroutineScope(thread Thread) (*EvalScope, error) {
|
||||||
locations, err := ThreadStacktrace(thread, 0)
|
locations, err := ThreadStacktrace(thread, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -364,7 +364,7 @@ func GoroutineScope(thread IThread) (*EvalScope, error) {
|
|||||||
return &EvalScope{locations[0].Current.PC, locations[0].CFA, thread, gvar, thread.BinInfo()}, nil
|
return &EvalScope{locations[0].Current.PC, locations[0].CFA, thread, gvar, thread.BinInfo()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func onRuntimeBreakpoint(thread IThread) bool {
|
func onRuntimeBreakpoint(thread Thread) bool {
|
||||||
loc, err := thread.Location()
|
loc, err := thread.Location()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -373,7 +373,7 @@ func onRuntimeBreakpoint(thread IThread) 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 onNextGoroutine(thread IThread, breakpoints map[uint64]*Breakpoint) (bool, error) {
|
func onNextGoroutine(thread Thread, breakpoints map[uint64]*Breakpoint) (bool, error) {
|
||||||
var bp *Breakpoint
|
var bp *Breakpoint
|
||||||
for i := range breakpoints {
|
for i := range breakpoints {
|
||||||
if breakpoints[i].Internal() {
|
if breakpoints[i].Internal() {
|
||||||
|
@ -129,7 +129,7 @@ type G struct {
|
|||||||
CurrentLoc Location
|
CurrentLoc Location
|
||||||
|
|
||||||
// Thread that this goroutine is currently allocated to
|
// Thread that this goroutine is currently allocated to
|
||||||
Thread IThread
|
Thread Thread
|
||||||
|
|
||||||
variable *Variable
|
variable *Variable
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ func (scope *EvalScope) newVariable(name string, addr uintptr, dwarfType dwarf.T
|
|||||||
return newVariable(name, addr, dwarfType, scope.BinInfo, scope.Mem)
|
return newVariable(name, addr, dwarfType, scope.BinInfo, scope.Mem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVariableFromThread(t IThread, name string, addr uintptr, dwarfType dwarf.Type) *Variable {
|
func newVariableFromThread(t Thread, name string, addr uintptr, dwarfType dwarf.Type) *Variable {
|
||||||
return newVariable(name, addr, dwarfType, t.BinInfo(), t)
|
return newVariable(name, addr, dwarfType, t.BinInfo(), t)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ func (gvar *Variable) parseG() (*G, error) {
|
|||||||
}
|
}
|
||||||
if gaddr == 0 {
|
if gaddr == 0 {
|
||||||
id := 0
|
id := 0
|
||||||
if thread, ok := mem.(IThread); ok {
|
if thread, ok := mem.(Thread); ok {
|
||||||
id = thread.ThreadID()
|
id = thread.ThreadID()
|
||||||
}
|
}
|
||||||
return nil, NoGError{tid: id}
|
return nil, NoGError{tid: id}
|
||||||
|
@ -47,7 +47,7 @@ func ConvertBreakpoint(bp *proc.Breakpoint) *Breakpoint {
|
|||||||
|
|
||||||
// ConvertThread converts a proc.Thread into an
|
// ConvertThread converts a proc.Thread into an
|
||||||
// api thread.
|
// api thread.
|
||||||
func ConvertThread(th proc.IThread) *Thread {
|
func ConvertThread(th proc.Thread) *Thread {
|
||||||
var (
|
var (
|
||||||
function *Function
|
function *Function
|
||||||
file string
|
file string
|
||||||
|
@ -17,7 +17,6 @@ import (
|
|||||||
"github.com/derekparker/delve/pkg/proc/core"
|
"github.com/derekparker/delve/pkg/proc/core"
|
||||||
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
||||||
"github.com/derekparker/delve/pkg/proc/native"
|
"github.com/derekparker/delve/pkg/proc/native"
|
||||||
"github.com/derekparker/delve/pkg/target"
|
|
||||||
"github.com/derekparker/delve/service/api"
|
"github.com/derekparker/delve/service/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ type Debugger struct {
|
|||||||
config *Config
|
config *Config
|
||||||
// TODO(DO NOT MERGE WITHOUT) rename to targetMutex
|
// TODO(DO NOT MERGE WITHOUT) rename to targetMutex
|
||||||
processMutex sync.Mutex
|
processMutex sync.Mutex
|
||||||
target target.Interface
|
target proc.Process
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config provides the configuration to start a Debugger.
|
// Config provides the configuration to start a Debugger.
|
||||||
@ -100,7 +99,7 @@ func New(config *Config) (*Debugger, error) {
|
|||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Debugger) Launch(processArgs []string, wd string) (target.Interface, error) {
|
func (d *Debugger) Launch(processArgs []string, wd string) (proc.Process, error) {
|
||||||
switch d.config.Backend {
|
switch d.config.Backend {
|
||||||
case "native":
|
case "native":
|
||||||
return native.Launch(processArgs, wd)
|
return native.Launch(processArgs, wd)
|
||||||
@ -121,7 +120,7 @@ func (d *Debugger) Launch(processArgs []string, wd string) (target.Interface, er
|
|||||||
// the target's executable.
|
// the target's executable.
|
||||||
var ErrNoAttachPath = errors.New("must specify executable path on macOS")
|
var ErrNoAttachPath = errors.New("must specify executable path on macOS")
|
||||||
|
|
||||||
func (d *Debugger) Attach(pid int, path string) (target.Interface, error) {
|
func (d *Debugger) Attach(pid int, path string) (proc.Process, error) {
|
||||||
switch d.config.Backend {
|
switch d.config.Backend {
|
||||||
case "native":
|
case "native":
|
||||||
return native.Attach(pid)
|
return native.Attach(pid)
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/derekparker/delve/pkg/proc"
|
"github.com/derekparker/delve/pkg/proc"
|
||||||
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
"github.com/derekparker/delve/pkg/proc/gdbserial"
|
||||||
"github.com/derekparker/delve/pkg/proc/native"
|
"github.com/derekparker/delve/pkg/proc/native"
|
||||||
"github.com/derekparker/delve/pkg/target"
|
|
||||||
"github.com/derekparker/delve/service/api"
|
"github.com/derekparker/delve/service/api"
|
||||||
|
|
||||||
protest "github.com/derekparker/delve/pkg/proc/test"
|
protest "github.com/derekparker/delve/pkg/proc/test"
|
||||||
@ -56,7 +55,7 @@ func assertVariable(t *testing.T, variable *proc.Variable, expected varTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalVariable(p target.Interface, symbol string, cfg proc.LoadConfig) (*proc.Variable, error) {
|
func evalVariable(p proc.Process, symbol string, cfg proc.LoadConfig) (*proc.Variable, error) {
|
||||||
scope, err := proc.GoroutineScope(p.CurrentThread())
|
scope, err := proc.GoroutineScope(p.CurrentThread())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -70,7 +69,7 @@ func (tc *varTest) alternateVarTest() varTest {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func setVariable(p target.Interface, symbol, value string) error {
|
func setVariable(p proc.Process, symbol, value string) error {
|
||||||
scope, err := proc.GoroutineScope(p.CurrentThread())
|
scope, err := proc.GoroutineScope(p.CurrentThread())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -80,9 +79,9 @@ func setVariable(p target.Interface, symbol, value string) error {
|
|||||||
|
|
||||||
const varTestBreakpointLineNumber = 59
|
const varTestBreakpointLineNumber = 59
|
||||||
|
|
||||||
func withTestProcess(name string, t *testing.T, fn func(p target.Interface, fixture protest.Fixture)) {
|
func withTestProcess(name string, t *testing.T, fn func(p proc.Process, fixture protest.Fixture)) {
|
||||||
fixture := protest.BuildFixture(name)
|
fixture := protest.BuildFixture(name)
|
||||||
var p target.Interface
|
var p proc.Process
|
||||||
var err error
|
var err error
|
||||||
switch testBackend {
|
switch testBackend {
|
||||||
case "native":
|
case "native":
|
||||||
@ -149,7 +148,7 @@ func TestVariableEvaluation(t *testing.T) {
|
|||||||
{"NonExistent", true, "", "", "", fmt.Errorf("could not find symbol value for NonExistent")},
|
{"NonExistent", true, "", "", "", fmt.Errorf("could not find symbol value for NonExistent")},
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue() returned an error")
|
assertNoError(err, t, "Continue() returned an error")
|
||||||
|
|
||||||
@ -227,7 +226,7 @@ func TestVariableEvaluationShort(t *testing.T) {
|
|||||||
{"NonExistent", true, "", "", "", fmt.Errorf("could not find symbol value for NonExistent")},
|
{"NonExistent", true, "", "", "", fmt.Errorf("could not find symbol value for NonExistent")},
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue() returned an error")
|
assertNoError(err, t, "Continue() returned an error")
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ func TestMultilineVariableEvaluation(t *testing.T) {
|
|||||||
Nest: *(*main.Nest)(…`, "", "main.Nest", nil},
|
Nest: *(*main.Nest)(…`, "", "main.Nest", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue() returned an error")
|
assertNoError(err, t, "Continue() returned an error")
|
||||||
|
|
||||||
@ -355,7 +354,7 @@ func TestLocalVariables(t *testing.T) {
|
|||||||
{"baz", true, "\"bazburzum\"", "", "string", nil}}},
|
{"baz", true, "\"bazburzum\"", "", "string", nil}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue() returned an error")
|
assertNoError(err, t, "Continue() returned an error")
|
||||||
|
|
||||||
@ -379,7 +378,7 @@ func TestLocalVariables(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEmbeddedStruct(t *testing.T) {
|
func TestEmbeddedStruct(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
testcases := []varTest{
|
testcases := []varTest{
|
||||||
{"b.val", true, "-314", "-314", "int", nil},
|
{"b.val", true, "-314", "-314", "int", nil},
|
||||||
{"b.A.val", true, "-314", "-314", "int", nil},
|
{"b.A.val", true, "-314", "-314", "int", nil},
|
||||||
@ -409,7 +408,7 @@ func TestEmbeddedStruct(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestComplexSetting(t *testing.T) {
|
func TestComplexSetting(t *testing.T) {
|
||||||
withTestProcess("testvariables", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
err := proc.Continue(p)
|
err := proc.Continue(p)
|
||||||
assertNoError(err, t, "Continue() returned an error")
|
assertNoError(err, t, "Continue() returned an error")
|
||||||
|
|
||||||
@ -655,7 +654,7 @@ func TestEvalExpression(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
for _, tc := range testcases {
|
for _, tc := range testcases {
|
||||||
variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
|
variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
|
||||||
@ -679,7 +678,7 @@ func TestEvalExpression(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEvalAddrAndCast(t *testing.T) {
|
func TestEvalAddrAndCast(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
c1addr, err := evalVariable(p, "&c1", pnormalLoadConfig)
|
c1addr, err := evalVariable(p, "&c1", pnormalLoadConfig)
|
||||||
assertNoError(err, t, "EvalExpression(&c1)")
|
assertNoError(err, t, "EvalExpression(&c1)")
|
||||||
@ -705,7 +704,7 @@ func TestEvalAddrAndCast(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMapEvaluation(t *testing.T) {
|
func TestMapEvaluation(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
m1v, err := evalVariable(p, "m1", pnormalLoadConfig)
|
m1v, err := evalVariable(p, "m1", pnormalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable()")
|
assertNoError(err, t, "EvalVariable()")
|
||||||
@ -739,7 +738,7 @@ func TestMapEvaluation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUnsafePointer(t *testing.T) {
|
func TestUnsafePointer(t *testing.T) {
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
up1v, err := evalVariable(p, "up1", pnormalLoadConfig)
|
up1v, err := evalVariable(p, "up1", pnormalLoadConfig)
|
||||||
assertNoError(err, t, "EvalVariable(up1)")
|
assertNoError(err, t, "EvalVariable(up1)")
|
||||||
@ -776,7 +775,7 @@ func TestIssue426(t *testing.T) {
|
|||||||
|
|
||||||
// Serialization of type expressions (go/ast.Expr) containing anonymous structs or interfaces
|
// Serialization of type expressions (go/ast.Expr) containing anonymous structs or interfaces
|
||||||
// differs from the serialization used by the linker to produce DWARF type information
|
// differs from the serialization used by the linker to produce DWARF type information
|
||||||
withTestProcess("testvariables2", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("testvariables2", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
v, err := evalVariable(p, testcase.name, pnormalLoadConfig)
|
v, err := evalVariable(p, testcase.name, pnormalLoadConfig)
|
||||||
@ -827,7 +826,7 @@ func TestPackageRenames(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess("pkgrenames", t, func(p target.Interface, fixture protest.Fixture) {
|
withTestProcess("pkgrenames", t, func(p proc.Process, fixture protest.Fixture) {
|
||||||
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
assertNoError(proc.Continue(p), t, "Continue() returned an error")
|
||||||
for _, tc := range testcases {
|
for _, tc := range testcases {
|
||||||
variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
|
variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
|
||||||
|
Loading…
Reference in New Issue
Block a user