proc: refactor Continue to work on any Process implementation

This commit is contained in:
aarzilli 2017-02-22 09:35:21 +01:00 committed by Derek Parker
parent 510b7db2a7
commit 3dacc25d2e
11 changed files with 326 additions and 284 deletions

@ -107,7 +107,7 @@ func (dbp *Process) writeSoftwareBreakpoint(thread *Thread, addr uint64) error {
return err return err
} }
func (bp *Breakpoint) checkCondition(thread *Thread) (bool, error) { func (bp *Breakpoint) checkCondition(thread IThread) (bool, error) {
if bp.Cond == nil { if bp.Cond == nil {
return true, nil return true, nil
} }

@ -1,6 +1,7 @@
package proc package proc
import ( import (
"debug/gosym"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@ -319,17 +320,17 @@ func (dbp *Process) Status() *WaitStatus {
} }
// Next continues execution until the next source line. // Next continues execution until the next source line.
func (dbp *Process) Next() (err error) { func Next(dbp Continuable) (err error) {
if dbp.exited { if dbp.Exited() {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
for i := range dbp.breakpoints { for _, bp := range dbp.Breakpoints() {
if dbp.breakpoints[i].Internal() { if bp.Internal() {
return fmt.Errorf("next while nexting") return fmt.Errorf("next while nexting")
} }
} }
if err = dbp.next(false); err != nil { if err = next(dbp, false); err != nil {
switch err.(type) { switch err.(type) {
case ThreadBlockedError, NoReturnAddr: // Noop case ThreadBlockedError, NoReturnAddr: // Noop
default: default:
@ -338,19 +339,16 @@ func (dbp *Process) Next() (err error) {
} }
} }
return dbp.Continue() return Continue(dbp)
} }
// Continue continues execution of the debugged func (dbp *Process) ContinueOnce() (IThread, error) {
// process. It will continue until it hits a breakpoint
// or is otherwise stopped.
func (dbp *Process) Continue() error {
if dbp.exited { if dbp.exited {
return &ProcessExitedError{} return nil, &ProcessExitedError{}
} }
for {
if err := dbp.resume(); err != nil { if err := dbp.resume(); err != nil {
return err return nil, err
} }
dbp.allGCache = nil dbp.allGCache = nil
@ -360,69 +358,100 @@ func (dbp *Process) Continue() error {
trapthread, err := dbp.trapWait(-1) trapthread, err := dbp.trapWait(-1)
if err != nil { if err != nil {
return err return nil, err
} }
if err := dbp.Halt(); err != nil { if err := dbp.Halt(); err != nil {
return dbp.exitGuard(err) return nil, dbp.exitGuard(err)
} }
if err := dbp.setCurrentBreakpoints(trapthread); err != nil { if err := dbp.setCurrentBreakpoints(trapthread); err != nil {
return err return nil, err
} }
if err := dbp.pickCurrentThread(trapthread); err != nil { return trapthread, err
}
// 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
// process. It will continue until it hits a breakpoint
// or is otherwise stopped.
func Continue(dbp Continuable) error {
for {
trapthread, err := dbp.ContinueOnce()
if err != nil {
return err return err
} }
threads := dbp.ThreadList()
if err := pickCurrentThread(dbp, trapthread, threads); err != nil {
return err
}
curthread := dbp.CurrentThread()
curbp, curbpActive, _ := curthread.Breakpoint()
switch { switch {
case dbp.currentThread.CurrentBreakpoint == nil: case curbp == nil:
// runtime.Breakpoint or manual stop // runtime.Breakpoint or manual stop
if dbp.currentThread.onRuntimeBreakpoint() { if onRuntimeBreakpoint(curthread) {
// Single-step current thread until we exit runtime.breakpoint and // Single-step current thread until we exit runtime.breakpoint and
// runtime.Breakpoint. // runtime.Breakpoint.
// On go < 1.8 it was sufficient to single-step twice on go1.8 a change // On go < 1.8 it was sufficient to single-step twice on go1.8 a change
// to the compiler requires 4 steps. // to the compiler requires 4 steps.
for { for {
if err = dbp.currentThread.StepInstruction(); err != nil { if err = curthread.StepInstruction(); err != nil {
return err return err
} }
loc, err := dbp.currentThread.Location() loc, err := curthread.Location()
if err != nil || loc.Fn == nil || (loc.Fn.Name != "runtime.breakpoint" && loc.Fn.Name != "runtime.Breakpoint") { if err != nil || loc.Fn == nil || (loc.Fn.Name != "runtime.breakpoint" && loc.Fn.Name != "runtime.Breakpoint") {
break break
} }
} }
} }
return dbp.conditionErrors() return conditionErrors(threads)
case dbp.currentThread.onTriggeredInternalBreakpoint(): case curbpActive && curbp.Internal():
if dbp.currentThread.CurrentBreakpoint.Kind == StepBreakpoint { if curbp.Kind == StepBreakpoint {
// See description of proc.(*Process).next for the meaning of StepBreakpoints // See description of proc.(*Process).next for the meaning of StepBreakpoints
if err := dbp.conditionErrors(); err != nil { if err := conditionErrors(threads); err != nil {
return err return err
} }
pc, err := dbp.currentThread.PC() regs, err := curthread.Registers(false)
if err != nil { if err != nil {
return err return err
} }
regs, err := dbp.currentThread.Registers(false) pc := regs.PC()
if err != nil { text, err := disassemble(curthread, regs, dbp.Breakpoints(), dbp.BinInfo(), pc, pc+maxInstructionLength)
return err
}
text, err := disassemble(dbp.currentThread, regs, dbp.breakpoints, dbp.BinInfo(), pc, pc+maxInstructionLength)
if err != nil { if err != nil {
return err return err
} }
// here we either set a breakpoint into the destination of the CALL // here we either set a breakpoint into the destination of the CALL
// instruction or we determined that the called function is hidden, // instruction or we determined that the called function is hidden,
// either way we need to resume execution // either way we need to resume execution
if err = dbp.setStepIntoBreakpoint(text, sameGoroutineCondition(dbp.selectedGoroutine)); err != nil { if err = setStepIntoBreakpoint(dbp, text, sameGoroutineCondition(dbp.SelectedGoroutine())); err != nil {
return err return err
} }
} else { } else {
if err := dbp.ClearInternalBreakpoints(); err != nil { if err := dbp.ClearInternalBreakpoints(); err != nil {
return err return err
} }
return dbp.conditionErrors() return conditionErrors(threads)
} }
case dbp.currentThread.onTriggeredBreakpoint(): case curbpActive:
onNextGoroutine, err := dbp.currentThread.onNextGoroutine() onNextGoroutine, err := onNextGoroutine(curthread, dbp.Breakpoints())
if err != nil { if err != nil {
return err return err
} }
@ -432,19 +461,19 @@ func (dbp *Process) Continue() error {
return err return err
} }
} }
return dbp.conditionErrors() return conditionErrors(threads)
default: default:
// not a manual stop, not on runtime.Breakpoint, not on a breakpoint, just repeat // not a manual stop, not on runtime.Breakpoint, not on a breakpoint, just repeat
} }
} }
} }
func (dbp *Process) conditionErrors() error { func conditionErrors(threads []IThread) error {
var condErr error var condErr error
for _, th := range dbp.threads { for _, th := range threads {
if th.CurrentBreakpoint != nil && th.BreakpointConditionError != nil { if bp, _, bperr := th.Breakpoint(); bp != nil && bperr != nil {
if condErr == nil { if condErr == nil {
condErr = th.BreakpointConditionError condErr = bperr
} else { } else {
return fmt.Errorf("multiple errors evaluating conditions") return fmt.Errorf("multiple errors evaluating conditions")
} }
@ -457,36 +486,36 @@ func (dbp *Process) conditionErrors() 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 (dbp *Process) pickCurrentThread(trapthread *Thread) error { func pickCurrentThread(dbp Continuable, trapthread IThread, threads []IThread) error {
for _, th := range dbp.threads { for _, th := range threads {
if th.onTriggeredInternalBreakpoint() { if bp, active, _ := th.Breakpoint(); active && bp.Internal() {
return dbp.SwitchThread(th.ID) return dbp.SwitchThread(th.ThreadID())
} }
} }
if trapthread.onTriggeredBreakpoint() { if _, active, _ := trapthread.Breakpoint(); active {
return dbp.SwitchThread(trapthread.ID) return dbp.SwitchThread(trapthread.ThreadID())
} }
for _, th := range dbp.threads { for _, th := range threads {
if th.onTriggeredBreakpoint() { if _, active, _ := th.Breakpoint(); active {
return dbp.SwitchThread(th.ID) return dbp.SwitchThread(th.ThreadID())
} }
} }
return dbp.SwitchThread(trapthread.ID) return dbp.SwitchThread(trapthread.ThreadID())
} }
// 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 (dbp *Process) Step() (err error) { func Step(dbp Continuable) (err error) {
if dbp.exited { if dbp.Exited() {
return &ProcessExitedError{} return &ProcessExitedError{}
} }
for i := range dbp.breakpoints { for _, bp := range dbp.Breakpoints() {
if dbp.breakpoints[i].Internal() { if bp.Internal() {
return fmt.Errorf("next while nexting") return fmt.Errorf("next while nexting")
} }
} }
if err = dbp.next(true); err != nil { if err = next(dbp, true); err != nil {
switch err.(type) { switch err.(type) {
case ThreadBlockedError, NoReturnAddr: // Noop case ThreadBlockedError, NoReturnAddr: // Noop
default: default:
@ -495,7 +524,7 @@ func (dbp *Process) Step() (err error) {
} }
} }
return dbp.Continue() return Continue(dbp)
} }
// Returns an expression that evaluates to true when the current goroutine is g // Returns an expression that evaluates to true when the current goroutine is g
@ -529,7 +558,7 @@ func (dbp *Process) StepInstruction() (err error) {
if _, err := dbp.SetBreakpoint(dbp.selectedGoroutine.PC, NextBreakpoint, sameGoroutineCondition(dbp.selectedGoroutine)); err != nil { if _, err := dbp.SetBreakpoint(dbp.selectedGoroutine.PC, NextBreakpoint, sameGoroutineCondition(dbp.selectedGoroutine)); err != nil {
return err return err
} }
return dbp.Continue() return Continue(dbp)
} }
dbp.allGCache = nil dbp.allGCache = nil
if dbp.exited { if dbp.exited {
@ -545,10 +574,12 @@ func (dbp *Process) StepInstruction() (err error) {
// StepOut will continue until the current goroutine exits the // StepOut will continue until the current goroutine exits the
// function currently being executed or a deferred function is executed // function currently being executed or a deferred function is executed
func (dbp *Process) StepOut() error { func StepOut(dbp Continuable) error {
cond := sameGoroutineCondition(dbp.selectedGoroutine) selg := dbp.SelectedGoroutine()
curthread := dbp.CurrentThread()
cond := sameGoroutineCondition(selg)
topframe, err := topframe(dbp.selectedGoroutine, dbp.currentThread) topframe, err := topframe(selg, curthread)
if err != nil { if err != nil {
return err return err
} }
@ -557,10 +588,10 @@ func (dbp *Process) StepOut() error {
var deferpc uint64 = 0 var deferpc uint64 = 0
if filepath.Ext(topframe.Current.File) == ".go" { if filepath.Ext(topframe.Current.File) == ".go" {
if dbp.selectedGoroutine != nil { if selg != nil {
deferPCEntry := dbp.selectedGoroutine.DeferPC() deferPCEntry := selg.DeferPC()
if deferPCEntry != 0 { if deferPCEntry != 0 {
_, _, deferfn := dbp.bi.goSymTable.PCToLine(deferPCEntry) _, _, deferfn := dbp.BinInfo().PCToLine(deferPCEntry)
deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false) deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false)
if err != nil { if err != nil {
return err return err
@ -591,12 +622,12 @@ func (dbp *Process) StepOut() error {
} }
if topframe.Ret != 0 { if topframe.Ret != 0 {
if err := dbp.setInternalBreakpoints(topframe.Current.PC, []uint64{topframe.Ret}, NextBreakpoint, cond); err != nil { if err := setInternalBreakpoints(dbp, topframe.Current.PC, []uint64{topframe.Ret}, NextBreakpoint, cond); err != nil {
return err return err
} }
} }
return dbp.Continue() return Continue(dbp)
} }
// SwitchThread changes from current thread to the thread specified by `tid`. // SwitchThread changes from current thread to the thread specified by `tid`.
@ -633,29 +664,42 @@ func (dbp *Process) SwitchGoroutine(gid int) error {
return nil return nil
} }
// If the argument of GoroutinesInfo implements AllGCache GoroutinesInfo
// will use the pointer returned by AllGCache as a cache.
type AllGCache interface {
AllGCache() *[]*G
}
func (dbp *Process) AllGCache() *[]*G {
return &dbp.allGCache
}
// 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 (dbp *Process) GoroutinesInfo() ([]*G, error) { func GoroutinesInfo(dbp EvalScopeConvertible) ([]*G, error) {
if dbp.exited { if dbp.Exited() {
return nil, &ProcessExitedError{} return nil, &ProcessExitedError{}
} }
if dbp.allGCache != nil { if dbp, ok := dbp.(AllGCache); ok {
return dbp.allGCache, nil if allGCache := dbp.AllGCache(); *allGCache != nil {
return *allGCache, nil
}
} }
var ( var (
threadg = map[int]*Thread{} threadg = map[int]IThread{}
allg []*G allg []*G
rdr = dbp.bi.DwarfReader() rdr = dbp.BinInfo().DwarfReader()
) )
for i := range dbp.threads { threads := dbp.ThreadList()
if dbp.threads[i].blocked() { for _, th := range threads {
if threadBlocked(th) {
continue continue
} }
g, _ := GetG(dbp.threads[i]) g, _ := GetG(th)
if g != nil { if g != nil {
threadg[g.ID] = dbp.threads[i] threadg[g.ID] = th
} }
} }
@ -663,7 +707,7 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
allglenBytes, err := dbp.currentThread.readMemory(uintptr(addr), 8) allglenBytes, err := dbp.CurrentThread().readMemory(uintptr(addr), 8)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -678,11 +722,11 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
return nil, err return nil, err
} }
} }
faddr, err := dbp.currentThread.readMemory(uintptr(allgentryaddr), dbp.bi.arch.PtrSize()) faddr, err := dbp.CurrentThread().readMemory(uintptr(allgentryaddr), dbp.BinInfo().arch.PtrSize())
allgptr := binary.LittleEndian.Uint64(faddr) allgptr := binary.LittleEndian.Uint64(faddr)
for i := uint64(0); i < allglen; i++ { for i := uint64(0); i < allglen; i++ {
gvar, err := newGVariable(dbp.currentThread, uintptr(allgptr+(i*uint64(dbp.bi.arch.PtrSize()))), true) gvar, err := newGVariable(dbp.CurrentThread(), uintptr(allgptr+(i*uint64(dbp.BinInfo().arch.PtrSize()))), true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -703,7 +747,11 @@ func (dbp *Process) GoroutinesInfo() ([]*G, error) {
allg = append(allg, g) allg = append(allg, g)
} }
} }
dbp.allGCache = allg if dbp, ok := dbp.(AllGCache); ok {
allGCache := dbp.AllGCache()
*allGCache = allg
}
return allg, nil return allg, nil
} }
@ -884,19 +932,14 @@ func (scope *EvalScope) getGoInformation() (ver GoVersion, isextld bool, err err
return return
} }
type GoroutinesInfo interface {
SelectedGoroutine() *G
GoroutinesInfo() ([]*G, 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 GoroutinesInfo, gid int) (*G, error) { func FindGoroutine(dbp EvalScopeConvertible, gid int) (*G, error) {
if gid == -1 { if gid == -1 {
return dbp.SelectedGoroutine(), nil return dbp.SelectedGoroutine(), nil
} }
gs, err := dbp.GoroutinesInfo() gs, err := GoroutinesInfo(dbp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -911,9 +954,11 @@ func FindGoroutine(dbp GoroutinesInfo, gid int) (*G, error) {
// EvalScopeConvertible is a subset of target.Interface with the methods // EvalScopeConvertible is a subset of target.Interface with the methods
// used by ConvertEvalScope/GoroutinesInfo/etc. // used by ConvertEvalScope/GoroutinesInfo/etc.
type EvalScopeConvertible interface { type EvalScopeConvertible interface {
GoroutinesInfo Exited() bool
SelectedGoroutine() *G
CurrentThread() IThread CurrentThread() IThread
BinInfo() *BinaryInfo BinInfo() *BinaryInfo
ThreadList() []IThread
} }
// ConvertEvalScope returns a new EvalScope in the context of the // ConvertEvalScope returns a new EvalScope in the context of the

@ -101,7 +101,7 @@ func currentLineNumber(p *Process, t *testing.T) (string, int) {
func TestExit(t *testing.T) { func TestExit(t *testing.T) {
withTestProcess("continuetestprog", t, func(p *Process, fixture protest.Fixture) { withTestProcess("continuetestprog", t, func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := Continue(p)
pe, ok := err.(ProcessExitedError) pe, ok := err.(ProcessExitedError)
if !ok { if !ok {
t.Fatalf("Continue() returned unexpected error type %s", err) t.Fatalf("Continue() returned unexpected error type %s", err)
@ -119,8 +119,8 @@ func TestExitAfterContinue(t *testing.T) {
withTestProcess("continuetestprog", t, func(p *Process, fixture protest.Fixture) { withTestProcess("continuetestprog", t, func(p *Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "main.sayhi") _, err := setFunctionBreakpoint(p, "main.sayhi")
assertNoError(err, t, "setFunctionBreakpoint()") assertNoError(err, t, "setFunctionBreakpoint()")
assertNoError(p.Continue(), t, "First Continue()") assertNoError(Continue(p), t, "First Continue()")
err = p.Continue() err = Continue(p)
pe, ok := err.(ProcessExitedError) pe, ok := err.(ProcessExitedError)
if !ok { if !ok {
t.Fatalf("Continue() returned unexpected error type %s", pe) t.Fatalf("Continue() returned unexpected error type %s", pe)
@ -159,7 +159,7 @@ func TestHalt(t *testing.T) {
withTestProcess("loopprog", t, func(p *Process, fixture protest.Fixture) { withTestProcess("loopprog", t, func(p *Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "main.loop") _, err := setFunctionBreakpoint(p, "main.loop")
assertNoError(err, t, "SetBreakpoint") assertNoError(err, t, "SetBreakpoint")
assertNoError(p.Continue(), t, "Continue") assertNoError(Continue(p), t, "Continue")
for _, th := range p.threads { for _, th := range p.threads {
if th.running != false { if th.running != false {
t.Fatal("expected running = false for thread", th.ID) t.Fatal("expected running = false for thread", th.ID)
@ -178,7 +178,7 @@ func TestHalt(t *testing.T) {
} }
} }
}() }()
assertNoError(p.Continue(), t, "Continue") assertNoError(Continue(p), t, "Continue")
<-stopChan <-stopChan
// Loop through threads and make sure they are all // Loop through threads and make sure they are all
// actually stopped, err will not be nil if the process // actually stopped, err will not be nil if the process
@ -203,7 +203,7 @@ func TestStep(t *testing.T) {
_, err := p.SetBreakpoint(helloworldaddr, UserBreakpoint, nil) _, err := p.SetBreakpoint(helloworldaddr, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
regs := getRegisters(p, t) regs := getRegisters(p, t)
rip := regs.PC() rip := regs.PC()
@ -225,7 +225,7 @@ func TestBreakpoint(t *testing.T) {
bp, err := p.SetBreakpoint(helloworldaddr, UserBreakpoint, nil) bp, err := p.SetBreakpoint(helloworldaddr, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
pc, err := p.PC() pc, err := p.PC()
if err != nil { if err != nil {
@ -255,7 +255,7 @@ func TestBreakpointInSeperateGoRoutine(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
err = p.Continue() err = Continue(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -340,7 +340,7 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc
bp, err = p.SetBreakpoint(pc, UserBreakpoint, nil) bp, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
} }
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
p.currentThread.SetPC(bp.Addr) p.currentThread.SetPC(bp.Addr)
@ -353,9 +353,9 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc
switch contFunc { switch contFunc {
case contNext: case contNext:
assertNoError(p.Next(), t, "Next() returned an error") assertNoError(Next(p), t, "Next() returned an error")
case contStep: case contStep:
assertNoError(p.Step(), t, "Step() returned an error") assertNoError(Step(p), t, "Step() returned an error")
} }
f, ln = currentLineNumber(p, t) f, ln = currentLineNumber(p, t)
@ -427,7 +427,7 @@ func TestNextConcurrent(t *testing.T) {
withTestProcess("parallel_next", t, func(p *Process, fixture protest.Fixture) { withTestProcess("parallel_next", t, func(p *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(p.Continue(), t, "Continue") assertNoError(Continue(p), t, "Continue")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
initV, err := evalVariable(p, "n") initV, err := evalVariable(p, "n")
initVval, _ := constant.Int64Val(initV.Value) initVval, _ := constant.Int64Val(initV.Value)
@ -443,7 +443,7 @@ func TestNextConcurrent(t *testing.T) {
if ln != tc.begin { if ln != tc.begin {
t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln) t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln)
} }
assertNoError(p.Next(), t, "Next() returned an error") assertNoError(Next(p), t, "Next() returned an error")
f, ln = currentLineNumber(p, t) f, ln = currentLineNumber(p, t)
if ln != tc.end { if ln != tc.end {
t.Fatalf("Program did not continue to correct next location expected %d was %s:%d", tc.end, filepath.Base(f), ln) t.Fatalf("Program did not continue to correct next location expected %d was %s:%d", tc.end, filepath.Base(f), ln)
@ -468,7 +468,7 @@ func TestNextConcurrentVariant2(t *testing.T) {
withTestProcess("parallel_next", t, func(p *Process, fixture protest.Fixture) { withTestProcess("parallel_next", t, func(p *Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "main.sayhi") _, err := setFunctionBreakpoint(p, "main.sayhi")
assertNoError(err, t, "SetBreakpoint") assertNoError(err, t, "SetBreakpoint")
assertNoError(p.Continue(), t, "Continue") assertNoError(Continue(p), t, "Continue")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
initV, err := evalVariable(p, "n") initV, err := evalVariable(p, "n")
initVval, _ := constant.Int64Val(initV.Value) initVval, _ := constant.Int64Val(initV.Value)
@ -482,7 +482,7 @@ func TestNextConcurrentVariant2(t *testing.T) {
if ln != tc.begin { if ln != tc.begin {
t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln) t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln)
} }
assertNoError(p.Next(), t, "Next() returned an error") assertNoError(Next(p), t, "Next() returned an error")
var vval int64 var vval int64
for { for {
v, err := evalVariable(p, "n") v, err := evalVariable(p, "n")
@ -497,7 +497,7 @@ func TestNextConcurrentVariant2(t *testing.T) {
if vval == initVval { if vval == initVval {
t.Fatal("Initial breakpoint triggered twice for the same goroutine") t.Fatal("Initial breakpoint triggered twice for the same goroutine")
} }
assertNoError(p.Continue(), t, "Continue 2") assertNoError(Continue(p), t, "Continue 2")
} }
} }
f, ln = currentLineNumber(p, t) f, ln = currentLineNumber(p, t)
@ -550,7 +550,7 @@ func TestNextNetHTTP(t *testing.T) {
} }
http.Get("http://localhost:9191") http.Get("http://localhost:9191")
}() }()
if err := p.Continue(); err != nil { if err := Continue(p); err != nil {
t.Fatal(err) t.Fatal(err)
} }
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
@ -559,7 +559,7 @@ func TestNextNetHTTP(t *testing.T) {
t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln) t.Fatalf("Program not stopped at correct spot expected %d was %s:%d", tc.begin, filepath.Base(f), ln)
} }
assertNoError(p.Next(), t, "Next() returned an error") assertNoError(Next(p), t, "Next() returned an error")
f, ln = currentLineNumber(p, t) f, ln = currentLineNumber(p, t)
if ln != tc.end { if ln != tc.end {
@ -571,7 +571,7 @@ func TestNextNetHTTP(t *testing.T) {
func TestRuntimeBreakpoint(t *testing.T) { func TestRuntimeBreakpoint(t *testing.T) {
withTestProcess("testruntimebreakpoint", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testruntimebreakpoint", t, func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := Continue(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -607,7 +607,7 @@ func TestFindReturnAddress(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = p.Continue() err = Continue(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -632,7 +632,7 @@ func TestFindReturnAddressTopOfStackFn(t *testing.T) {
if _, err := p.SetBreakpoint(fn.Entry, UserBreakpoint, nil); err != nil { if _, err := p.SetBreakpoint(fn.Entry, UserBreakpoint, nil); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := p.Continue(); err != nil { if err := Continue(p); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := returnAddress(p.currentThread); err == nil { if _, err := returnAddress(p.currentThread); err == nil {
@ -656,7 +656,7 @@ func TestSwitchThread(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = p.Continue() err = Continue(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -701,11 +701,11 @@ func TestCGONext(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = p.Continue() err = Continue(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = p.Next() err = Next(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -736,7 +736,7 @@ func TestStacktrace(t *testing.T) {
assertNoError(err, t, "BreakByLocation()") assertNoError(err, t, "BreakByLocation()")
for i := range stacks { for i := range stacks {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
locations, err := ThreadStacktrace(p.currentThread, 40) locations, err := ThreadStacktrace(p.currentThread, 40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
@ -757,13 +757,13 @@ func TestStacktrace(t *testing.T) {
} }
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
p.Continue() Continue(p)
}) })
} }
func TestStacktrace2(t *testing.T) { func TestStacktrace2(t *testing.T) {
withTestProcess("retstack", t, func(p *Process, fixture protest.Fixture) { withTestProcess("retstack", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
locations, err := ThreadStacktrace(p.currentThread, 40) locations, err := ThreadStacktrace(p.currentThread, 40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
@ -774,7 +774,7 @@ func TestStacktrace2(t *testing.T) {
t.Fatalf("Stack error at main.f()\n%v\n", locations) t.Fatalf("Stack error at main.f()\n%v\n", locations)
} }
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
locations, err = ThreadStacktrace(p.currentThread, 40) locations, err = ThreadStacktrace(p.currentThread, 40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if !stackMatch([]loc{{-1, "main.g"}, {17, "main.main"}}, locations, false) { if !stackMatch([]loc{{-1, "main.g"}, {17, "main.main"}}, locations, false) {
@ -817,7 +817,7 @@ func TestStacktraceGoroutine(t *testing.T) {
bp, err := setFunctionBreakpoint(p, "main.stacktraceme") bp, err := setFunctionBreakpoint(p, "main.stacktraceme")
assertNoError(err, t, "BreakByLocation()") assertNoError(err, t, "BreakByLocation()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
gs, err := p.GoroutinesInfo() gs, err := p.GoroutinesInfo()
assertNoError(err, t, "GoroutinesInfo") assertNoError(err, t, "GoroutinesInfo")
@ -867,7 +867,7 @@ func TestStacktraceGoroutine(t *testing.T) {
} }
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
p.Continue() Continue(p)
}) })
} }
@ -892,7 +892,7 @@ func testGSupportFunc(name string, t *testing.T, p *Process, fixture protest.Fix
bp, err := setFunctionBreakpoint(p, "main.main") bp, err := setFunctionBreakpoint(p, "main.main")
assertNoError(err, t, name+": BreakByLocation()") assertNoError(err, t, name+": BreakByLocation()")
assertNoError(p.Continue(), t, name+": Continue()") assertNoError(Continue(p), t, name+": Continue()")
g, err := GetG(p.currentThread) g, err := GetG(p.currentThread)
assertNoError(err, t, name+": GetG()") assertNoError(err, t, name+": GetG()")
@ -935,7 +935,7 @@ func TestContinueMulti(t *testing.T) {
mainCount := 0 mainCount := 0
sayhiCount := 0 sayhiCount := 0
for { for {
err := p.Continue() err := Continue(p)
if p.Exited() { if p.Exited() {
break break
} }
@ -993,7 +993,7 @@ func TestBreakpointOnFunctionEntry(t *testing.T) {
assertNoError(err, t, "FindFunctionLocation()") assertNoError(err, t, "FindFunctionLocation()")
_, err = p.SetBreakpoint(addr, UserBreakpoint, nil) _, err = p.SetBreakpoint(addr, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
_, ln := currentLineNumber(p, t) _, ln := currentLineNumber(p, t)
if ln != 17 { if ln != 17 {
t.Fatalf("Wrong line number: %d (expected: 17)\n", ln) t.Fatalf("Wrong line number: %d (expected: 17)\n", ln)
@ -1003,7 +1003,7 @@ func TestBreakpointOnFunctionEntry(t *testing.T) {
func TestProcessReceivesSIGCHLD(t *testing.T) { func TestProcessReceivesSIGCHLD(t *testing.T) {
withTestProcess("sigchldprog", t, func(p *Process, fixture protest.Fixture) { withTestProcess("sigchldprog", t, func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := Continue(p)
_, ok := err.(ProcessExitedError) _, ok := err.(ProcessExitedError)
if !ok { if !ok {
t.Fatalf("Continue() returned unexpected error type %s", err) t.Fatalf("Continue() returned unexpected error type %s", err)
@ -1017,7 +1017,7 @@ func TestIssue239(t *testing.T) {
assertNoError(err, t, "LineToPC()") assertNoError(err, t, "LineToPC()")
_, err = p.SetBreakpoint(pos, UserBreakpoint, nil) _, err = p.SetBreakpoint(pos, UserBreakpoint, nil)
assertNoError(err, t, fmt.Sprintf("SetBreakpoint(%d)", pos)) assertNoError(err, t, fmt.Sprintf("SetBreakpoint(%d)", pos))
assertNoError(p.Continue(), t, fmt.Sprintf("Continue()")) assertNoError(Continue(p), t, fmt.Sprintf("Continue()"))
}) })
} }
@ -1074,7 +1074,7 @@ func TestVariableEvaluation(t *testing.T) {
} }
withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue() returned an error") assertNoError(Continue(p), t, "Continue() returned an error")
for _, tc := range testcases { for _, tc := range testcases {
v, err := evalVariable(p, tc.name) v, err := evalVariable(p, tc.name)
@ -1126,7 +1126,7 @@ func TestFrameEvaluation(t *testing.T) {
withTestProcess("goroutinestackprog", t, func(p *Process, fixture protest.Fixture) { withTestProcess("goroutinestackprog", t, func(p *Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "main.stacktraceme") _, err := setFunctionBreakpoint(p, "main.stacktraceme")
assertNoError(err, t, "setFunctionBreakpoint") assertNoError(err, t, "setFunctionBreakpoint")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
// Testing evaluation on goroutines // Testing evaluation on goroutines
gs, err := p.GoroutinesInfo() gs, err := p.GoroutinesInfo()
@ -1171,7 +1171,7 @@ func TestFrameEvaluation(t *testing.T) {
} }
// Testing evaluation on frames // Testing evaluation on frames
assertNoError(p.Continue(), t, "Continue() 2") assertNoError(Continue(p), t, "Continue() 2")
g, err := GetG(p.currentThread) g, err := GetG(p.currentThread)
assertNoError(err, t, "GetG()") assertNoError(err, t, "GetG()")
@ -1191,7 +1191,7 @@ func TestFrameEvaluation(t *testing.T) {
func TestPointerSetting(t *testing.T) { func TestPointerSetting(t *testing.T) {
withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue() returned an error") assertNoError(Continue(p), t, "Continue() returned an error")
pval := func(n int64) { pval := func(n int64) {
variable, err := evalVariable(p, "p1") variable, err := evalVariable(p, "p1")
@ -1220,7 +1220,7 @@ func TestPointerSetting(t *testing.T) {
func TestVariableFunctionScoping(t *testing.T) { func TestVariableFunctionScoping(t *testing.T) {
withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
_, err = evalVariable(p, "a1") _, err = evalVariable(p, "a1")
@ -1230,7 +1230,7 @@ func TestVariableFunctionScoping(t *testing.T) {
assertNoError(err, t, "Unable to find variable a1") assertNoError(err, t, "Unable to find variable a1")
// Move scopes, a1 exists here by a2 does not // Move scopes, a1 exists here by a2 does not
err = p.Continue() err = Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
_, err = evalVariable(p, "a1") _, err = evalVariable(p, "a1")
@ -1245,7 +1245,7 @@ func TestVariableFunctionScoping(t *testing.T) {
func TestRecursiveStructure(t *testing.T) { func TestRecursiveStructure(t *testing.T) {
withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
v, err := evalVariable(p, "aas") v, err := evalVariable(p, "aas")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
t.Logf("v: %v\n", v) t.Logf("v: %v\n", v)
@ -1255,7 +1255,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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
_, err := evalVariable(p, "iface5") _, err := evalVariable(p, "iface5")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
}) })
@ -1264,7 +1264,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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
iface2fn1v, err := evalVariable(p, "iface2fn1") iface2fn1v, err := evalVariable(p, "iface2fn1")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
t.Logf("iface2fn1: %v\n", iface2fn1v) t.Logf("iface2fn1: %v\n", iface2fn1v)
@ -1283,7 +1283,7 @@ func TestBreakpointCounts(t *testing.T) {
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
for { for {
if err := p.Continue(); err != nil { if err := Continue(p); err != nil {
if _, exited := err.(ProcessExitedError); exited { if _, exited := err.(ProcessExitedError); exited {
break break
} }
@ -1312,7 +1312,7 @@ 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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", b, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), b, "Continue()") assertNoError(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")
assertNoError(err, b, "EvalVariable()") assertNoError(err, b, "EvalVariable()")
@ -1334,7 +1334,7 @@ func TestBreakpointCountsWithDetection(t *testing.T) {
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
for { for {
if err := p.Continue(); err != nil { if err := Continue(p); err != nil {
if _, exited := err.(ProcessExitedError); exited { if _, exited := err.(ProcessExitedError); exited {
break break
} }
@ -1387,7 +1387,7 @@ func BenchmarkArrayPointer(b *testing.B) {
// 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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", b, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), b, "Continue()") assertNoError(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")
assertNoError(err, b, "EvalVariable()") assertNoError(err, b, "EvalVariable()")
@ -1401,7 +1401,7 @@ func BenchmarkMap(b *testing.B) {
// 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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", b, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), b, "Continue()") assertNoError(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")
assertNoError(err, b, "EvalVariable()") assertNoError(err, b, "EvalVariable()")
@ -1411,7 +1411,7 @@ func BenchmarkMap(b *testing.B) {
func BenchmarkGoroutinesInfo(b *testing.B) { func BenchmarkGoroutinesInfo(b *testing.B) {
withTestProcess("testvariables2", b, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables2", b, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), b, "Continue()") assertNoError(Continue(p), b, "Continue()")
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
p.allGCache = nil p.allGCache = nil
_, err := p.GoroutinesInfo() _, err := p.GoroutinesInfo()
@ -1428,8 +1428,8 @@ func TestIssue262(t *testing.T) {
_, err = p.SetBreakpoint(addr, UserBreakpoint, nil) _, err = p.SetBreakpoint(addr, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
err = p.Continue() err = Continue(p)
if err == nil { if err == nil {
t.Fatalf("No error on second continue") t.Fatalf("No error on second continue")
} }
@ -1450,13 +1450,13 @@ func TestIssue305(t *testing.T) {
_, err = p.SetBreakpoint(addr, UserBreakpoint, nil) _, err = p.SetBreakpoint(addr, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
assertNoError(p.Next(), t, "Next() 1") assertNoError(Next(p), t, "Next() 1")
assertNoError(p.Next(), t, "Next() 2") assertNoError(Next(p), t, "Next() 2")
assertNoError(p.Next(), t, "Next() 3") assertNoError(Next(p), t, "Next() 3")
assertNoError(p.Next(), t, "Next() 4") assertNoError(Next(p), t, "Next() 4")
assertNoError(p.Next(), t, "Next() 5") assertNoError(Next(p), t, "Next() 5")
}) })
} }
@ -1464,7 +1464,7 @@ 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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(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)
v, err := evalVariable(p, expr) v, err := evalVariable(p, expr)
@ -1476,7 +1476,7 @@ func TestPointerLoops(t *testing.T) {
func BenchmarkLocalVariables(b *testing.B) { func BenchmarkLocalVariables(b *testing.B) {
withTestProcess("testvariables", b, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables", b, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), b, "Continue() returned an error") assertNoError(Continue(p), b, "Continue() returned an error")
scope, err := GoroutineScope(p.currentThread) scope, err := GoroutineScope(p.currentThread)
assertNoError(err, b, "Scope()") assertNoError(err, b, "Scope()")
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@ -1498,7 +1498,7 @@ func TestCondBreakpoint(t *testing.T) {
Y: &ast.BasicLit{Kind: token.INT, Value: "7"}, Y: &ast.BasicLit{Kind: token.INT, Value: "7"},
} }
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
nvar, err := evalVariable(p, "n") nvar, err := evalVariable(p, "n")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
@ -1522,7 +1522,7 @@ func TestCondBreakpointError(t *testing.T) {
Y: &ast.BasicLit{Kind: token.INT, Value: "7"}, Y: &ast.BasicLit{Kind: token.INT, Value: "7"},
} }
err = p.Continue() err = Continue(p)
if err == nil { if err == nil {
t.Fatalf("No error on first Continue()") t.Fatalf("No error on first Continue()")
} }
@ -1537,7 +1537,7 @@ func TestCondBreakpointError(t *testing.T) {
Y: &ast.BasicLit{Kind: token.INT, Value: "7"}, Y: &ast.BasicLit{Kind: token.INT, Value: "7"},
} }
err = p.Continue() err = Continue(p)
if err != nil { if err != nil {
if _, exited := err.(ProcessExitedError); !exited { if _, exited := err.(ProcessExitedError); !exited {
t.Fatalf("Unexpected error on second Continue(): %v", err) t.Fatalf("Unexpected error on second Continue(): %v", err)
@ -1557,7 +1557,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 *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue() returned an error") assertNoError(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()")
if mmvar.Kind != reflect.Slice { if mmvar.Kind != reflect.Slice {
@ -1569,9 +1569,9 @@ func TestIssue356(t *testing.T) {
func TestStepIntoFunction(t *testing.T) { func TestStepIntoFunction(t *testing.T) {
withTestProcess("teststep", t, func(p *Process, fixture protest.Fixture) { withTestProcess("teststep", t, func(p *Process, fixture protest.Fixture) {
// Continue until breakpoint // Continue until breakpoint
assertNoError(p.Continue(), t, "Continue() returned an error") assertNoError(Continue(p), t, "Continue() returned an error")
// Step into function // Step into function
assertNoError(p.Step(), t, "Step() returned an error") assertNoError(Step(p), t, "Step() returned an error")
// We should now be inside the function. // We should now be inside the function.
loc, err := p.CurrentLocation() loc, err := p.CurrentLocation()
if err != nil { if err != nil {
@ -1596,7 +1596,7 @@ func TestIssue384(t *testing.T) {
assertNoError(err, t, "LineToPC()") assertNoError(err, t, "LineToPC()")
_, err = p.SetBreakpoint(start, UserBreakpoint, nil) _, err = p.SetBreakpoint(start, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
_, err = evalVariable(p, "st") _, err = evalVariable(p, "st")
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
}) })
@ -1609,8 +1609,8 @@ func TestIssue332_Part1(t *testing.T) {
assertNoError(err, t, "LineToPC()") assertNoError(err, t, "LineToPC()")
_, err = p.SetBreakpoint(start, UserBreakpoint, nil) _, err = p.SetBreakpoint(start, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
assertNoError(p.Next(), t, "first Next()") assertNoError(Next(p), t, "first Next()")
locations, err := ThreadStacktrace(p.currentThread, 2) locations, err := ThreadStacktrace(p.currentThread, 2)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if locations[0].Call.Fn == nil { if locations[0].Call.Fn == nil {
@ -1635,11 +1635,11 @@ func TestIssue332_Part2(t *testing.T) {
assertNoError(err, t, "LineToPC()") assertNoError(err, t, "LineToPC()")
_, err = p.SetBreakpoint(start, UserBreakpoint, nil) _, err = p.SetBreakpoint(start, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
// step until we enter changeMe // step until we enter changeMe
for { for {
assertNoError(p.Step(), t, "Step()") assertNoError(Step(p), t, "Step()")
locations, err := ThreadStacktrace(p.currentThread, 2) locations, err := ThreadStacktrace(p.currentThread, 2)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
if locations[0].Call.Fn == nil { if locations[0].Call.Fn == nil {
@ -1662,10 +1662,10 @@ func TestIssue332_Part2(t *testing.T) {
t.Fatalf("Step did not skip the prologue: current pc: %x, first instruction after prologue: %x", pc, pcAfterPrologue) t.Fatalf("Step did not skip the prologue: current pc: %x, first instruction after prologue: %x", pc, pcAfterPrologue)
} }
assertNoError(p.Next(), t, "first Next()") assertNoError(Next(p), t, "first Next()")
assertNoError(p.Next(), t, "second Next()") assertNoError(Next(p), t, "second Next()")
assertNoError(p.Next(), t, "third Next()") assertNoError(Next(p), t, "third Next()")
err = p.Continue() err = Continue(p)
if _, exited := err.(ProcessExitedError); !exited { if _, exited := err.(ProcessExitedError); !exited {
assertNoError(err, t, "final Continue()") assertNoError(err, t, "final Continue()")
} }
@ -1686,9 +1686,9 @@ func TestIssue414(t *testing.T) {
assertNoError(err, t, "LineToPC()") assertNoError(err, t, "LineToPC()")
_, err = p.SetBreakpoint(start, UserBreakpoint, nil) _, err = p.SetBreakpoint(start, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
for { for {
err := p.Step() err := Step(p)
if err != nil { if err != nil {
if _, exited := err.(ProcessExitedError); exited { if _, exited := err.(ProcessExitedError); exited {
break break
@ -1701,7 +1701,7 @@ func TestIssue414(t *testing.T) {
func TestPackageVariables(t *testing.T) { func TestPackageVariables(t *testing.T) {
withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := Continue(p)
assertNoError(err, t, "Continue()") assertNoError(err, t, "Continue()")
scope, err := GoroutineScope(p.currentThread) scope, err := GoroutineScope(p.currentThread)
assertNoError(err, t, "Scope()") assertNoError(err, t, "Scope()")
@ -1734,7 +1734,7 @@ func TestIssue149(t *testing.T) {
func TestPanicBreakpoint(t *testing.T) { func TestPanicBreakpoint(t *testing.T) {
withTestProcess("panic", t, func(p *Process, fixture protest.Fixture) { withTestProcess("panic", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
bp := p.CurrentBreakpoint() bp := p.CurrentBreakpoint()
if bp == nil || bp.Name != "unrecovered-panic" { if bp == nil || bp.Name != "unrecovered-panic" {
t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint()) t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint())
@ -1744,7 +1744,7 @@ func TestPanicBreakpoint(t *testing.T) {
func TestCmdLineArgs(t *testing.T) { func TestCmdLineArgs(t *testing.T) {
expectSuccess := func(p *Process, fixture protest.Fixture) { expectSuccess := func(p *Process, fixture protest.Fixture) {
err := p.Continue() err := Continue(p)
bp := p.CurrentBreakpoint() bp := p.CurrentBreakpoint()
if bp != nil && bp.Name == "unrecovered-panic" { if bp != nil && bp.Name == "unrecovered-panic" {
t.Fatalf("testing args failed on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint()) t.Fatalf("testing args failed on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint())
@ -1760,7 +1760,7 @@ func TestCmdLineArgs(t *testing.T) {
} }
expectPanic := func(p *Process, fixture protest.Fixture) { expectPanic := func(p *Process, fixture protest.Fixture) {
p.Continue() Continue(p)
bp := p.CurrentBreakpoint() bp := p.CurrentBreakpoint()
if bp == nil || bp.Name != "unrecovered-panic" { if bp == nil || bp.Name != "unrecovered-panic" {
t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint()) t.Fatalf("not on unrecovered-panic breakpoint: %v", p.CurrentBreakpoint())
@ -1805,7 +1805,7 @@ func TestIssue462(t *testing.T) {
p.RequestManualStop() p.RequestManualStop()
}() }()
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
_, err := ThreadStacktrace(p.currentThread, 40) _, err := ThreadStacktrace(p.currentThread, 40)
assertNoError(err, t, "Stacktrace()") assertNoError(err, t, "Stacktrace()")
}) })
@ -1829,7 +1829,7 @@ func TestNextParked(t *testing.T) {
var parkedg *G var parkedg *G
LookForParkedG: LookForParkedG:
for { for {
err := p.Continue() err := Continue(p)
if _, exited := err.(ProcessExitedError); exited { if _, exited := err.(ProcessExitedError); exited {
t.Log("could not find parked goroutine") t.Log("could not find parked goroutine")
return return
@ -1849,7 +1849,7 @@ func TestNextParked(t *testing.T) {
assertNoError(p.SwitchGoroutine(parkedg.ID), t, "SwitchGoroutine()") assertNoError(p.SwitchGoroutine(parkedg.ID), t, "SwitchGoroutine()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
assertNoError(p.Next(), t, "Next()") assertNoError(Next(p), t, "Next()")
if p.selectedGoroutine.ID != parkedg.ID { if p.selectedGoroutine.ID != parkedg.ID {
t.Fatalf("Next did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.selectedGoroutine.ID) t.Fatalf("Next did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.selectedGoroutine.ID)
@ -1866,7 +1866,7 @@ func TestStepParked(t *testing.T) {
var parkedg *G var parkedg *G
LookForParkedG: LookForParkedG:
for { for {
err := p.Continue() err := Continue(p)
if _, exited := err.(ProcessExitedError); exited { if _, exited := err.(ProcessExitedError); exited {
t.Log("could not find parked goroutine") t.Log("could not find parked goroutine")
return return
@ -1896,7 +1896,7 @@ func TestStepParked(t *testing.T) {
assertNoError(p.SwitchGoroutine(parkedg.ID), t, "SwitchGoroutine()") assertNoError(p.SwitchGoroutine(parkedg.ID), t, "SwitchGoroutine()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
assertNoError(p.Step(), t, "Step()") assertNoError(Step(p), t, "Step()")
if p.selectedGoroutine.ID != parkedg.ID { if p.selectedGoroutine.ID != parkedg.ID {
t.Fatalf("Step did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.selectedGoroutine.ID) t.Fatalf("Step did not continue on the selected goroutine, expected %d got %d", parkedg.ID, p.selectedGoroutine.ID)
@ -1965,10 +1965,10 @@ func TestIssue573(t *testing.T) {
f := p.BinInfo().goSymTable.LookupFunc("main.foo") f := p.BinInfo().goSymTable.LookupFunc("main.foo")
_, err := p.SetBreakpoint(f.Entry, UserBreakpoint, nil) _, err := p.SetBreakpoint(f.Entry, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
assertNoError(p.Step(), t, "Step() #1") assertNoError(Step(p), t, "Step() #1")
assertNoError(p.Step(), t, "Step() #2") // Bug exits here. assertNoError(Step(p), t, "Step() #2") // Bug exits here.
assertNoError(p.Step(), t, "Step() #3") // Third step ought to be possible; program ought not have exited. assertNoError(Step(p), t, "Step() #3") // Third step ought to be possible; program ought not have exited.
}) })
} }
@ -2085,8 +2085,8 @@ func TestIssue561(t *testing.T) {
// where a breakpoint is also set. // where a breakpoint is also set.
withTestProcess("issue561", t, func(p *Process, fixture protest.Fixture) { withTestProcess("issue561", t, func(p *Process, fixture protest.Fixture) {
setFileBreakpoint(p, t, fixture, 10) setFileBreakpoint(p, t, fixture, 10)
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
assertNoError(p.Step(), t, "Step()") assertNoError(Step(p), t, "Step()")
_, ln := currentLineNumber(p, t) _, ln := currentLineNumber(p, t)
if ln != 5 { if ln != 5 {
t.Fatalf("wrong line number after Step, expected 5 got %d", ln) t.Fatalf("wrong line number after Step, expected 5 got %d", ln)
@ -2098,7 +2098,7 @@ func TestStepOut(t *testing.T) {
withTestProcess("testnextprog", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testnextprog", t, func(p *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(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
f, lno := currentLineNumber(p, t) f, lno := currentLineNumber(p, t)
@ -2106,7 +2106,7 @@ func TestStepOut(t *testing.T) {
t.Fatalf("wrong line number %s:%d, expected %d", f, lno, 13) t.Fatalf("wrong line number %s:%d, expected %d", f, lno, 13)
} }
assertNoError(p.StepOut(), t, "StepOut()") assertNoError(StepOut(p), t, "StepOut()")
f, lno = currentLineNumber(p, t) f, lno = currentLineNumber(p, t)
if lno != 35 { if lno != 35 {
@ -2122,7 +2122,7 @@ func TestStepConcurrentDirect(t *testing.T) {
bp, err := p.SetBreakpoint(pc, UserBreakpoint, nil) bp, err := p.SetBreakpoint(pc, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
_, err = p.ClearBreakpoint(bp.Addr) _, err = p.ClearBreakpoint(bp.Addr)
assertNoError(err, t, "ClearBreakpoint()") assertNoError(err, t, "ClearBreakpoint()")
@ -2171,7 +2171,7 @@ func TestStepConcurrentDirect(t *testing.T) {
if i == 0 { if i == 0 {
count++ count++
} }
assertNoError(p.Step(), t, "Step()") assertNoError(Step(p), t, "Step()")
} }
if count != 100 { if count != 100 {
@ -2207,7 +2207,7 @@ func TestStepConcurrentPtr(t *testing.T) {
kvals := map[int]int64{} kvals := map[int]int64{}
count := 0 count := 0
for { for {
err := p.Continue() err := Continue(p)
_, exited := err.(ProcessExitedError) _, exited := err.(ProcessExitedError)
if exited { if exited {
break break
@ -2235,12 +2235,12 @@ func TestStepConcurrentPtr(t *testing.T) {
} }
kvals[gid] = k kvals[gid] = k
assertNoError(p.Step(), t, "Step()") assertNoError(Step(p), t, "Step()")
for nextInProgress(p) { for nextInProgress(p) {
if p.selectedGoroutine.ID == gid { if p.selectedGoroutine.ID == gid {
t.Fatalf("step did not step into function call (but internal breakpoints still active?) (%d %d)", gid, p.selectedGoroutine.ID) t.Fatalf("step did not step into function call (but internal breakpoints still active?) (%d %d)", gid, p.selectedGoroutine.ID)
} }
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
} }
if p.selectedGoroutine.ID != gid { if p.selectedGoroutine.ID != gid {
@ -2272,7 +2272,7 @@ func TestStepOutDefer(t *testing.T) {
assertNoError(err, t, "FindFileLocation()") assertNoError(err, t, "FindFileLocation()")
bp, err := p.SetBreakpoint(pc, UserBreakpoint, nil) bp, err := p.SetBreakpoint(pc, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
f, lno := currentLineNumber(p, t) f, lno := currentLineNumber(p, t)
@ -2280,7 +2280,7 @@ func TestStepOutDefer(t *testing.T) {
t.Fatalf("worng line number %s:%d, expected %d", f, lno, 5) t.Fatalf("worng line number %s:%d, expected %d", f, lno, 5)
} }
assertNoError(p.StepOut(), t, "StepOut()") assertNoError(StepOut(p), t, "StepOut()")
f, l, _ := p.BinInfo().goSymTable.PCToLine(currentPC(p, t)) f, l, _ := p.BinInfo().goSymTable.PCToLine(currentPC(p, t))
if f == fixture.Source || l == 6 { if f == fixture.Source || l == 6 {
@ -2295,10 +2295,10 @@ func TestStepOutDeferReturnAndDirectCall(t *testing.T) {
// 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 *Process, fixture protest.Fixture) { withTestProcess("defercall", t, func(p *Process, fixture protest.Fixture) {
bp := setFileBreakpoint(p, t, fixture, 11) bp := setFileBreakpoint(p, t, fixture, 11)
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
assertNoError(p.StepOut(), t, "StepOut()") assertNoError(StepOut(p), t, "StepOut()")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
if ln != 28 { if ln != 28 {
@ -2314,7 +2314,7 @@ func TestStepOnCallPtrInstr(t *testing.T) {
_, err = p.SetBreakpoint(pc, UserBreakpoint, nil) _, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
assertNoError(err, t, "SetBreakpoint()") assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
found := false found := false
@ -2340,7 +2340,7 @@ func TestStepOnCallPtrInstr(t *testing.T) {
t.Fatal("Could not find CALL instruction") t.Fatal("Could not find CALL instruction")
} }
assertNoError(p.Step(), t, "Step()") assertNoError(Step(p), t, "Step()")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
if ln != 5 { if ln != 5 {
@ -2355,7 +2355,7 @@ func TestIssue594(t *testing.T) {
// 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 *Process, fixture protest.Fixture) { withTestProcess("issue594", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
if ln != 21 { if ln != 21 {
t.Fatalf("Program stopped at %s:%d, expected :21", f, ln) t.Fatalf("Program stopped at %s:%d, expected :21", f, ln)
@ -2369,10 +2369,10 @@ func TestStepOutPanicAndDirectCall(t *testing.T) {
// 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 *Process, fixture protest.Fixture) { withTestProcess("defercall", t, func(p *Process, fixture protest.Fixture) {
bp := setFileBreakpoint(p, t, fixture, 17) bp := setFileBreakpoint(p, t, fixture, 17)
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
p.ClearBreakpoint(bp.Addr) p.ClearBreakpoint(bp.Addr)
assertNoError(p.StepOut(), t, "StepOut()") assertNoError(StepOut(p), t, "StepOut()")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
if ln != 5 { if ln != 5 {
@ -2391,7 +2391,7 @@ func TestWorkDir(t *testing.T) {
addr, _, err := p.BinInfo().goSymTable.LineToPC(fixture.Source, 14) addr, _, err := p.BinInfo().goSymTable.LineToPC(fixture.Source, 14)
assertNoError(err, t, "LineToPC") assertNoError(err, t, "LineToPC")
p.SetBreakpoint(addr, UserBreakpoint, nil) p.SetBreakpoint(addr, UserBreakpoint, nil)
p.Continue() Continue(p)
v, err := evalVariable(p, "pwd") v, err := evalVariable(p, "pwd")
assertNoError(err, t, "EvalVariable") assertNoError(err, t, "EvalVariable")
str := constant.StringVal(v.Value) str := constant.StringVal(v.Value)
@ -2412,7 +2412,7 @@ func TestNegativeIntEvaluation(t *testing.T) {
{"ni32", "int32", int64(-5)}, {"ni32", "int32", int64(-5)},
} }
withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
for _, tc := range testcases { for _, tc := range testcases {
v, err := evalVariable(p, tc.name) v, err := evalVariable(p, tc.name)
assertNoError(err, t, "EvalVariable()") assertNoError(err, t, "EvalVariable()")
@ -2431,11 +2431,11 @@ func TestIssue683(t *testing.T) {
withTestProcess("issue683", t, func(p *Process, fixture protest.Fixture) { withTestProcess("issue683", t, func(p *Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "main.main") _, err := setFunctionBreakpoint(p, "main.main")
assertNoError(err, t, "setFunctionBreakpoint()") assertNoError(err, t, "setFunctionBreakpoint()")
assertNoError(p.Continue(), t, "First Continue()") assertNoError(Continue(p), t, "First Continue()")
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
// eventually an error about the source file not being found will be // eventually an error about the source file not being found will be
// returned, the important thing is that we shouldn't panic // returned, the important thing is that we shouldn't panic
err := p.Step() err := Step(p)
if err != nil { if err != nil {
break break
} }
@ -2446,8 +2446,8 @@ func TestIssue683(t *testing.T) {
func TestIssue664(t *testing.T) { func TestIssue664(t *testing.T) {
withTestProcess("issue664", t, func(p *Process, fixture protest.Fixture) { withTestProcess("issue664", t, func(p *Process, fixture protest.Fixture) {
setFileBreakpoint(p, t, fixture, 4) setFileBreakpoint(p, t, fixture, 4)
assertNoError(p.Continue(), t, "Continue()") assertNoError(Continue(p), t, "Continue()")
assertNoError(p.Next(), t, "Next()") assertNoError(Next(p), t, "Next()")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
if ln != 5 { if ln != 5 {
t.Fatalf("Did not continue to line 5: %s:%d", f, ln) t.Fatalf("Did not continue to line 5: %s:%d", f, ln)
@ -2462,7 +2462,7 @@ func BenchmarkTrace(b *testing.B) {
assertNoError(err, b, "setFunctionBreakpoint()") assertNoError(err, b, "setFunctionBreakpoint()")
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
assertNoError(p.Continue(), b, "Continue()") assertNoError(Continue(p), b, "Continue()")
s, err := GoroutineScope(p.currentThread) s, err := GoroutineScope(p.currentThread)
assertNoError(err, b, "Scope()") assertNoError(err, b, "Scope()")
_, err = s.FunctionArguments(LoadConfig{false, 0, 64, 0, 3}) _, err = s.FunctionArguments(LoadConfig{false, 0, 64, 0, 3})
@ -2480,9 +2480,9 @@ func TestNextInDeferReturn(t *testing.T) {
withTestProcess("defercall", t, func(p *Process, fixture protest.Fixture) { withTestProcess("defercall", t, func(p *Process, fixture protest.Fixture) {
_, err := setFunctionBreakpoint(p, "runtime.deferreturn") _, err := setFunctionBreakpoint(p, "runtime.deferreturn")
assertNoError(err, t, "setFunctionBreakpoint()") assertNoError(err, t, "setFunctionBreakpoint()")
assertNoError(p.Continue(), t, "First Continue()") assertNoError(Continue(p), t, "First Continue()")
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
assertNoError(p.Next(), t, fmt.Sprintf("Next() %d", i)) assertNoError(Next(p), t, fmt.Sprintf("Next() %d", i))
} }
}) })
} }
@ -2519,7 +2519,7 @@ func TestStacktraceWithBarriers(t *testing.T) {
assertNoError(err, t, "setFunctionBreakpoint()") assertNoError(err, t, "setFunctionBreakpoint()")
stackBarrierGoids := []int{} stackBarrierGoids := []int{}
for len(stackBarrierGoids) == 0 { for len(stackBarrierGoids) == 0 {
err := p.Continue() err := Continue(p)
if _, exited := err.(ProcessExitedError); exited { if _, exited := err.(ProcessExitedError); exited {
t.Logf("Could not run test") t.Logf("Could not run test")
return return
@ -2555,7 +2555,7 @@ func TestStacktraceWithBarriers(t *testing.T) {
t.Logf("stack barrier goids: %v\n", stackBarrierGoids) t.Logf("stack barrier goids: %v\n", stackBarrierGoids)
assertNoError(p.StepOut(), t, "StepOut()") assertNoError(StepOut(p), t, "StepOut()")
gs, err := p.GoroutinesInfo() gs, err := p.GoroutinesInfo()
assertNoError(err, t, "GoroutinesInfo()") assertNoError(err, t, "GoroutinesInfo()")
@ -2628,7 +2628,7 @@ func TestAttachDetach(t *testing.T) {
http.Get("http://localhost:9191") http.Get("http://localhost:9191")
}() }()
assertNoError(p.Continue(), t, "Continue") assertNoError(Continue(p), t, "Continue")
f, ln := currentLineNumber(p, t) f, ln := currentLineNumber(p, t)
if ln != 11 { if ln != 11 {

@ -23,7 +23,7 @@ func TestIssue419(t *testing.T) {
} }
} }
}() }()
err := p.Continue() err := Continue(p)
if _, exited := err.(ProcessExitedError); !exited { if _, exited := err.(ProcessExitedError); !exited {
t.Fatalf("Unexpected error after Continue(): %v\n", err) t.Fatalf("Unexpected error after Continue(): %v\n", err)
} }

@ -46,6 +46,7 @@ type IThread interface {
Registers(floatingPoint bool) (Registers, error) Registers(floatingPoint bool) (Registers, error)
Arch() Arch Arch() Arch
BinInfo() *BinaryInfo BinInfo() *BinaryInfo
StepInstruction() error
} }
// Location represents the location of a thread. // Location represents the location of a thread.
@ -149,12 +150,12 @@ 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 *Thread) (Stackframe, error) { func topframe(g *G, thread IThread) (Stackframe, error) {
var frames []Stackframe var frames []Stackframe
var err error var err error
if g == nil { if g == nil {
if thread.blocked() { if threadBlocked(thread) {
return Stackframe{}, ThreadBlockedError{} return Stackframe{}, ThreadBlockedError{}
} }
frames, err = ThreadStacktrace(thread, 0) frames, err = ThreadStacktrace(thread, 0)
@ -177,8 +178,10 @@ func topframe(g *G, thread *Thread) (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 (dbp *Process) next(stepInto bool) error { func next(dbp Continuable, stepInto bool) error {
topframe, err := topframe(dbp.selectedGoroutine, dbp.currentThread) selg := dbp.SelectedGoroutine()
curthread := dbp.CurrentThread()
topframe, err := topframe(selg, curthread)
if err != nil { if err != nil {
return err return err
} }
@ -191,22 +194,22 @@ func (dbp *Process) next(stepInto bool) error {
}() }()
csource := filepath.Ext(topframe.Current.File) != ".go" csource := filepath.Ext(topframe.Current.File) != ".go"
var thread memoryReadWriter = dbp.currentThread var thread memoryReadWriter = curthread
var regs Registers var regs Registers
if dbp.selectedGoroutine != nil && dbp.selectedGoroutine.thread != nil { if selg != nil && selg.Thread() != nil {
thread = dbp.selectedGoroutine.thread thread = selg.Thread()
regs, err = dbp.selectedGoroutine.thread.Registers(false) regs, err = selg.Thread().Registers(false)
if err != nil { if err != nil {
return err return err
} }
} }
text, err := disassemble(thread, regs, dbp.breakpoints, dbp.BinInfo(), topframe.FDE.Begin(), topframe.FDE.End()) text, err := disassemble(thread, regs, dbp.Breakpoints(), dbp.BinInfo(), topframe.FDE.Begin(), topframe.FDE.End())
if err != nil && stepInto { if err != nil && stepInto {
return err return err
} }
cond := sameGoroutineCondition(dbp.selectedGoroutine) cond := sameGoroutineCondition(selg)
if stepInto { if stepInto {
for _, instr := range text { for _, instr := range text {
@ -215,7 +218,7 @@ func (dbp *Process) next(stepInto bool) error {
} }
if instr.DestLoc != nil && instr.DestLoc.Fn != nil { if instr.DestLoc != nil && instr.DestLoc.Fn != nil {
if err := dbp.setStepIntoBreakpoint([]AsmInstruction{instr}, cond); err != nil { if err := setStepIntoBreakpoint(dbp, []AsmInstruction{instr}, cond); err != nil {
return err return err
} }
} else { } else {
@ -242,10 +245,10 @@ func (dbp *Process) next(stepInto bool) error {
// Set breakpoint on the most recently deferred function (if any) // Set breakpoint on the most recently deferred function (if any)
var deferpc uint64 = 0 var deferpc uint64 = 0
if dbp.selectedGoroutine != nil { if selg != nil {
deferPCEntry := dbp.selectedGoroutine.DeferPC() deferPCEntry := selg.DeferPC()
if deferPCEntry != 0 { if deferPCEntry != 0 {
_, _, deferfn := dbp.bi.goSymTable.PCToLine(deferPCEntry) _, _, deferfn := dbp.BinInfo().PCToLine(deferPCEntry)
var err error var err error
deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false) deferpc, err = dbp.FirstPCAfterPrologue(deferfn, false)
if err != nil { if err != nil {
@ -267,7 +270,7 @@ func (dbp *Process) next(stepInto bool) error {
} }
// Add breakpoints on all the lines in the current function // Add breakpoints on all the lines in the current function
pcs, err := dbp.bi.lineInfo.AllPCsBetween(topframe.FDE.Begin(), topframe.FDE.End()-1, topframe.Current.File) pcs, err := dbp.BinInfo().lineInfo.AllPCsBetween(topframe.FDE.Begin(), topframe.FDE.End()-1, topframe.Current.File)
if err != nil { if err != nil {
return err return err
} }
@ -282,8 +285,8 @@ func (dbp *Process) next(stepInto bool) error {
} }
if !covered { if !covered {
fn := dbp.bi.goSymTable.PCToFunc(topframe.Ret) fn := dbp.BinInfo().goSymTable.PCToFunc(topframe.Ret)
if dbp.selectedGoroutine != nil && fn != nil && fn.Name == "runtime.goexit" { if selg != nil && fn != nil && fn.Name == "runtime.goexit" {
return nil return nil
} }
} }
@ -292,10 +295,10 @@ func (dbp *Process) next(stepInto bool) error {
// Add a breakpoint on the return address for the current frame // Add a breakpoint on the return address for the current frame
pcs = append(pcs, topframe.Ret) pcs = append(pcs, topframe.Ret)
success = true success = true
return dbp.setInternalBreakpoints(topframe.Current.PC, pcs, NextBreakpoint, cond) return setInternalBreakpoints(dbp, topframe.Current.PC, pcs, NextBreakpoint, cond)
} }
func (dbp *Process) setStepIntoBreakpoint(text []AsmInstruction, cond ast.Expr) error { func setStepIntoBreakpoint(dbp Continuable, text []AsmInstruction, cond ast.Expr) error {
if len(text) <= 0 { if len(text) <= 0 {
return nil return nil
} }
@ -337,7 +340,7 @@ func (dbp *Process) setStepIntoBreakpoint(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 (dbp *Process) setInternalBreakpoints(curpc uint64, pcs []uint64, kind BreakpointKind, cond ast.Expr) error { func setInternalBreakpoints(dbp Continuable, 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
@ -495,7 +498,7 @@ func (thread *Thread) SetCurrentBreakpoint() error {
return err return err
} }
thread.BreakpointConditionMet, thread.BreakpointConditionError = bp.checkCondition(thread) thread.BreakpointConditionMet, thread.BreakpointConditionError = bp.checkCondition(thread)
if thread.onTriggeredBreakpoint() { if thread.CurrentBreakpoint != nil && thread.BreakpointConditionMet {
if g, err := GetG(thread); err == nil { if g, err := GetG(thread); err == nil {
thread.CurrentBreakpoint.HitCount[g.ID]++ thread.CurrentBreakpoint.HitCount[g.ID]++
} }
@ -511,15 +514,7 @@ func (thread *Thread) clearBreakpointState() {
thread.BreakpointConditionError = nil thread.BreakpointConditionError = nil
} }
func (thread *Thread) onTriggeredBreakpoint() bool { func onRuntimeBreakpoint(thread IThread) bool {
return (thread.CurrentBreakpoint != nil) && thread.BreakpointConditionMet
}
func (thread *Thread) onTriggeredInternalBreakpoint() bool {
return thread.onTriggeredBreakpoint() && thread.CurrentBreakpoint.Internal()
}
func (thread *Thread) onRuntimeBreakpoint() bool {
loc, err := thread.Location() loc, err := thread.Location()
if err != nil { if err != nil {
return false return false
@ -528,11 +523,11 @@ func (thread *Thread) onRuntimeBreakpoint() bool {
} }
// onNextGorutine returns true if this thread is on the goroutine requested by the current 'next' command // onNextGorutine returns true if this thread is on the goroutine requested by the current 'next' command
func (thread *Thread) onNextGoroutine() (bool, error) { func onNextGoroutine(thread IThread, breakpoints map[uint64]*Breakpoint) (bool, error) {
var bp *Breakpoint var bp *Breakpoint
for i := range thread.dbp.breakpoints { for i := range breakpoints {
if thread.dbp.breakpoints[i].Internal() { if breakpoints[i].Internal() {
bp = thread.dbp.breakpoints[i] bp = breakpoints[i]
break break
} }
} }

@ -81,13 +81,14 @@ func (t *Thread) resume() error {
return nil return nil
} }
func (t *Thread) blocked() bool { func threadBlocked(t IThread) bool {
// TODO(dp) cache the func pc to remove this lookup // TODO(dp) cache the func pc to remove this lookup
pc, err := t.PC() regs, err := t.Registers(false)
if err != nil { if err != nil {
return false return false
} }
fn := t.dbp.bi.goSymTable.PCToFunc(pc) pc := regs.PC()
fn := t.BinInfo().goSymTable.PCToFunc(pc)
if fn == nil { if fn == nil {
return false return false
} }

@ -67,9 +67,13 @@ func (t *Thread) singleStep() (err error) {
} }
} }
func (t *Thread) blocked() bool { func threadBlocked(t IThread) bool {
pc, _ := t.PC() regs, err := t.Registers(false)
fn := t.dbp.bi.goSymTable.PCToFunc(pc) if err != nil {
return false
}
pc := regs.PC()
fn := t.BinInfo().goSymTable.PCToFunc(pc)
if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) { if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) {
return true return true
} }

@ -103,14 +103,15 @@ func (t *Thread) resume() error {
return err return err
} }
func (t *Thread) blocked() bool { func threadBlocked(t IThread) bool {
// TODO: Probably incorrect - what are the runtime functions that // TODO: Probably incorrect - what are the runtime functions that
// indicate blocking on Windows? // indicate blocking on Windows?
pc, err := t.PC() regs, err := t.Registers(false)
if err != nil { if err != nil {
return false return false
} }
fn := t.dbp.bi.goSymTable.PCToFunc(pc) pc := regs.PC()
fn := t.BinInfo().goSymTable.PCToFunc(pc)
if fn == nil { if fn == nil {
return false return false
} }

@ -60,16 +60,12 @@ type ThreadInfo interface {
// 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 {
GoroutinesInfo() ([]*proc.G, error)
SelectedGoroutine() *proc.G SelectedGoroutine() *proc.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 {
Continue() error ContinueOnce() (trapthread proc.IThread, err error)
Next() error
Step() error
StepOut() error
StepInstruction() error StepInstruction() error
SwitchThread(int) error SwitchThread(int) error
SwitchGoroutine(int) error SwitchGoroutine(int) error

@ -412,7 +412,7 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
switch command.Name { switch command.Name {
case api.Continue: case api.Continue:
log.Print("continuing") log.Print("continuing")
err = d.target.Continue() err = proc.Continue(d.target)
if err != nil { if err != nil {
if exitedErr, exited := err.(proc.ProcessExitedError); exited { if exitedErr, exited := err.(proc.ProcessExitedError); exited {
state := &api.DebuggerState{} state := &api.DebuggerState{}
@ -432,16 +432,16 @@ func (d *Debugger) Command(command *api.DebuggerCommand) (*api.DebuggerState, er
case api.Next: case api.Next:
log.Print("nexting") log.Print("nexting")
err = d.target.Next() err = proc.Next(d.target)
case api.Step: case api.Step:
log.Print("stepping") log.Print("stepping")
err = d.target.Step() err = proc.Step(d.target)
case api.StepInstruction: case api.StepInstruction:
log.Print("single stepping") log.Print("single stepping")
err = d.target.StepInstruction() err = d.target.StepInstruction()
case api.StepOut: case api.StepOut:
log.Print("step out") log.Print("step out")
err = d.target.StepOut() err = proc.StepOut(d.target)
case api.SwitchThread: case api.SwitchThread:
log.Printf("switching to thread %d", command.ThreadID) log.Printf("switching to thread %d", command.ThreadID)
err = d.target.SwitchThread(command.ThreadID) err = d.target.SwitchThread(command.ThreadID)
@ -714,7 +714,7 @@ func (d *Debugger) Goroutines() ([]*api.Goroutine, error) {
defer d.processMutex.Unlock() defer d.processMutex.Unlock()
goroutines := []*api.Goroutine{} goroutines := []*api.Goroutine{}
gs, err := d.target.GoroutinesInfo() gs, err := proc.GoroutinesInfo(d.target)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -138,7 +138,7 @@ func TestVariableEvaluation(t *testing.T) {
} }
withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) {
err := p.Continue() err := proc.Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
for _, tc := range testcases { for _, tc := range testcases {
@ -216,7 +216,7 @@ func TestVariableEvaluationShort(t *testing.T) {
} }
withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) {
err := p.Continue() err := proc.Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
for _, tc := range testcases { for _, tc := range testcases {
@ -271,7 +271,7 @@ func TestMultilineVariableEvaluation(t *testing.T) {
} }
withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) {
err := p.Continue() err := proc.Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
for _, tc := range testcases { for _, tc := range testcases {
@ -344,7 +344,7 @@ func TestLocalVariables(t *testing.T) {
} }
withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) {
err := p.Continue() err := proc.Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
for _, tc := range testcases { for _, tc := range testcases {
@ -377,7 +377,7 @@ func TestEmbeddedStruct(t *testing.T) {
{"b.s", true, "\"hello\"", "\"hello\"", "string", nil}, {"b.s", true, "\"hello\"", "\"hello\"", "string", nil},
{"b2", true, "main.B {main.A: main.A {val: 42}, *main.C: *main.C nil, a: main.A {val: 47}, ptr: *main.A nil}", "main.B {main.A: (*main.A)(0x…", "main.B", nil}, {"b2", true, "main.B {main.A: main.A {val: 42}, *main.C: *main.C nil, a: main.A {val: 47}, ptr: *main.A nil}", "main.B {main.A: (*main.A)(0x…", "main.B", nil},
} }
assertNoError(p.Continue(), t, "Continue()") assertNoError(proc.Continue(p), t, "Continue()")
for _, tc := range testcases { for _, tc := range testcases {
variable, err := evalVariable(p, tc.name, pnormalLoadConfig) variable, err := evalVariable(p, tc.name, pnormalLoadConfig)
@ -398,7 +398,7 @@ func TestEmbeddedStruct(t *testing.T) {
func TestComplexSetting(t *testing.T) { func TestComplexSetting(t *testing.T) {
withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables", t, func(p *proc.Process, fixture protest.Fixture) {
err := p.Continue() err := proc.Continue(p)
assertNoError(err, t, "Continue() returned an error") assertNoError(err, t, "Continue() returned an error")
h := func(setExpr, value string) { h := func(setExpr, value string) {
@ -644,7 +644,7 @@ func TestEvalExpression(t *testing.T) {
} }
withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) {
assertNoError(p.Continue(), 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)
if tc.err == nil { if tc.err == nil {
@ -668,7 +668,7 @@ func TestEvalExpression(t *testing.T) {
func TestEvalAddrAndCast(t *testing.T) { func TestEvalAddrAndCast(t *testing.T) {
withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) {
assertNoError(p.Continue(), 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)")
c1addrstr := api.ConvertVar(c1addr).SinglelineString() c1addrstr := api.ConvertVar(c1addr).SinglelineString()
@ -694,7 +694,7 @@ func TestEvalAddrAndCast(t *testing.T) {
func TestMapEvaluation(t *testing.T) { func TestMapEvaluation(t *testing.T) {
withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) {
assertNoError(p.Continue(), 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()")
m1 := api.ConvertVar(m1v) m1 := api.ConvertVar(m1v)
@ -728,7 +728,7 @@ func TestMapEvaluation(t *testing.T) {
func TestUnsafePointer(t *testing.T) { func TestUnsafePointer(t *testing.T) {
withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) {
assertNoError(p.Continue(), 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)")
up1 := api.ConvertVar(up1v) up1 := api.ConvertVar(up1v)
@ -765,7 +765,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 *proc.Process, fixture protest.Fixture) { withTestProcess("testvariables2", t, func(p *proc.Process, fixture protest.Fixture) {
assertNoError(p.Continue(), 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)
assertNoError(err, t, fmt.Sprintf("EvalVariable(%s)", testcase.name)) assertNoError(err, t, fmt.Sprintf("EvalVariable(%s)", testcase.name))
@ -816,7 +816,7 @@ func TestPackageRenames(t *testing.T) {
} }
withTestProcess("pkgrenames", t, func(p *proc.Process, fixture protest.Fixture) { withTestProcess("pkgrenames", t, func(p *proc.Process, fixture protest.Fixture) {
assertNoError(p.Continue(), 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)
if tc.err == nil { if tc.err == nil {