]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Target/ThreadPlan.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Target / ThreadPlan.cpp
1 //===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/ThreadPlan.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/State.h"
18 #include "lldb/Target/RegisterContext.h"
19 #include "lldb/Target/Thread.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/ConvertEnum.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 //----------------------------------------------------------------------
28 // ThreadPlan constructor
29 //----------------------------------------------------------------------
30 ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote)
31     : m_thread(thread),
32       m_stop_vote(stop_vote),
33       m_run_vote(run_vote),
34       m_kind(kind),
35       m_name(name),
36       m_plan_complete_mutex(),
37       m_cached_plan_explains_stop(eLazyBoolCalculate),
38       m_plan_complete(false),
39       m_plan_private(false),
40       m_okay_to_discard(true),
41       m_is_master_plan(false),
42       m_plan_succeeded(true)
43 {
44     SetID(GetNextID());
45 }
46
47 //----------------------------------------------------------------------
48 // Destructor
49 //----------------------------------------------------------------------
50 ThreadPlan::~ThreadPlan() = default;
51
52 bool
53 ThreadPlan::PlanExplainsStop (Event *event_ptr)
54 {
55     if (m_cached_plan_explains_stop == eLazyBoolCalculate)
56     {
57         bool actual_value = DoPlanExplainsStop(event_ptr);
58         m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo;
59         return actual_value;
60     }
61     else
62     {
63         return m_cached_plan_explains_stop == eLazyBoolYes;
64     }
65 }
66
67 bool
68 ThreadPlan::IsPlanComplete ()
69 {
70     std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
71     return m_plan_complete;
72 }
73
74 void
75 ThreadPlan::SetPlanComplete (bool success)
76 {
77     std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
78     m_plan_complete = true;
79     m_plan_succeeded = success;
80 }
81
82 bool
83 ThreadPlan::MischiefManaged ()
84 {
85     std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
86     // Mark the plan is complete, but don't override the success flag.
87     m_plan_complete = true;
88     return true;
89 }
90
91 Vote
92 ThreadPlan::ShouldReportStop (Event *event_ptr)
93 {
94     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
95
96     if (m_stop_vote == eVoteNoOpinion)
97     {
98         ThreadPlan *prev_plan = GetPreviousPlan ();
99         if (prev_plan)
100         {
101             Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
102             if (log)
103                 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 
104                              GetVoteAsCString (prev_vote));
105             return prev_vote;
106         }
107     }
108     if (log)
109         log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote));
110     return m_stop_vote;
111 }
112
113 Vote
114 ThreadPlan::ShouldReportRun (Event *event_ptr)
115 {
116     if (m_run_vote == eVoteNoOpinion)
117     {
118         ThreadPlan *prev_plan = GetPreviousPlan ();
119         if (prev_plan)
120             return prev_plan->ShouldReportRun (event_ptr);
121     }
122     return m_run_vote;
123 }
124
125 bool
126 ThreadPlan::StopOthers ()
127 {
128     ThreadPlan *prev_plan;
129     prev_plan = GetPreviousPlan ();
130     return (prev_plan == nullptr) ? false : prev_plan->StopOthers();
131 }
132
133 void
134 ThreadPlan::SetStopOthers (bool new_value)
135 {
136         // SetStopOthers doesn't work up the hierarchy.  You have to set the 
137     // explicit ThreadPlan you want to affect.
138 }
139
140 bool
141 ThreadPlan::WillResume (StateType resume_state, bool current_plan)
142 {
143     m_cached_plan_explains_stop = eLazyBoolCalculate;
144     
145     if (current_plan)
146     {
147         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
148
149         if (log)
150         {
151             RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
152             assert (reg_ctx);
153             addr_t pc = reg_ctx->GetPC();
154             addr_t sp = reg_ctx->GetSP();
155             addr_t fp = reg_ctx->GetFP();
156             log->Printf("%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
157                         "plan = '%s', state = %s, stop others = %d", 
158                         __FUNCTION__, m_thread.GetIndexID(),
159                         static_cast<void*>(&m_thread), m_thread.GetID(),
160                         static_cast<uint64_t>(pc), static_cast<uint64_t>(sp),
161                         static_cast<uint64_t>(fp), m_name.c_str(),
162                         StateAsCString(resume_state), StopOthers());
163         }
164     }
165     return DoWillResume (resume_state, current_plan);
166 }
167
168 lldb::user_id_t
169 ThreadPlan::GetNextID()
170 {
171     static uint32_t g_nextPlanID = 0;
172     return ++g_nextPlanID;
173 }
174
175 void
176 ThreadPlan::DidPush()
177 {
178 }
179
180 void
181 ThreadPlan::WillPop()
182 {
183 }
184
185 bool
186 ThreadPlan::OkayToDiscard()
187 {
188     return IsMasterPlan() ? m_okay_to_discard : true;
189 }
190
191 lldb::StateType
192 ThreadPlan::RunState ()
193 {
194     if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled())
195         return eStateStepping;
196     else
197         return GetPlanRunState();
198 }
199
200 bool
201 ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason)
202 {
203     switch (reason)
204     {
205         case eStopReasonWatchpoint:
206         case eStopReasonSignal:
207         case eStopReasonException:
208         case eStopReasonExec:
209         case eStopReasonThreadExiting:
210         case eStopReasonInstrumentation:
211             return true;
212         default:
213             return false;
214     }
215 }
216
217 //----------------------------------------------------------------------
218 // ThreadPlanNull
219 //----------------------------------------------------------------------
220
221 ThreadPlanNull::ThreadPlanNull (Thread &thread) :
222     ThreadPlan (ThreadPlan::eKindNull,
223                 "Null Thread Plan",
224                 thread,
225                 eVoteNoOpinion,
226                 eVoteNoOpinion)
227 {
228 }
229
230 ThreadPlanNull::~ThreadPlanNull() = default;
231
232 void
233 ThreadPlanNull::GetDescription (Stream *s,
234                                 lldb::DescriptionLevel level)
235 {
236     s->PutCString("Null thread plan - thread has been destroyed.");
237 }
238
239 bool
240 ThreadPlanNull::ValidatePlan (Stream *error)
241 {
242 #ifdef LLDB_CONFIGURATION_DEBUG
243     fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
244             __PRETTY_FUNCTION__,
245             m_thread.GetID(),
246             m_thread.GetProtocolID());
247 #else
248     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
249     if (log)
250         log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
251                     __PRETTY_FUNCTION__,
252                     m_thread.GetID(),
253                     m_thread.GetProtocolID());
254 #endif
255     return true;
256 }
257
258 bool
259 ThreadPlanNull::ShouldStop (Event *event_ptr)
260 {
261 #ifdef LLDB_CONFIGURATION_DEBUG
262     fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
263             __PRETTY_FUNCTION__,
264             m_thread.GetID(),
265             m_thread.GetProtocolID());
266 #else
267     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
268     if (log)
269         log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
270                     __PRETTY_FUNCTION__,
271                     m_thread.GetID(),
272                     m_thread.GetProtocolID());
273 #endif
274     return true;
275 }
276
277 bool
278 ThreadPlanNull::WillStop ()
279 {
280 #ifdef LLDB_CONFIGURATION_DEBUG
281     fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
282             __PRETTY_FUNCTION__,
283             m_thread.GetID(),
284             m_thread.GetProtocolID());
285 #else
286     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
287     if (log)
288         log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
289                     __PRETTY_FUNCTION__,
290                     m_thread.GetID(),
291                     m_thread.GetProtocolID());
292 #endif
293     return true;
294 }
295
296 bool
297 ThreadPlanNull::DoPlanExplainsStop (Event *event_ptr)
298 {
299 #ifdef LLDB_CONFIGURATION_DEBUG
300     fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
301             __PRETTY_FUNCTION__,
302             m_thread.GetID(),
303             m_thread.GetProtocolID());
304 #else
305     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
306     if (log)
307         log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
308                    __PRETTY_FUNCTION__,
309                    m_thread.GetID(),
310                    m_thread.GetProtocolID());
311 #endif
312     return true;
313 }
314
315 // The null plan is never done.
316 bool
317 ThreadPlanNull::MischiefManaged ()
318 {
319     // The null plan is never done.
320 #ifdef LLDB_CONFIGURATION_DEBUG
321     fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
322             __PRETTY_FUNCTION__,
323             m_thread.GetID(),
324             m_thread.GetProtocolID());
325 #else
326     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
327     if (log)
328         log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
329                    __PRETTY_FUNCTION__,
330                    m_thread.GetID(),
331                    m_thread.GetProtocolID());
332 #endif
333     return false;
334 }
335
336 lldb::StateType
337 ThreadPlanNull::GetPlanRunState ()
338 {
339     // Not sure what to return here.  This is a dead thread.
340 #ifdef LLDB_CONFIGURATION_DEBUG
341     fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
342             __PRETTY_FUNCTION__,
343             m_thread.GetID(),
344             m_thread.GetProtocolID());
345 #else
346     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
347     if (log)
348         log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
349                    __PRETTY_FUNCTION__,
350                    m_thread.GetID(),
351                    m_thread.GetProtocolID());
352 #endif
353     return eStateRunning;
354 }