mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 01:27:16 +08:00
proc: fix bug with range-over-func stepping (#3778)
Set a breakpoint on the return address of the current function, if it's a range-over-func body, and clear the stepping breakpoints for the current function (except the entry one) when its hit. Without this what can happen is the following: 1. the range-over-func body finishes and returns to the iterator 2. the iterator calls back into the range-over-func body 3. a stepping breakpoint that's inside the prologue gets hit Updates #3733
This commit is contained in:
committed by
GitHub
parent
3ae22627df
commit
c1366e90cc
@ -144,7 +144,10 @@ const (
|
||||
// goroutine.
|
||||
StepIntoNewProcBreakpoint
|
||||
|
||||
steppingMask = NextBreakpoint | NextDeferBreakpoint | StepBreakpoint | StepIntoNewProcBreakpoint
|
||||
// NextInactivatedBreakpoint a NextBreakpoint that has been inactivated, see rangeFrameInactivateNextBreakpoints
|
||||
NextInactivatedBreakpoint
|
||||
|
||||
steppingMask = NextBreakpoint | NextDeferBreakpoint | StepBreakpoint | StepIntoNewProcBreakpoint | NextInactivatedBreakpoint
|
||||
)
|
||||
|
||||
// WatchType is the watchpoint type
|
||||
@ -221,6 +224,8 @@ func (bp *Breakpoint) VerboseDescr() []string {
|
||||
r = append(r, "PluginOpenBreakpoint")
|
||||
case StepIntoNewProcBreakpoint:
|
||||
r = append(r, "StepIntoNewProcBreakpoint")
|
||||
case NextInactivatedBreakpoint:
|
||||
r = append(r, "NextInactivatedBreakpoint")
|
||||
default:
|
||||
r = append(r, fmt.Sprintf("Unknown %d", breaklet.Kind))
|
||||
}
|
||||
@ -318,6 +323,9 @@ func (bpstate *BreakpointState) checkCond(tgt *Target, breaklet *Breaklet, threa
|
||||
case StackResizeBreakpoint, PluginOpenBreakpoint, StepIntoNewProcBreakpoint:
|
||||
// no further checks
|
||||
|
||||
case NextInactivatedBreakpoint:
|
||||
active = false
|
||||
|
||||
default:
|
||||
bpstate.CondError = fmt.Errorf("internal error unknown breakpoint kind %v", breaklet.Kind)
|
||||
}
|
||||
@ -834,6 +842,29 @@ func (t *Target) ClearSteppingBreakpoints() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Target) clearInactivatedSteppingBreakpoint() error {
|
||||
threads := t.ThreadList()
|
||||
for _, bp := range t.Breakpoints().M {
|
||||
for i := range bp.Breaklets {
|
||||
if bp.Breaklets[i].Kind == NextInactivatedBreakpoint {
|
||||
bp.Breaklets[i] = nil
|
||||
}
|
||||
}
|
||||
cleared, err := t.finishClearBreakpoint(bp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cleared {
|
||||
for _, thread := range threads {
|
||||
if thread.Breakpoint().Breakpoint == bp {
|
||||
thread.Breakpoint().Clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// finishClearBreakpoint clears nil breaklets from the breaklet list of bp
|
||||
// and if it is empty erases the breakpoint.
|
||||
// Returns true if the breakpoint was deleted
|
||||
|
||||
Reference in New Issue
Block a user