Skip to content

Commit

Permalink
proc: skip trapthread for harcoded breakpoints after manual stop (#3582)
Browse files Browse the repository at this point in the history
When using debugserver as a backend a manual stop request can end up
looking like an hardcoded breakpoint if the thread that receives the
stop request happens to be stopped right after a hardcoded breakpoint
(and the space between functions is filled with hardcoded breakpoints).
When creating hardcoded breakpoints we should ignore the trapthread if
a manual stop has been requested.

This problem made TestSetBreakpointWhileRunning and
TestSetFunctionBreakpointWhileRunning fail on macOS between 1.7% and 6%
of the time.

TestIssue1376 in rr_test.go used to pass accidentally, the stop when
the start of the recording was reached was mistaken for a hardcoded
breakpoint.
  • Loading branch information
aarzilli authored Nov 27, 2023
1 parent 4ed41e9 commit 37db3e8
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion pkg/proc/target_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ func (grp *TargetGroup) Continue() error {
dbp.StopReason = StopWatchpoint
}
return conditionErrors(grp)
case stopReason == StopLaunched:
return nil
default:
// not a manual stop, not on runtime.Breakpoint, not on a breakpoint, just repeat
}
Expand Down Expand Up @@ -1342,6 +1344,9 @@ func (t *Target) handleHardcodedBreakpoints(grp *TargetGroup, trapthread Thread,
if (thread.ThreadID() != trapthread.ThreadID()) && !thread.SoftExc() {
continue
}
if (thread.ThreadID() == trapthread.ThreadID()) && grp.cctx.GetManualStopRequested() {
continue
}

loc, err := thread.Location()
if err != nil || loc.Fn == nil {
Expand Down Expand Up @@ -1371,7 +1376,11 @@ func (t *Target) handleHardcodedBreakpoints(grp *TargetGroup, trapthread Thread,
}
setHardcodedBreakpoint(thread, loc)
case g == nil || t.fncallForG[g.ID] == nil:
if isHardcodedBreakpoint(thread, loc.PC) > 0 {
// Check that PC is inside a function (not the entry point) and the
// preceding instruction is a hardcoded breakpoint.
// We explicitly check for entry points of functions because the space
// between functions is usually filled with hardcoded breakpoints.
if (loc.Fn == nil || loc.Fn.Entry != loc.PC) && isHardcodedBreakpoint(thread, loc.PC) > 0 {
stepOverBreak(thread, loc.PC)
setHardcodedBreakpoint(thread, loc)
}
Expand Down

0 comments on commit 37db3e8

Please sign in to comment.