150
|
1 //===-- ThreadPlanBase.cpp ------------------------------------------------===//
|
|
2 //
|
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
|
9 #include "lldb/Target/ThreadPlanBase.h"
|
|
10
|
|
11 //
|
|
12 #include "lldb/Breakpoint/Breakpoint.h"
|
|
13 #include "lldb/Breakpoint/BreakpointLocation.h"
|
|
14 #include "lldb/Breakpoint/BreakpointSite.h"
|
|
15 #include "lldb/Breakpoint/StoppointCallbackContext.h"
|
|
16 #include "lldb/Target/Process.h"
|
|
17 #include "lldb/Target/RegisterContext.h"
|
|
18 #include "lldb/Target/StopInfo.h"
|
|
19 #include "lldb/Utility/Log.h"
|
|
20 #include "lldb/Utility/Stream.h"
|
|
21
|
|
22 using namespace lldb;
|
|
23 using namespace lldb_private;
|
|
24
|
|
25 // ThreadPlanBase: This one always stops, and never has anything particular to
|
|
26 // do.
|
|
27 // FIXME: The "signal handling" policies should probably go here.
|
|
28
|
|
29 ThreadPlanBase::ThreadPlanBase(Thread &thread)
|
|
30 : ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes,
|
|
31 eVoteNoOpinion) {
|
|
32 // Set the tracer to a default tracer.
|
|
33 // FIXME: need to add a thread settings variable to pix various tracers...
|
|
34 #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1
|
|
35
|
|
36 #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
|
173
|
37 ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(thread));
|
150
|
38 #else
|
|
39 ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread));
|
|
40 #endif
|
173
|
41 new_tracer_sp->EnableTracing(thread.GetTraceEnabledState());
|
150
|
42 SetThreadPlanTracer(new_tracer_sp);
|
|
43 SetIsMasterPlan(true);
|
|
44 }
|
|
45
|
223
|
46 ThreadPlanBase::~ThreadPlanBase() = default;
|
150
|
47
|
|
48 void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
|
|
49 s->Printf("Base thread plan.");
|
|
50 }
|
|
51
|
|
52 bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }
|
|
53
|
|
54 bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
|
|
55 // The base plan should defer to its tracer, since by default it always
|
|
56 // handles the stop.
|
|
57 return !TracerExplainsStop();
|
|
58 }
|
|
59
|
|
60 Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) {
|
173
|
61 StopInfoSP stop_info_sp = GetThread().GetStopInfo();
|
150
|
62 if (stop_info_sp) {
|
|
63 bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
|
|
64 if (should_notify)
|
|
65 return eVoteYes;
|
|
66 else
|
|
67 return eVoteNoOpinion;
|
|
68 } else
|
|
69 return eVoteNoOpinion;
|
|
70 }
|
|
71
|
|
72 bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
|
221
|
73 m_report_stop_vote = eVoteYes;
|
|
74 m_report_run_vote = eVoteYes;
|
150
|
75
|
|
76 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
|
77
|
|
78 StopInfoSP stop_info_sp = GetPrivateStopInfo();
|
|
79 if (stop_info_sp) {
|
|
80 StopReason reason = stop_info_sp->GetStopReason();
|
|
81 switch (reason) {
|
|
82 case eStopReasonInvalid:
|
|
83 case eStopReasonNone:
|
|
84 // This
|
221
|
85 m_report_run_vote = eVoteNoOpinion;
|
|
86 m_report_stop_vote = eVoteNo;
|
150
|
87 return false;
|
|
88
|
|
89 case eStopReasonBreakpoint:
|
|
90 case eStopReasonWatchpoint:
|
|
91 if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
|
|
92 // If we are going to stop for a breakpoint, then unship the other
|
|
93 // plans at this point. Don't force the discard, however, so Master
|
|
94 // plans can stay in place if they want to.
|
|
95 LLDB_LOGF(
|
|
96 log,
|
|
97 "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
|
|
98 " (breakpoint hit.)",
|
173
|
99 m_tid);
|
|
100 GetThread().DiscardThreadPlans(false);
|
150
|
101 return true;
|
|
102 }
|
|
103 // If we aren't going to stop at this breakpoint, and it is internal,
|
|
104 // don't report this stop or the subsequent running event. Otherwise we
|
|
105 // will post the stopped & running, but the stopped event will get marked
|
|
106 // with "restarted" so the UI will know to wait and expect the consequent
|
|
107 // "running".
|
|
108 if (stop_info_sp->ShouldNotify(event_ptr)) {
|
221
|
109 m_report_stop_vote = eVoteYes;
|
|
110 m_report_run_vote = eVoteYes;
|
150
|
111 } else {
|
221
|
112 m_report_stop_vote = eVoteNo;
|
|
113 m_report_run_vote = eVoteNo;
|
150
|
114 }
|
|
115 return false;
|
|
116
|
|
117 // TODO: the break below was missing, was this intentional??? If so
|
|
118 // please mention it
|
|
119 break;
|
|
120
|
|
121 case eStopReasonException:
|
|
122 // If we crashed, discard thread plans and stop. Don't force the
|
|
123 // discard, however, since on rerun the target may clean up this
|
|
124 // exception and continue normally from there.
|
|
125 LLDB_LOGF(
|
|
126 log,
|
|
127 "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
|
173
|
128 " (exception: %s)",
|
|
129 m_tid, stop_info_sp->GetDescription());
|
|
130 GetThread().DiscardThreadPlans(false);
|
150
|
131 return true;
|
|
132
|
|
133 case eStopReasonExec:
|
|
134 // If we crashed, discard thread plans and stop. Don't force the
|
|
135 // discard, however, since on rerun the target may clean up this
|
|
136 // exception and continue normally from there.
|
|
137 LLDB_LOGF(
|
|
138 log,
|
|
139 "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
|
|
140 " (exec.)",
|
173
|
141 m_tid);
|
|
142 GetThread().DiscardThreadPlans(false);
|
150
|
143 return true;
|
|
144
|
|
145 case eStopReasonThreadExiting:
|
|
146 case eStopReasonSignal:
|
|
147 if (stop_info_sp->ShouldStop(event_ptr)) {
|
|
148 LLDB_LOGF(
|
|
149 log,
|
|
150 "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
|
173
|
151 " (signal: %s)",
|
|
152 m_tid, stop_info_sp->GetDescription());
|
|
153 GetThread().DiscardThreadPlans(false);
|
150
|
154 return true;
|
|
155 } else {
|
|
156 // We're not going to stop, but while we are here, let's figure out
|
|
157 // whether to report this.
|
|
158 if (stop_info_sp->ShouldNotify(event_ptr))
|
221
|
159 m_report_stop_vote = eVoteYes;
|
150
|
160 else
|
221
|
161 m_report_stop_vote = eVoteNo;
|
150
|
162 }
|
|
163 return false;
|
|
164
|
|
165 default:
|
|
166 return true;
|
|
167 }
|
|
168
|
|
169 } else {
|
221
|
170 m_report_run_vote = eVoteNoOpinion;
|
|
171 m_report_stop_vote = eVoteNo;
|
150
|
172 }
|
|
173
|
|
174 // If there's no explicit reason to stop, then we will continue.
|
|
175 return false;
|
|
176 }
|
|
177
|
|
178 bool ThreadPlanBase::StopOthers() { return false; }
|
|
179
|
|
180 StateType ThreadPlanBase::GetPlanRunState() { return eStateRunning; }
|
|
181
|
|
182 bool ThreadPlanBase::WillStop() { return true; }
|
|
183
|
|
184 bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
|
|
185 bool current_plan) {
|
|
186 // Reset these to the default values so we don't set them wrong, then not get
|
|
187 // asked for a while, then return the wrong answer.
|
221
|
188 m_report_run_vote = eVoteNoOpinion;
|
|
189 m_report_stop_vote = eVoteNo;
|
150
|
190 return true;
|
|
191 }
|
|
192
|
|
193 // The base plan is never done.
|
|
194 bool ThreadPlanBase::MischiefManaged() {
|
|
195 // The base plan is never done.
|
|
196 return false;
|
|
197 }
|