230 std::lock_guard<std::recursive_mutex> guard(
GetMutex());
245 thread_sp->IsStillAtLastBreakpointHit()
246 || thread_sp->ShouldRunBeforePublicStop())
247 threads_copy.push_back(thread_sp);
254 if (threads_copy.size() == 0)
258 collection::iterator pos, end = threads_copy.end();
263 "ThreadList::%s: %" PRIu64
" threads, %" PRIu64
264 " unsuspended threads",
265 __FUNCTION__, (uint64_t)
m_threads.size(),
266 (uint64_t)threads_copy.size());
269 bool did_anybody_stop_for_a_reason =
false;
273 bool should_stop =
false;
276 log,
"ThreadList::%s handling interrupt event, should stop set to true",
289 for (pos = threads_copy.begin(); pos != end; ++pos) {
291 thread_sp->GetStopInfo();
297 bool a_thread_needs_to_run =
false;
298 for (pos = threads_copy.begin(); pos != end; ++pos) {
321 if (thread_sp->GetProcess()->GetStopID() > 1)
322 did_anybody_stop_for_a_reason =
true;
324 did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
326 const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
328 if (thread_should_stop)
331 bool this_thread_forces_run = thread_sp->ShouldRunBeforePublicStop();
332 a_thread_needs_to_run |= this_thread_forces_run;
333 if (this_thread_forces_run)
335 "ThreadList::{0} thread: {1:x}, "
336 "says it needs to run before public stop.",
337 __FUNCTION__, thread_sp->GetID());
341 if (a_thread_needs_to_run) {
343 }
else if (!should_stop && !did_anybody_stop_for_a_reason) {
346 "ThreadList::%s we stopped but no threads had a stop reason, "
347 "overriding should_stop and stopping.",
351 LLDB_LOGF(log,
"ThreadList::%s overall should_stop = %i", __FUNCTION__,
355 for (pos = threads_copy.begin(); pos != end; ++pos) {
357 thread_sp->WillStop();
504 std::lock_guard<std::recursive_mutex> guard(
GetMutex());
507 collection::iterator pos, end =
m_threads.end();
514 for (
const auto &thread_sp :
m_threads) {
515 ThreadPlan *plan = thread_sp->GetCurrentPlan();
522 if (bp_plan->GetDeferReenableBreakpointSite()) {
526 bp_plan->SetReenabledBreakpointSite();
527 thread_sp->DiscardPlan();
537 llvm::SmallVector<ThreadSP> batched_step_threads;
550 for (pos =
m_threads.begin(); pos != end; ++pos) {
553 thread_sp->GetCurrentPlan()->StopOthers()) {
554 if (thread_sp->IsOperatingSystemPluginThread() &&
555 !thread_sp->GetBackingThread())
563 thread_to_run = thread_sp;
565 if (thread_sp->ShouldRunBeforePublicStop()) {
567 thread_to_run = thread_sp;
573 if (run_me_only_list.
GetSize(
false) > 0 && !thread_to_run) {
574 if (run_me_only_list.
GetSize(
false) == 1) {
578 (int)((run_me_only_list.
GetSize(
false) * (
double)rand()) /
584 if (thread_to_run !=
nullptr) {
585 direction = thread_to_run->GetCurrentPlan()->GetDirection();
587 direction =
m_process.GetBaseDirection();
594 if (thread_to_run !=
nullptr) {
601 if (thread_to_run->SetupToStepOverBreakpointIfNeeded(direction)) {
605 assert(thread_to_run->GetCurrentPlan()->GetDirection() == direction);
612 llvm::DenseMap<lldb::addr_t, llvm::SmallVector<ThreadSP>> breakpoint_groups;
613 bool found_run_before_public_stop =
false;
615 for (pos =
m_threads.begin(); pos != end; ++pos) {
618 if (thread_sp->IsOperatingSystemPluginThread() &&
619 !thread_sp->GetBackingThread())
621 if (thread_sp->SetupToStepOverBreakpointIfNeeded(direction)) {
625 assert(thread_sp->GetCurrentPlan()->GetDirection() == direction);
630 ThreadPlan *current_plan = thread_sp->GetCurrentPlan();
636 breakpoint_groups[bp_addr].push_back(thread_sp);
639 thread_to_run = thread_sp;
640 if (thread_sp->ShouldRunBeforePublicStop()) {
642 found_run_before_public_stop =
true;
653 if (!found_run_before_public_stop) {
658 for (
auto &group : breakpoint_groups) {
660 llvm::SmallVector<ThreadSP> &threads = group.second;
662 if (threads.size() > 1) {
665 for (
ThreadSP &thread_sp : threads) {
670 ThreadPlan *plan = thread_sp->GetCurrentPlan();
681 if (threads.size() > batched_step_threads.size())
682 batched_step_threads = threads;
688 if (!batched_step_threads.empty())
689 thread_to_run = batched_step_threads[0];
693 if (thread_to_run !=
nullptr) {
695 "Turning on notification of new threads while single "
696 "stepping a thread.");
700 "Turning off notification of new threads while single "
701 "stepping a thread.");
705 bool need_to_resume =
true;
707 if (!batched_step_threads.empty()) {
710 llvm::DenseSet<lldb::tid_t> batch_tids;
711 for (
ThreadSP &thread_sp : batched_step_threads)
712 batch_tids.insert(thread_sp->GetID());
714 for (
const auto &thread_sp :
m_threads) {
715 if (batch_tids.count(thread_sp->GetID()) > 0) {
717 if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
718 need_to_resume =
false;
724 }
else if (thread_to_run ==
nullptr) {
726 for (pos =
m_threads.begin(); pos != end; ++pos) {
730 run_state = thread_sp->GetCurrentPlan()->RunState();
733 if (!thread_sp->ShouldResume(run_state))
734 need_to_resume =
false;
736 if (need_to_resume) {
738 for (pos =
m_threads.begin(); pos != end; ++pos) {
740 while (thread_sp->GetCurrentPlan()->GetDirection() != direction) {
743 thread_sp->DiscardPlan();
748 for (pos =
m_threads.begin(); pos != end; ++pos) {
750 if (thread_sp == thread_to_run) {
754 if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
755 need_to_resume =
false;
761 return need_to_resume;
927 std::lock_guard<std::recursive_mutex> guard(
GetMutex());
935 "ThreadList::%s: Thread 0x%" PRIx64
936 " finished stepping over breakpoint at 0x%" PRIx64
937 " but no threads were registered, re-enabling directly",
938 __FUNCTION__, tid, breakpoint_addr);
940 m_process.GetBreakpointSiteList().FindByAddress(breakpoint_addr))
941 m_process.EnableBreakpointSite(bp_site_sp.get());
946 it->second.erase(tid);
949 "ThreadList::%s: Thread 0x%" PRIx64
950 " finished stepping over breakpoint at 0x%" PRIx64
951 " (%zu threads remaining)",
952 __FUNCTION__, tid, breakpoint_addr,
953 static_cast<size_t>(it->second.size()));
956 if (it->second.empty()) {
958 "ThreadList::%s: All threads finished stepping over breakpoint "
959 "at 0x%" PRIx64
", re-enabling breakpoint",
960 __FUNCTION__, breakpoint_addr);
963 m_process.GetBreakpointSiteList().FindByAddress(breakpoint_addr))
964 m_process.EnableBreakpointSite(bp_site_sp.get());