Skip to content

Commit c14b6e9

Browse files
[lldb][NFC] Move ShouldShow/ShouldSelect logic into Stopinfo (#134160)
This NFC patch simplifies the main loop in HandleProcessStateChanged event by moving duplicated code into the StopInfo class, also allowing StopInfo subclasses to override behavior. More specifically, two functions are created: * ShouldShow: should a Thread with such StopInfo should be printed when the debugger stops? Currently, no StopInfo subclasses override this, but a subsequent patch will fix a bug by making StopInfoBreakpoint check whether the breakpoint is internal. * ShouldSelect: should a Thread with such a StopInfo be selected? This is currently overridden by StopInfoUnixSignal but will, in the future, be overridden by StopInfoBreakpoint.
1 parent f59b5b8 commit c14b6e9

File tree

3 files changed

+36
-69
lines changed

3 files changed

+36
-69
lines changed

lldb/include/lldb/Target/StopInfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ class StopInfo : public std::enable_shared_from_this<StopInfo> {
118118

119119
StructuredData::ObjectSP GetExtendedInfo() { return m_extended_info; }
120120

121+
/// Returns true if this is a stop reason that should be shown to a user when
122+
/// viewing the thread with this stop info.
123+
virtual bool ShouldShow() const { return IsValid(); }
124+
125+
/// Returns true if this is a stop reason that should cause a thread to be
126+
/// selected when stopping.
127+
virtual bool ShouldSelect() const {
128+
lldb::StopReason reason = GetStopReason();
129+
return reason != lldb::eStopReasonNone &&
130+
reason != lldb::eStopReasonHistoryBoundary &&
131+
reason != lldb::eStopReasonInvalid;
132+
}
133+
121134
static lldb::StopInfoSP
122135
CreateStopReasonWithBreakpointSiteID(Thread &thread,
123136
lldb::break_id_t break_id);

lldb/source/Target/Process.cpp

Lines changed: 14 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -808,85 +808,36 @@ bool Process::HandleProcessStateChangedEvent(
808808
std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
809809

810810
ThreadSP curr_thread(thread_list.GetSelectedThread());
811-
ThreadSP thread;
812-
StopReason curr_thread_stop_reason = eStopReasonInvalid;
813-
bool prefer_curr_thread = false;
814-
if (curr_thread && curr_thread->IsValid()) {
815-
curr_thread_stop_reason = curr_thread->GetStopReason();
816-
switch (curr_thread_stop_reason) {
817-
case eStopReasonNone:
818-
case eStopReasonInvalid:
819-
// Don't prefer the current thread if it didn't stop for a reason.
820-
break;
821-
case eStopReasonSignal: {
822-
// We need to do the same computation we do for other threads
823-
// below in case the current thread happens to be the one that
824-
// stopped for the no-stop signal.
825-
uint64_t signo = curr_thread->GetStopInfo()->GetValue();
826-
if (process_sp->GetUnixSignals()->GetShouldStop(signo))
827-
prefer_curr_thread = true;
828-
} break;
829-
default:
830-
prefer_curr_thread = true;
831-
break;
832-
}
811+
812+
if (curr_thread && curr_thread->IsValid())
833813
curr_thread_stop_info_sp = curr_thread->GetStopInfo();
834-
}
814+
bool prefer_curr_thread = curr_thread_stop_info_sp &&
815+
curr_thread_stop_info_sp->ShouldSelect();
835816

836817
if (!prefer_curr_thread) {
837818
// Prefer a thread that has just completed its plan over another
838819
// thread as current thread.
839820
ThreadSP plan_thread;
840821
ThreadSP other_thread;
841822

842-
const size_t num_threads = thread_list.GetSize();
843-
size_t i;
844-
for (i = 0; i < num_threads; ++i) {
845-
thread = thread_list.GetThreadAtIndex(i);
846-
StopReason thread_stop_reason = thread->GetStopReason();
847-
switch (thread_stop_reason) {
848-
case eStopReasonInvalid:
849-
case eStopReasonNone:
850-
case eStopReasonHistoryBoundary:
851-
break;
852-
853-
case eStopReasonSignal: {
854-
// Don't select a signal thread if we weren't going to stop at
855-
// that signal. We have to have had another reason for stopping
856-
// here, and the user doesn't want to see this thread.
857-
uint64_t signo = thread->GetStopInfo()->GetValue();
858-
if (process_sp->GetUnixSignals()->GetShouldStop(signo)) {
859-
if (!other_thread)
860-
other_thread = thread;
861-
}
862-
break;
863-
}
864-
case eStopReasonTrace:
865-
case eStopReasonBreakpoint:
866-
case eStopReasonWatchpoint:
867-
case eStopReasonException:
868-
case eStopReasonExec:
869-
case eStopReasonFork:
870-
case eStopReasonVFork:
871-
case eStopReasonVForkDone:
872-
case eStopReasonThreadExiting:
873-
case eStopReasonInstrumentation:
874-
case eStopReasonProcessorTrace:
875-
case eStopReasonInterrupt:
876-
if (!other_thread)
877-
other_thread = thread;
878-
break;
879-
case eStopReasonPlanComplete:
823+
for (ThreadSP thread : thread_list.Threads()) {
824+
StopInfoSP stop_info = thread->GetStopInfo();
825+
if (!stop_info || !stop_info->ShouldSelect())
826+
continue;
827+
StopReason thread_stop_reason = stop_info->GetStopReason();
828+
if (thread_stop_reason == eStopReasonPlanComplete) {
880829
if (!plan_thread)
881830
plan_thread = thread;
882-
break;
831+
} else if (!other_thread) {
832+
other_thread = thread;
883833
}
884834
}
885835
if (plan_thread)
886836
thread_list.SetSelectedThreadByID(plan_thread->GetID());
887837
else if (other_thread)
888838
thread_list.SetSelectedThreadByID(other_thread->GetID());
889839
else {
840+
ThreadSP thread;
890841
if (curr_thread && curr_thread->IsValid())
891842
thread = curr_thread;
892843
else
@@ -5832,7 +5783,7 @@ size_t Process::GetThreadStatus(Stream &strm,
58325783
if (thread_sp) {
58335784
if (only_threads_with_stop_reason) {
58345785
StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
5835-
if (!stop_info_sp || !stop_info_sp->IsValid())
5786+
if (!stop_info_sp || !stop_info_sp->ShouldShow())
58365787
continue;
58375788
}
58385789
thread_sp->GetStatus(strm, start_frame, num_frames,

lldb/source/Target/StopInfo.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,12 +1080,7 @@ class StopInfoUnixSignal : public StopInfo {
10801080
return false;
10811081
}
10821082

1083-
bool ShouldStop(Event *event_ptr) override {
1084-
ThreadSP thread_sp(m_thread_wp.lock());
1085-
if (thread_sp)
1086-
return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1087-
return false;
1088-
}
1083+
bool ShouldStop(Event *event_ptr) override { return IsShouldStopSignal(); }
10891084

10901085
// If should stop returns false, check if we should notify of this event
10911086
bool DoShouldNotify(Event *event_ptr) override {
@@ -1137,9 +1132,17 @@ class StopInfoUnixSignal : public StopInfo {
11371132
return m_description.c_str();
11381133
}
11391134

1135+
bool ShouldSelect() const override { return IsShouldStopSignal(); }
1136+
11401137
private:
11411138
// In siginfo_t terms, if m_value is si_signo, m_code is si_code.
11421139
std::optional<int> m_code;
1140+
1141+
bool IsShouldStopSignal() const {
1142+
if (ThreadSP thread_sp = m_thread_wp.lock())
1143+
return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1144+
return false;
1145+
}
11431146
};
11441147

11451148
// StopInfoInterrupt

0 commit comments

Comments
 (0)