================
@@ -589,14 +621,69 @@ bool ThreadList::WillResume(RunDirection &direction) {
assert(thread_sp->GetCurrentPlan()->GetDirection() == direction);
// You can't say "stop others" and also want yourself to be
suspended.
assert(thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
+
----------------
barsolo2000 wrote:
@jimingham , I might be wrong, but from my understanding, the flow of
WillResume is:
1. Cleanup, we clear `m_threads_stepping_over_bp` and pop all existing
`StepOverBreakpoint` plans. On the first cycle there are no plans yet. on later
cycles, this pops leftover plans from threads that didn't finish their step in
the previous cycle. we call SetReenableBreakpointsite() before each pop.
After this cleanup, no thread has a StepOverBreakpoint plan.
2. StopOthers scans: we scan for threads whose current plan has
stopothers()=true. since we just popped all stepoverbreakpoint plans, these
wont contibue here. the only way thread_to_run gets set in this scan is if some
thread has non-breapoint stopothers plan. in our case, we shouldnt have a
thread that has such plan, so thread_to_ryb remains nullptr and we fall to the
else branch.
3. the else branch:
we create the breakpoint_groups, loop through all the threads and call
`SetupToStepOverBreakpointIfNeeded` on each one (line 617), this function
checks if the thread is sitting on a bp that needs stepping over (we use
`m_stopped_at_unexecuted_bp` which lives on the `thread`, not the plan, so it
survives the pop). If we indeed need to step over, it pushes a new
`StepOverBreakpoint` plan.
Immediately after `SetupToStepOverBreakpointIfNeeded` returns true, we get the
bp address via `GetBreakpointLoadAddress()` and group it in
`breakpoint_groups[bp_addr].push_back(thread_sp);`. We also check
`ShouldRunBeforePublicStop()` and set `found_run_before_public_stop` if found.
4. if no `found_run_before_public_stop` was found, we process the groups and if
the group has more than 1 thread at the same breakpoint. we register each
threads in `m_threads_stepping_over_bp` for tracking, set
`SetDeferReenableBreakpointSite(true)` on each plan so re-enable goes through
the callback instead of directly, and pick the largest group for
batched_step_threads.
5. we get to `if (!batched_step_threads.empty())` if we have a batched vCont.
Each thread in the batch calls `ShouldResume(eStateStepping)`, which triggers
`DoWillResume` on its plan. That what disable the bp (one z0), all other
threads get ShouldResume(eStateSuspeneded). The process sends a single batched
vCont.
6.In later cycles: When the process stops again, some threads may have
completed their step (plan pops, calls `ThreadFinishedSteppingOverBreakpoint`
to decrement the tracking count) and some may not (plan stays on the stack).
then willresume is called again, step 1 (from above) pops the leftover plans,
and step 3 recreatess plans only for threads that still need to step (those
whose `m_stopped_at_unexecuted_bp` hasn't been cleared), which creates a natual
re-batching. 10->5->2->1 (for example). the bp stays disabled throughout all
cycles, only the last thread finsihes does
`ThreadFinishedSteppingOverBreakpoint` see an empty tracking set and sends the
single Z0.
we call `SetupToStepOverBreakpointIfNeeded` both in the if statement (line 597)
and in the else statement in line 617.
again, I might be 100% WRONG and confused. so please, lmk if im mistaken
https://github.com/llvm/llvm-project/pull/180101
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits