proc: Renamed temp breakpoints to internal breakpoints
This commit is contained in:
parent
7c49d4968d
commit
9cbe768836
@ -9,7 +9,7 @@ package main
|
||||
// Expect to be stopped in fmt.Printf or runtime.duffzero
|
||||
// In bug, s #2 runs to the process exit because the call
|
||||
// to duffzero enters duffzero well after the nominal entry
|
||||
// and skips the temporary breakpoint placed by StepZero().
|
||||
// and skips the internal breakpoint placed by Step().
|
||||
import "fmt"
|
||||
|
||||
var v int = 99
|
||||
|
@ -21,7 +21,7 @@ type Breakpoint struct {
|
||||
OriginalData []byte // If software breakpoint, the data we replace with breakpoint instruction.
|
||||
Name string // User defined name of the breakpoint
|
||||
ID int // Monotonically increasing ID.
|
||||
Kind BreakpointKind // Whether this is a temp breakpoint (for next'ing or stepping).
|
||||
Kind BreakpointKind // Whether this is an internal breakpoint (for next'ing or stepping).
|
||||
|
||||
// Breakpoint information
|
||||
Tracepoint bool // Tracepoint flag
|
||||
@ -103,48 +103,6 @@ func (iae InvalidAddressError) Error() string {
|
||||
return fmt.Sprintf("Invalid address %#v\n", iae.address)
|
||||
}
|
||||
|
||||
func (dbp *Process) setBreakpoint(tid int, addr uint64, kind BreakpointKind) (*Breakpoint, error) {
|
||||
if bp, ok := dbp.FindBreakpoint(addr); ok {
|
||||
return nil, BreakpointExistsError{bp.File, bp.Line, bp.Addr}
|
||||
}
|
||||
|
||||
f, l, fn := dbp.goSymTable.PCToLine(uint64(addr))
|
||||
if fn == nil {
|
||||
return nil, InvalidAddressError{address: addr}
|
||||
}
|
||||
|
||||
newBreakpoint := &Breakpoint{
|
||||
FunctionName: fn.Name,
|
||||
File: f,
|
||||
Line: l,
|
||||
Addr: addr,
|
||||
Kind: kind,
|
||||
Cond: nil,
|
||||
HitCount: map[int]uint64{},
|
||||
}
|
||||
|
||||
if kind != UserBreakpoint {
|
||||
dbp.tempBreakpointIDCounter++
|
||||
newBreakpoint.ID = dbp.tempBreakpointIDCounter
|
||||
} else {
|
||||
dbp.breakpointIDCounter++
|
||||
newBreakpoint.ID = dbp.breakpointIDCounter
|
||||
}
|
||||
|
||||
thread := dbp.Threads[tid]
|
||||
originalData, err := thread.readMemory(uintptr(addr), dbp.arch.BreakpointSize())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := dbp.writeSoftwareBreakpoint(thread, addr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newBreakpoint.OriginalData = originalData
|
||||
dbp.Breakpoints[addr] = newBreakpoint
|
||||
|
||||
return newBreakpoint, nil
|
||||
}
|
||||
|
||||
func (dbp *Process) writeSoftwareBreakpoint(thread *Thread, addr uint64) error {
|
||||
_, err := thread.writeMemory(uintptr(addr), dbp.arch.BreakpointInstruction())
|
||||
return err
|
||||
|
71
proc/proc.go
71
proc/proc.go
@ -51,7 +51,7 @@ type Process struct {
|
||||
os *OSProcessDetails
|
||||
arch Arch
|
||||
breakpointIDCounter int
|
||||
tempBreakpointIDCounter int
|
||||
internalBreakpointIDCounter int
|
||||
firstStart bool
|
||||
halt bool
|
||||
exited bool
|
||||
@ -224,21 +224,48 @@ func (dbp *Process) RequestManualStop() error {
|
||||
// SetBreakpoint sets a breakpoint at addr, and stores it in the process wide
|
||||
// break point table. Setting a break point must be thread specific due to
|
||||
// ptrace actions needing the thread to be in a signal-delivery-stop.
|
||||
func (dbp *Process) SetBreakpoint(addr uint64) (*Breakpoint, error) {
|
||||
if dbp.exited {
|
||||
return nil, &ProcessExitedError{}
|
||||
}
|
||||
return dbp.setBreakpoint(dbp.CurrentThread.ID, addr, UserBreakpoint)
|
||||
}
|
||||
func (dbp *Process) SetBreakpoint(addr uint64, kind BreakpointKind, cond ast.Expr) (*Breakpoint, error) {
|
||||
tid := dbp.CurrentThread.ID
|
||||
|
||||
// SetTempBreakpoint sets a temp breakpoint. Used during 'next' operations.
|
||||
func (dbp *Process) SetTempBreakpoint(addr uint64, kind BreakpointKind, cond ast.Expr) (*Breakpoint, error) {
|
||||
bp, err := dbp.setBreakpoint(dbp.CurrentThread.ID, addr, kind)
|
||||
if bp, ok := dbp.FindBreakpoint(addr); ok {
|
||||
return nil, BreakpointExistsError{bp.File, bp.Line, bp.Addr}
|
||||
}
|
||||
|
||||
f, l, fn := dbp.goSymTable.PCToLine(uint64(addr))
|
||||
if fn == nil {
|
||||
return nil, InvalidAddressError{address: addr}
|
||||
}
|
||||
|
||||
newBreakpoint := &Breakpoint{
|
||||
FunctionName: fn.Name,
|
||||
File: f,
|
||||
Line: l,
|
||||
Addr: addr,
|
||||
Kind: kind,
|
||||
Cond: cond,
|
||||
HitCount: map[int]uint64{},
|
||||
}
|
||||
|
||||
if kind != UserBreakpoint {
|
||||
dbp.internalBreakpointIDCounter++
|
||||
newBreakpoint.ID = dbp.internalBreakpointIDCounter
|
||||
} else {
|
||||
dbp.breakpointIDCounter++
|
||||
newBreakpoint.ID = dbp.breakpointIDCounter
|
||||
}
|
||||
|
||||
thread := dbp.Threads[tid]
|
||||
originalData, err := thread.readMemory(uintptr(addr), dbp.arch.BreakpointSize())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bp.Cond = cond
|
||||
return bp, nil
|
||||
if err := dbp.writeSoftwareBreakpoint(thread, addr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newBreakpoint.OriginalData = originalData
|
||||
dbp.Breakpoints[addr] = newBreakpoint
|
||||
|
||||
return newBreakpoint, nil
|
||||
}
|
||||
|
||||
// ClearBreakpoint clears the breakpoint at addr.
|
||||
@ -280,7 +307,7 @@ func (dbp *Process) Next() (err error) {
|
||||
switch err.(type) {
|
||||
case ThreadBlockedError, NoReturnAddr: // Noop
|
||||
default:
|
||||
dbp.ClearTempBreakpoints()
|
||||
dbp.ClearInternalBreakpoints()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -330,7 +357,7 @@ func (dbp *Process) Continue() error {
|
||||
}
|
||||
}
|
||||
return dbp.conditionErrors()
|
||||
case dbp.CurrentThread.onTriggeredTempBreakpoint():
|
||||
case dbp.CurrentThread.onTriggeredInternalBreakpoint():
|
||||
if dbp.CurrentThread.CurrentBreakpoint.Kind == StepBreakpoint {
|
||||
// See description of proc.(*Process).next for the meaning of StepBreakpoints
|
||||
if err := dbp.conditionErrors(); err != nil {
|
||||
@ -351,7 +378,7 @@ func (dbp *Process) Continue() error {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := dbp.ClearTempBreakpoints(); err != nil {
|
||||
if err := dbp.ClearInternalBreakpoints(); err != nil {
|
||||
return err
|
||||
}
|
||||
return dbp.conditionErrors()
|
||||
@ -362,7 +389,7 @@ func (dbp *Process) Continue() error {
|
||||
return err
|
||||
}
|
||||
if onNextGoroutine {
|
||||
err := dbp.ClearTempBreakpoints()
|
||||
err := dbp.ClearInternalBreakpoints()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -389,12 +416,12 @@ func (dbp *Process) conditionErrors() error {
|
||||
}
|
||||
|
||||
// pick a new dbp.CurrentThread, with the following priority:
|
||||
// - a thread with onTriggeredTempBreakpoint() == true
|
||||
// - a thread with onTriggeredInternalBreakpoint() == true
|
||||
// - a thread with onTriggeredBreakpoint() == true (prioritizing trapthread)
|
||||
// - trapthread
|
||||
func (dbp *Process) pickCurrentThread(trapthread *Thread) error {
|
||||
for _, th := range dbp.Threads {
|
||||
if th.onTriggeredTempBreakpoint() {
|
||||
if th.onTriggeredInternalBreakpoint() {
|
||||
return dbp.SwitchThread(th.ID)
|
||||
}
|
||||
}
|
||||
@ -425,7 +452,7 @@ func (dbp *Process) Step() (err error) {
|
||||
switch err.(type) {
|
||||
case ThreadBlockedError, NoReturnAddr: // Noop
|
||||
default:
|
||||
dbp.ClearTempBreakpoints()
|
||||
dbp.ClearInternalBreakpoints()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -461,7 +488,7 @@ func (dbp *Process) StepInstruction() (err error) {
|
||||
}
|
||||
if dbp.SelectedGoroutine.thread == nil {
|
||||
// Step called on parked goroutine
|
||||
if _, err := dbp.SetTempBreakpoint(dbp.SelectedGoroutine.PC, NextBreakpoint, sameGoroutineCondition(dbp.SelectedGoroutine)); err != nil {
|
||||
if _, err := dbp.SetBreakpoint(dbp.SelectedGoroutine.PC, NextBreakpoint, sameGoroutineCondition(dbp.SelectedGoroutine)); err != nil {
|
||||
return err
|
||||
}
|
||||
return dbp.Continue()
|
||||
@ -715,7 +742,7 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e
|
||||
|
||||
panicpc, err := dbp.FindFunctionLocation("runtime.startpanic", true, 0)
|
||||
if err == nil {
|
||||
bp, err := dbp.SetBreakpoint(panicpc)
|
||||
bp, err := dbp.SetBreakpoint(panicpc, UserBreakpoint, nil)
|
||||
if err == nil {
|
||||
bp.Name = "unrecovered-panic"
|
||||
bp.ID = -1
|
||||
@ -726,7 +753,7 @@ func initializeDebugProcess(dbp *Process, path string, attach bool) (*Process, e
|
||||
return dbp, nil
|
||||
}
|
||||
|
||||
func (dbp *Process) ClearTempBreakpoints() error {
|
||||
func (dbp *Process) ClearInternalBreakpoints() error {
|
||||
for _, bp := range dbp.Breakpoints {
|
||||
if !bp.Internal() {
|
||||
continue
|
||||
|
@ -138,7 +138,7 @@ func setFunctionBreakpoint(p *Process, fname string) (*Breakpoint, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.SetBreakpoint(addr)
|
||||
return p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
}
|
||||
|
||||
func TestHalt(t *testing.T) {
|
||||
@ -188,7 +188,7 @@ func TestStep(t *testing.T) {
|
||||
helloworldfunc := p.goSymTable.LookupFunc("main.helloworld")
|
||||
helloworldaddr := helloworldfunc.Entry
|
||||
|
||||
_, err := p.SetBreakpoint(helloworldaddr)
|
||||
_, err := p.SetBreakpoint(helloworldaddr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
|
||||
@ -210,7 +210,7 @@ func TestBreakpoint(t *testing.T) {
|
||||
helloworldfunc := p.goSymTable.LookupFunc("main.helloworld")
|
||||
helloworldaddr := helloworldfunc.Entry
|
||||
|
||||
bp, err := p.SetBreakpoint(helloworldaddr)
|
||||
bp, err := p.SetBreakpoint(helloworldaddr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
|
||||
@ -237,7 +237,7 @@ func TestBreakpointInSeperateGoRoutine(t *testing.T) {
|
||||
t.Fatal("No fn exists")
|
||||
}
|
||||
|
||||
_, err := p.SetBreakpoint(fn.Entry)
|
||||
_, err := p.SetBreakpoint(fn.Entry, UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -261,7 +261,7 @@ func TestBreakpointInSeperateGoRoutine(t *testing.T) {
|
||||
|
||||
func TestBreakpointWithNonExistantFunction(t *testing.T) {
|
||||
withTestProcess("testprog", t, func(p *Process, fixture protest.Fixture) {
|
||||
_, err := p.SetBreakpoint(0)
|
||||
_, err := p.SetBreakpoint(0, UserBreakpoint, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Should not be able to break at non existant function")
|
||||
}
|
||||
@ -271,7 +271,7 @@ func TestBreakpointWithNonExistantFunction(t *testing.T) {
|
||||
func TestClearBreakpointBreakpoint(t *testing.T) {
|
||||
withTestProcess("testprog", t, func(p *Process, fixture protest.Fixture) {
|
||||
fn := p.goSymTable.LookupFunc("main.sleepytime")
|
||||
bp, err := p.SetBreakpoint(fn.Entry)
|
||||
bp, err := p.SetBreakpoint(fn.Entry, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
bp, err = p.ClearBreakpoint(fn.Entry)
|
||||
@ -324,7 +324,7 @@ func testseq(program string, contFunc contFunc, testcases []nextTest, initialLoc
|
||||
var pc uint64
|
||||
pc, err = p.FindFileLocation(fixture.Source, testcases[0].begin)
|
||||
assertNoError(err, t, "FindFileLocation()")
|
||||
bp, err = p.SetBreakpoint(pc)
|
||||
bp, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
|
||||
}
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
@ -579,7 +579,7 @@ func TestFindReturnAddress(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = p.SetBreakpoint(start)
|
||||
_, err = p.SetBreakpoint(start, UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -605,7 +605,7 @@ func TestFindReturnAddressTopOfStackFn(t *testing.T) {
|
||||
if fn == nil {
|
||||
t.Fatalf("could not find function %s", fnName)
|
||||
}
|
||||
if _, err := p.SetBreakpoint(fn.Entry); err != nil {
|
||||
if _, err := p.SetBreakpoint(fn.Entry, UserBreakpoint, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.Continue(); err != nil {
|
||||
@ -628,7 +628,7 @@ func TestSwitchThread(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = p.SetBreakpoint(pc)
|
||||
_, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -670,7 +670,7 @@ func TestCGONext(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = p.SetBreakpoint(pc)
|
||||
_, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -953,7 +953,7 @@ func TestBreakpointOnFunctionEntry(t *testing.T) {
|
||||
withTestProcess("testprog", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, err := p.FindFunctionLocation("main.main", false, 0)
|
||||
assertNoError(err, t, "FindFunctionLocation()")
|
||||
_, err = p.SetBreakpoint(addr)
|
||||
_, err = p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
_, ln := currentLineNumber(p, t)
|
||||
@ -977,7 +977,7 @@ func TestIssue239(t *testing.T) {
|
||||
withTestProcess("is sue239", t, func(p *Process, fixture protest.Fixture) {
|
||||
pos, _, err := p.goSymTable.LineToPC(fixture.Source, 17)
|
||||
assertNoError(err, t, "LineToPC()")
|
||||
_, err = p.SetBreakpoint(pos)
|
||||
_, err = p.SetBreakpoint(pos, UserBreakpoint, nil)
|
||||
assertNoError(err, t, fmt.Sprintf("SetBreakpoint(%d)", pos))
|
||||
assertNoError(p.Continue(), t, fmt.Sprintf("Continue()"))
|
||||
})
|
||||
@ -1238,7 +1238,7 @@ func TestBreakpointCounts(t *testing.T) {
|
||||
withTestProcess("bpcountstest", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 12)
|
||||
assertNoError(err, t, "LineToPC")
|
||||
bp, err := p.SetBreakpoint(addr)
|
||||
bp, err := p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
for {
|
||||
@ -1289,7 +1289,7 @@ func TestBreakpointCountsWithDetection(t *testing.T) {
|
||||
withTestProcess("bpcountstest", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 12)
|
||||
assertNoError(err, t, "LineToPC")
|
||||
bp, err := p.SetBreakpoint(addr)
|
||||
bp, err := p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
for {
|
||||
@ -1384,7 +1384,7 @@ func TestIssue262(t *testing.T) {
|
||||
withTestProcess("issue262", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 11)
|
||||
assertNoError(err, t, "LineToPC")
|
||||
_, err = p.SetBreakpoint(addr)
|
||||
_, err = p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
@ -1400,12 +1400,13 @@ func TestIssue262(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIssue305(t *testing.T) {
|
||||
// If 'next' hits a breakpoint on the goroutine it's stepping through the temp breakpoints aren't cleared
|
||||
// preventing further use of 'next' command
|
||||
// If 'next' hits a breakpoint on the goroutine it's stepping through
|
||||
// the internal breakpoints aren't cleared preventing further use of
|
||||
// 'next' command
|
||||
withTestProcess("issue305", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 5)
|
||||
assertNoError(err, t, "LineToPC()")
|
||||
_, err = p.SetBreakpoint(addr)
|
||||
_, err = p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
@ -1445,7 +1446,7 @@ func TestCondBreakpoint(t *testing.T) {
|
||||
withTestProcess("parallel_next", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 9)
|
||||
assertNoError(err, t, "LineToPC")
|
||||
bp, err := p.SetBreakpoint(addr)
|
||||
bp, err := p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
bp.Cond = &ast.BinaryExpr{
|
||||
Op: token.EQL,
|
||||
@ -1469,7 +1470,7 @@ func TestCondBreakpointError(t *testing.T) {
|
||||
withTestProcess("parallel_next", t, func(p *Process, fixture protest.Fixture) {
|
||||
addr, _, err := p.goSymTable.LineToPC(fixture.Source, 9)
|
||||
assertNoError(err, t, "LineToPC")
|
||||
bp, err := p.SetBreakpoint(addr)
|
||||
bp, err := p.SetBreakpoint(addr, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
bp.Cond = &ast.BinaryExpr{
|
||||
Op: token.EQL,
|
||||
@ -1549,7 +1550,7 @@ func TestIssue384(t *testing.T) {
|
||||
withTestProcess("issue384", t, func(p *Process, fixture protest.Fixture) {
|
||||
start, _, err := p.goSymTable.LineToPC(fixture.Source, 13)
|
||||
assertNoError(err, t, "LineToPC()")
|
||||
_, err = p.SetBreakpoint(start)
|
||||
_, err = p.SetBreakpoint(start, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
_, err = evalVariable(p, "st")
|
||||
@ -1562,7 +1563,7 @@ func TestIssue332_Part1(t *testing.T) {
|
||||
withTestProcess("issue332", t, func(p *Process, fixture protest.Fixture) {
|
||||
start, _, err := p.goSymTable.LineToPC(fixture.Source, 8)
|
||||
assertNoError(err, t, "LineToPC()")
|
||||
_, err = p.SetBreakpoint(start)
|
||||
_, err = p.SetBreakpoint(start, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
assertNoError(p.Next(), t, "first Next()")
|
||||
@ -1588,7 +1589,7 @@ func TestIssue332_Part2(t *testing.T) {
|
||||
withTestProcess("issue332", t, func(p *Process, fixture protest.Fixture) {
|
||||
start, _, err := p.goSymTable.LineToPC(fixture.Source, 8)
|
||||
assertNoError(err, t, "LineToPC()")
|
||||
_, err = p.SetBreakpoint(start)
|
||||
_, err = p.SetBreakpoint(start, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
|
||||
@ -1639,7 +1640,7 @@ func TestIssue414(t *testing.T) {
|
||||
withTestProcess("math", t, func(p *Process, fixture protest.Fixture) {
|
||||
start, _, err := p.goSymTable.LineToPC(fixture.Source, 9)
|
||||
assertNoError(err, t, "LineToPC()")
|
||||
_, err = p.SetBreakpoint(start)
|
||||
_, err = p.SetBreakpoint(start, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
for {
|
||||
@ -1905,10 +1906,10 @@ func TestUnsupportedArch(t *testing.T) {
|
||||
|
||||
func TestIssue573(t *testing.T) {
|
||||
// calls to runtime.duffzero and runtime.duffcopy jump directly into the middle
|
||||
// of the function and the temp 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 *Process, fixture protest.Fixture) {
|
||||
f := p.goSymTable.LookupFunc("main.foo")
|
||||
_, err := p.SetBreakpoint(f.Entry)
|
||||
_, err := p.SetBreakpoint(f.Entry, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
assertNoError(p.Step(), t, "Step() #1")
|
||||
@ -2044,7 +2045,7 @@ func TestStepConcurrentDirect(t *testing.T) {
|
||||
withTestProcess("teststepconcurrent", t, func(p *Process, fixture protest.Fixture) {
|
||||
pc, err := p.FindFileLocation(fixture.Source, 37)
|
||||
assertNoError(err, t, "FindFileLocation()")
|
||||
bp, err := p.SetBreakpoint(pc)
|
||||
bp, err := p.SetBreakpoint(pc, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
@ -2095,7 +2096,7 @@ func TestStepConcurrentPtr(t *testing.T) {
|
||||
withTestProcess("teststepconcurrent", t, func(p *Process, fixture protest.Fixture) {
|
||||
pc, err := p.FindFileLocation(fixture.Source, 24)
|
||||
assertNoError(err, t, "FindFileLocation()")
|
||||
_, err = p.SetBreakpoint(pc)
|
||||
_, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
kvals := map[int]int64{}
|
||||
@ -2129,7 +2130,7 @@ func TestStepConcurrentPtr(t *testing.T) {
|
||||
assertNoError(p.Step(), t, "Step()")
|
||||
for nextInProgress(p) {
|
||||
if p.SelectedGoroutine.ID == gid {
|
||||
t.Fatalf("step did not step into function call (but temp 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()")
|
||||
}
|
||||
@ -2161,7 +2162,7 @@ func TestStepOnCallPtrInstr(t *testing.T) {
|
||||
withTestProcess("teststepprog", t, func(p *Process, fixture protest.Fixture) {
|
||||
pc, err := p.FindFileLocation(fixture.Source, 10)
|
||||
assertNoError(err, t, "FindFileLocation()")
|
||||
_, err = p.SetBreakpoint(pc)
|
||||
_, err = p.SetBreakpoint(pc, UserBreakpoint, nil)
|
||||
assertNoError(err, t, "SetBreakpoint()")
|
||||
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
|
@ -182,14 +182,14 @@ func (dbp *Process) next(stepInto bool) error {
|
||||
|
||||
if instr.DestLoc != nil && instr.DestLoc.Fn != nil {
|
||||
if err := dbp.setStepIntoBreakpoint([]AsmInstruction{instr}, cond); err != nil {
|
||||
dbp.ClearTempBreakpoints()
|
||||
dbp.ClearInternalBreakpoints()
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Non-absolute call instruction, set a StepBreakpoint here
|
||||
if _, err := dbp.SetTempBreakpoint(instr.Loc.PC, StepBreakpoint, cond); err != nil {
|
||||
if _, err := dbp.SetBreakpoint(instr.Loc.PC, StepBreakpoint, cond); err != nil {
|
||||
if _, ok := err.(BreakpointExistsError); !ok {
|
||||
dbp.ClearTempBreakpoints()
|
||||
dbp.ClearInternalBreakpoints()
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -219,10 +219,10 @@ func (dbp *Process) next(stepInto bool) error {
|
||||
}
|
||||
}
|
||||
if deferpc != 0 && deferpc != topframe.Current.PC {
|
||||
bp, err := dbp.SetTempBreakpoint(deferpc, NextDeferBreakpoint, cond)
|
||||
bp, err := dbp.SetBreakpoint(deferpc, NextDeferBreakpoint, cond)
|
||||
if err != nil {
|
||||
if _, ok := err.(BreakpointExistsError); !ok {
|
||||
dbp.ClearTempBreakpoints()
|
||||
dbp.ClearInternalBreakpoints()
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -254,7 +254,7 @@ func (dbp *Process) next(stepInto bool) error {
|
||||
|
||||
// Add a breakpoint on the return address for the current frame
|
||||
pcs = append(pcs, topframe.Ret)
|
||||
return dbp.setTempBreakpoints(topframe.Current.PC, pcs, NextBreakpoint, cond)
|
||||
return dbp.setInternalBreakpoints(topframe.Current.PC, pcs, NextBreakpoint, cond)
|
||||
}
|
||||
|
||||
func (dbp *Process) setStepIntoBreakpoint(text []AsmInstruction, cond ast.Expr) error {
|
||||
@ -288,7 +288,7 @@ func (dbp *Process) setStepIntoBreakpoint(text []AsmInstruction, cond ast.Expr)
|
||||
|
||||
// Set a breakpoint after the function's prologue
|
||||
pc, _ := dbp.FirstPCAfterPrologue(fn, false)
|
||||
if _, err := dbp.SetTempBreakpoint(pc, NextBreakpoint, cond); err != nil {
|
||||
if _, err := dbp.SetBreakpoint(pc, NextBreakpoint, cond); err != nil {
|
||||
if _, ok := err.(BreakpointExistsError); !ok {
|
||||
return err
|
||||
}
|
||||
@ -297,16 +297,16 @@ func (dbp *Process) setStepIntoBreakpoint(text []AsmInstruction, cond ast.Expr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// setTempBreakpoints 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
|
||||
func (dbp *Process) setTempBreakpoints(curpc uint64, pcs []uint64, kind BreakpointKind, cond ast.Expr) error {
|
||||
func (dbp *Process) setInternalBreakpoints(curpc uint64, pcs []uint64, kind BreakpointKind, cond ast.Expr) error {
|
||||
for i := range pcs {
|
||||
if pcs[i] == curpc || pcs[i] == curpc-1 {
|
||||
continue
|
||||
}
|
||||
if _, err := dbp.SetTempBreakpoint(pcs[i], kind, cond); err != nil {
|
||||
if _, err := dbp.SetBreakpoint(pcs[i], kind, cond); err != nil {
|
||||
if _, ok := err.(BreakpointExistsError); !ok {
|
||||
dbp.ClearTempBreakpoints()
|
||||
dbp.ClearInternalBreakpoints()
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -461,7 +461,7 @@ func (thread *Thread) onTriggeredBreakpoint() bool {
|
||||
return (thread.CurrentBreakpoint != nil) && thread.BreakpointConditionMet
|
||||
}
|
||||
|
||||
func (thread *Thread) onTriggeredTempBreakpoint() bool {
|
||||
func (thread *Thread) onTriggeredInternalBreakpoint() bool {
|
||||
return thread.onTriggeredBreakpoint() && thread.CurrentBreakpoint.Internal()
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ func (d *Debugger) Restart() error {
|
||||
if oldBp.ID < 0 {
|
||||
continue
|
||||
}
|
||||
newBp, err := p.SetBreakpoint(oldBp.Addr)
|
||||
newBp, err := p.SetBreakpoint(oldBp.Addr, proc.UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -224,7 +224,7 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bp, err := d.process.SetBreakpoint(addr)
|
||||
bp, err := d.process.SetBreakpoint(addr, proc.UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -254,7 +254,7 @@ func (d *Debugger) AmendBreakpoint(amend *api.Breakpoint) error {
|
||||
}
|
||||
|
||||
func (d *Debugger) CancelNext() error {
|
||||
return d.process.ClearTempBreakpoints()
|
||||
return d.process.ClearInternalBreakpoints()
|
||||
}
|
||||
|
||||
func copyBreakpointInfo(bp *proc.Breakpoint, requested *api.Breakpoint) (err error) {
|
||||
|
Loading…
Reference in New Issue
Block a user