Files
llvm-project/lldb/unittests/Thread/ThreadTest.cpp
Igor Kudrin f59d12001f [lldb] Keep the unexpected b/p state for suspended threads (#174264)
This fixes stepping out for a case when two threads reach the
stepping-out target breakpoint simultaneously, but a concurrent thread
executes the breakpoint first. The issue affects platforms with software
breakpoints. The scenario is as follows:

* The `step-out` command is executed for thread `A`.
* `ThreadPlanStepOut` creates a breakpoint at the target location.
* All threads are resumed, because the `step-out` command does not
  suspend other threads.
* Threads `A` and `B` reach the stepping-out address at the same time,
  but `B` executes the breakpoint instruction first.
* `SetThreadStoppedAtUnexecutedBP()` is called for thread `A`, and
  `SetThreadHitBreakpointSite()` is called for thread `B`.
* Thread `B` has no plans to stop at this location, so
  `ThreadPlanStepOverBreakpoint` is scheduled.
* The plan disables the breakpoint and resumes thread `B` with
  `eStateStepping`; for thread `A`, `ShouldResume(eStateSuspended)` is
  called, which clears `m_stopped_at_unexecuted_bp`.
* After the stepping, `ThreadPlanStepOverBreakpoint` finishes, the
  breakpoint is re-enabled, and all threads are resumed.
* At this moment, thread `A` is still at the location of the breakpoint,
  but `m_stopped_at_unexecuted_bp` is cleared, so
  `Thread::SetupToStepOverBreakpointIfNeeded()` schedules
  `ThreadPlanStepOverBreakpoint` for it.
* `ThreadPlanStepOverBreakpoint` steps over the target breakpoint, so
  `ThreadPlanStepOut` can't catch the execution there.
2026-01-08 14:11:35 -08:00

8.8 KiB