blob: f86d10dca3484988ab010b0f17ecf16f18869531 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000014#include "lldb/Target/ThreadPlan.h"
Jim Ingham06e827c2010-11-11 19:26:09 +000015#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Log.h"
17#include "lldb/Core/State.h"
Greg Clayton2cad65a2010-09-03 17:10:42 +000018#include "lldb/Target/RegisterContext.h"
19#include "lldb/Target/Thread.h"
Jim Ingham06e827c2010-11-11 19:26:09 +000020#include "lldb/Target/Process.h"
21#include "lldb/Target/Target.h"
Zachary Turner50232572015-03-18 21:31:45 +000022#include "lldb/Utility/ConvertEnum.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// ThreadPlan constructor
29//----------------------------------------------------------------------
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000030ThreadPlan::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)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000044 SetID(GetNextID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045}
46
47//----------------------------------------------------------------------
48// Destructor
49//----------------------------------------------------------------------
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000050ThreadPlan::~ThreadPlan() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052bool
Jim Ingham221d51c2013-05-08 00:35:16 +000053ThreadPlan::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
67bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068ThreadPlan::IsPlanComplete ()
69{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000070 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071 return m_plan_complete;
72}
73
74void
Jim Inghamfbbfe6e2012-05-01 18:38:37 +000075ThreadPlan::SetPlanComplete (bool success)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000077 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078 m_plan_complete = true;
Jim Inghamfbbfe6e2012-05-01 18:38:37 +000079 m_plan_succeeded = success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080}
81
82bool
83ThreadPlan::MischiefManaged ()
84{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000085 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
Jim Ingham18de2fd2012-05-10 01:35:39 +000086 // Mark the plan is complete, but don't override the success flag.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 m_plan_complete = true;
88 return true;
89}
90
91Vote
92ThreadPlan::ShouldReportStop (Event *event_ptr)
93{
Greg Clayton5160ce52013-03-27 23:08:40 +000094 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Greg Clayton2cad65a2010-09-03 17:10:42 +000095
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096 if (m_stop_vote == eVoteNoOpinion)
97 {
98 ThreadPlan *prev_plan = GetPreviousPlan ();
99 if (prev_plan)
Greg Clayton2cad65a2010-09-03 17:10:42 +0000100 {
101 Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
102 if (log)
Jim Inghamb5c0d1c2012-03-01 00:50:50 +0000103 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s",
104 GetVoteAsCString (prev_vote));
Greg Clayton2cad65a2010-09-03 17:10:42 +0000105 return prev_vote;
106 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107 }
Greg Clayton2cad65a2010-09-03 17:10:42 +0000108 if (log)
Greg Clayton1346f7e2010-09-03 22:45:01 +0000109 log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 return m_stop_vote;
111}
112
113Vote
114ThreadPlan::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
125bool
126ThreadPlan::StopOthers ()
127{
128 ThreadPlan *prev_plan;
129 prev_plan = GetPreviousPlan ();
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000130 return (prev_plan == nullptr) ? false : prev_plan->StopOthers();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131}
132
Jim Inghamf48169b2010-11-30 02:22:11 +0000133void
134ThreadPlan::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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140bool
141ThreadPlan::WillResume (StateType resume_state, bool current_plan)
142{
Jim Ingham221d51c2013-05-08 00:35:16 +0000143 m_cached_plan_explains_stop = eLazyBoolCalculate;
144
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 if (current_plan)
146 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000147 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148
149 if (log)
Greg Clayton2cad65a2010-09-03 17:10:42 +0000150 {
Greg Clayton5ccbd292011-01-06 22:15:06 +0000151 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
Ed Masteff1b5c42015-02-23 18:12:20 +0000152 assert (reg_ctx);
Greg Clayton2cad65a2010-09-03 17:10:42 +0000153 addr_t pc = reg_ctx->GetPC();
154 addr_t sp = reg_ctx->GetSP();
155 addr_t fp = reg_ctx->GetFP();
Jim Inghamdee1bc92013-06-22 00:27:45 +0000156 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 ", "
Jim Inghamb5c0d1c2012-03-01 00:50:50 +0000157 "plan = '%s', state = %s, stop others = %d",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000158 __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());
Greg Clayton2cad65a2010-09-03 17:10:42 +0000163 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164 }
Jim Ingham221d51c2013-05-08 00:35:16 +0000165 return DoWillResume (resume_state, current_plan);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166}
167
168lldb::user_id_t
169ThreadPlan::GetNextID()
170{
171 static uint32_t g_nextPlanID = 0;
172 return ++g_nextPlanID;
173}
174
175void
176ThreadPlan::DidPush()
177{
178}
179
180void
181ThreadPlan::WillPop()
182{
183}
184
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185bool
186ThreadPlan::OkayToDiscard()
187{
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000188 return IsMasterPlan() ? m_okay_to_discard : true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189}
190
Jim Ingham06e827c2010-11-11 19:26:09 +0000191lldb::StateType
192ThreadPlan::RunState ()
193{
194 if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled())
195 return eStateStepping;
196 else
197 return GetPlanRunState();
198}
Greg Clayton6e10f142013-07-30 00:23:06 +0000199
Jim Ingham9b03fa02015-07-23 19:55:02 +0000200bool
201ThreadPlan::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
Greg Clayton6e10f142013-07-30 00:23:06 +0000217//----------------------------------------------------------------------
218// ThreadPlanNull
219//----------------------------------------------------------------------
220
221ThreadPlanNull::ThreadPlanNull (Thread &thread) :
222 ThreadPlan (ThreadPlan::eKindNull,
223 "Null Thread Plan",
224 thread,
225 eVoteNoOpinion,
226 eVoteNoOpinion)
227{
228}
229
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000230ThreadPlanNull::~ThreadPlanNull() = default;
Greg Clayton6e10f142013-07-30 00:23:06 +0000231
232void
233ThreadPlanNull::GetDescription (Stream *s,
234 lldb::DescriptionLevel level)
235{
236 s->PutCString("Null thread plan - thread has been destroyed.");
237}
238
239bool
240ThreadPlanNull::ValidatePlan (Stream *error)
241{
242#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000243 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000244 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000245 m_thread.GetID(),
246 m_thread.GetProtocolID());
247#else
248 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
249 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000250 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000251 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000252 m_thread.GetID(),
253 m_thread.GetProtocolID());
254#endif
255 return true;
256}
257
258bool
259ThreadPlanNull::ShouldStop (Event *event_ptr)
260{
261#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000262 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000263 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000264 m_thread.GetID(),
265 m_thread.GetProtocolID());
266#else
267 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
268 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000269 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000270 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000271 m_thread.GetID(),
272 m_thread.GetProtocolID());
273#endif
274 return true;
275}
276
277bool
278ThreadPlanNull::WillStop ()
279{
280#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000281 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000282 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000283 m_thread.GetID(),
284 m_thread.GetProtocolID());
285#else
286 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
287 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000288 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000289 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000290 m_thread.GetID(),
291 m_thread.GetProtocolID());
292#endif
293 return true;
294}
295
296bool
297ThreadPlanNull::DoPlanExplainsStop (Event *event_ptr)
298{
299#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000300 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000301 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000302 m_thread.GetID(),
303 m_thread.GetProtocolID());
304#else
305 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
306 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000307 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000308 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000309 m_thread.GetID(),
310 m_thread.GetProtocolID());
311#endif
312 return true;
313}
314
315// The null plan is never done.
316bool
317ThreadPlanNull::MischiefManaged ()
318{
319 // The null plan is never done.
320#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000321 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000322 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000323 m_thread.GetID(),
324 m_thread.GetProtocolID());
325#else
326 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
327 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000328 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000329 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000330 m_thread.GetID(),
331 m_thread.GetProtocolID());
332#endif
333 return false;
334}
335
336lldb::StateType
337ThreadPlanNull::GetPlanRunState ()
338{
339 // Not sure what to return here. This is a dead thread.
340#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000341 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000342 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000343 m_thread.GetID(),
344 m_thread.GetProtocolID());
345#else
346 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
347 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000348 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Zachary Turnerf343968f2016-08-09 23:06:08 +0000349 LLVM_PRETTY_FUNCTION,
Greg Clayton6e10f142013-07-30 00:23:06 +0000350 m_thread.GetID(),
351 m_thread.GetProtocolID());
352#endif
353 return eStateRunning;
354}