proc: bugfix: clearing temp breakpoints

Temp breakpoints should be cleared even if a non-temp breakpoint is
triggered on the same goroutine that the temp breakpoints are set on.

Fixes #305
This commit is contained in:
aarzilli 2016-01-16 09:13:15 +01:00
parent b839eda2a9
commit 453bd0217f
5 changed files with 45 additions and 1 deletions

7
_fixtures/issue305.go Normal file

@ -0,0 +1,7 @@
package main
func main() {
for i := 0; i < 10; i++ {
println(i)
}
}

@ -353,6 +353,7 @@ func (dbp *Process) Continue() error {
if err := dbp.pickCurrentThread(trapthread); err != nil {
return err
}
switch {
case dbp.CurrentThread.CurrentBreakpoint == nil:
// runtime.Breakpoint or manual stop
@ -367,6 +368,9 @@ func (dbp *Process) Continue() error {
case dbp.CurrentThread.onTriggeredTempBreakpoint():
return dbp.clearTempBreakpoints()
case dbp.CurrentThread.onTriggeredBreakpoint():
if dbp.CurrentThread.onNextGoroutine() {
return dbp.clearTempBreakpoints()
}
return nil
default:
// not a manual stop, not on runtime.Breakpoint, not on a breakpoint, just repeat

@ -1315,6 +1315,25 @@ 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
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)
assertNoError(err, t, "SetBreakpoint()")
assertNoError(p.Continue(), t, "Continue()")
assertNoError(p.Next(), t, "Next() 1")
assertNoError(p.Next(), t, "Next() 2")
assertNoError(p.Next(), t, "Next() 3")
assertNoError(p.Next(), t, "Next() 4")
assertNoError(p.Next(), t, "Next() 5")
})
}
func TestIssue341(t *testing.T) {
// pointer loop through map entries
withTestProcess("testvariables3", t, func(p *Process, fixture protest.Fixture) {

@ -359,3 +359,17 @@ func (thread *Thread) onRuntimeBreakpoint() bool {
}
return loc.Fn != nil && loc.Fn.Name == "runtime.breakpoint"
}
// Returns true if this thread is on the goroutine requested by the current 'next' command
func (th *Thread) onNextGoroutine() bool {
var bp *Breakpoint
for i := range th.dbp.Breakpoints {
if th.dbp.Breakpoints[i].Temp {
bp = th.dbp.Breakpoints[i]
}
}
if bp == nil {
return false
}
return bp.checkCondition(th)
}