blob: 80852b7f7908e239ac7a26624c5e91f7d8cdf542 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Target/ThreadPlan.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham06e827c2010-11-11 19:26:09 +000018#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Log.h"
20#include "lldb/Core/State.h"
Greg Clayton2cad65a2010-09-03 17:10:42 +000021#include "lldb/Target/RegisterContext.h"
22#include "lldb/Target/Thread.h"
Jim Ingham06e827c2010-11-11 19:26:09 +000023#include "lldb/Target/Process.h"
24#include "lldb/Target/Target.h"
Zachary Turner50232572015-03-18 21:31:45 +000025#include "lldb/Utility/ConvertEnum.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
27using namespace lldb;
28using namespace lldb_private;
29
30//----------------------------------------------------------------------
31// ThreadPlan constructor
32//----------------------------------------------------------------------
Jim Inghamb01e7422010-06-19 04:45:32 +000033ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034 m_thread (thread),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035 m_stop_vote (stop_vote),
36 m_run_vote (run_vote),
Benjamin Kramer1ee0d4f2010-07-16 12:32:33 +000037 m_kind (kind),
38 m_name (name),
39 m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham221d51c2013-05-08 00:35:16 +000040 m_cached_plan_explains_stop (eLazyBoolCalculate),
Benjamin Kramer1ee0d4f2010-07-16 12:32:33 +000041 m_plan_complete (false),
42 m_plan_private (false),
Jim Ingham64e7ead2012-05-03 21:19:36 +000043 m_okay_to_discard (true),
Jim Inghamfbbfe6e2012-05-01 18:38:37 +000044 m_is_master_plan (false),
45 m_plan_succeeded(true)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046{
47 SetID (GetNextID());
48}
49
50//----------------------------------------------------------------------
51// Destructor
52//----------------------------------------------------------------------
53ThreadPlan::~ThreadPlan()
54{
55}
56
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057bool
Jim Ingham221d51c2013-05-08 00:35:16 +000058ThreadPlan::PlanExplainsStop (Event *event_ptr)
59{
60 if (m_cached_plan_explains_stop == eLazyBoolCalculate)
61 {
62 bool actual_value = DoPlanExplainsStop(event_ptr);
63 m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo;
64 return actual_value;
65 }
66 else
67 {
68 return m_cached_plan_explains_stop == eLazyBoolYes;
69 }
70}
71
72bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073ThreadPlan::IsPlanComplete ()
74{
Greg Claytonb1320972010-07-14 00:18:15 +000075 Mutex::Locker locker(m_plan_complete_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076 return m_plan_complete;
77}
78
79void
Jim Inghamfbbfe6e2012-05-01 18:38:37 +000080ThreadPlan::SetPlanComplete (bool success)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081{
Greg Claytonb1320972010-07-14 00:18:15 +000082 Mutex::Locker locker(m_plan_complete_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083 m_plan_complete = true;
Jim Inghamfbbfe6e2012-05-01 18:38:37 +000084 m_plan_succeeded = success;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085}
86
87bool
88ThreadPlan::MischiefManaged ()
89{
Greg Claytonb1320972010-07-14 00:18:15 +000090 Mutex::Locker locker(m_plan_complete_mutex);
Jim Ingham18de2fd2012-05-10 01:35:39 +000091 // Mark the plan is complete, but don't override the success flag.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092 m_plan_complete = true;
93 return true;
94}
95
96Vote
97ThreadPlan::ShouldReportStop (Event *event_ptr)
98{
Greg Clayton5160ce52013-03-27 23:08:40 +000099 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Greg Clayton2cad65a2010-09-03 17:10:42 +0000100
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 if (m_stop_vote == eVoteNoOpinion)
102 {
103 ThreadPlan *prev_plan = GetPreviousPlan ();
104 if (prev_plan)
Greg Clayton2cad65a2010-09-03 17:10:42 +0000105 {
106 Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
107 if (log)
Jim Inghamb5c0d1c2012-03-01 00:50:50 +0000108 log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s",
109 GetVoteAsCString (prev_vote));
Greg Clayton2cad65a2010-09-03 17:10:42 +0000110 return prev_vote;
111 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 }
Greg Clayton2cad65a2010-09-03 17:10:42 +0000113 if (log)
Greg Clayton1346f7e2010-09-03 22:45:01 +0000114 log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115 return m_stop_vote;
116}
117
118Vote
119ThreadPlan::ShouldReportRun (Event *event_ptr)
120{
121 if (m_run_vote == eVoteNoOpinion)
122 {
123 ThreadPlan *prev_plan = GetPreviousPlan ();
124 if (prev_plan)
125 return prev_plan->ShouldReportRun (event_ptr);
126 }
127 return m_run_vote;
128}
129
130bool
131ThreadPlan::StopOthers ()
132{
133 ThreadPlan *prev_plan;
134 prev_plan = GetPreviousPlan ();
135 if (prev_plan == NULL)
136 return false;
137 else
138 return prev_plan->StopOthers();
139}
140
Jim Inghamf48169b2010-11-30 02:22:11 +0000141void
142ThreadPlan::SetStopOthers (bool new_value)
143{
144 // SetStopOthers doesn't work up the hierarchy. You have to set the
145 // explicit ThreadPlan you want to affect.
146}
147
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148bool
149ThreadPlan::WillResume (StateType resume_state, bool current_plan)
150{
Jim Ingham221d51c2013-05-08 00:35:16 +0000151 m_cached_plan_explains_stop = eLazyBoolCalculate;
152
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 if (current_plan)
154 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000155 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156
157 if (log)
Greg Clayton2cad65a2010-09-03 17:10:42 +0000158 {
Greg Clayton5ccbd292011-01-06 22:15:06 +0000159 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
Ed Masteff1b5c42015-02-23 18:12:20 +0000160 assert (reg_ctx);
Greg Clayton2cad65a2010-09-03 17:10:42 +0000161 addr_t pc = reg_ctx->GetPC();
162 addr_t sp = reg_ctx->GetSP();
163 addr_t fp = reg_ctx->GetFP();
Jim Inghamdee1bc92013-06-22 00:27:45 +0000164 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 +0000165 "plan = '%s', state = %s, stop others = %d",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000166 __FUNCTION__, m_thread.GetIndexID(),
167 static_cast<void*>(&m_thread), m_thread.GetID(),
168 static_cast<uint64_t>(pc), static_cast<uint64_t>(sp),
169 static_cast<uint64_t>(fp), m_name.c_str(),
170 StateAsCString(resume_state), StopOthers());
Greg Clayton2cad65a2010-09-03 17:10:42 +0000171 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172 }
Jim Ingham221d51c2013-05-08 00:35:16 +0000173 return DoWillResume (resume_state, current_plan);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174}
175
176lldb::user_id_t
177ThreadPlan::GetNextID()
178{
179 static uint32_t g_nextPlanID = 0;
180 return ++g_nextPlanID;
181}
182
183void
184ThreadPlan::DidPush()
185{
186}
187
188void
189ThreadPlan::WillPop()
190{
191}
192
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193bool
194ThreadPlan::OkayToDiscard()
195{
196 if (!IsMasterPlan())
197 return true;
198 else
199 return m_okay_to_discard;
200}
201
Jim Ingham06e827c2010-11-11 19:26:09 +0000202lldb::StateType
203ThreadPlan::RunState ()
204{
205 if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled())
206 return eStateStepping;
207 else
208 return GetPlanRunState();
209}
Greg Clayton6e10f142013-07-30 00:23:06 +0000210
211//----------------------------------------------------------------------
212// ThreadPlanNull
213//----------------------------------------------------------------------
214
215ThreadPlanNull::ThreadPlanNull (Thread &thread) :
216 ThreadPlan (ThreadPlan::eKindNull,
217 "Null Thread Plan",
218 thread,
219 eVoteNoOpinion,
220 eVoteNoOpinion)
221{
222}
223
224ThreadPlanNull::~ThreadPlanNull ()
225{
226}
227
228void
229ThreadPlanNull::GetDescription (Stream *s,
230 lldb::DescriptionLevel level)
231{
232 s->PutCString("Null thread plan - thread has been destroyed.");
233}
234
235bool
236ThreadPlanNull::ValidatePlan (Stream *error)
237{
238#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000239 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000240 __PRETTY_FUNCTION__,
241 m_thread.GetID(),
242 m_thread.GetProtocolID());
243#else
244 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
245 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000246 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000247 __PRETTY_FUNCTION__,
248 m_thread.GetID(),
249 m_thread.GetProtocolID());
250#endif
251 return true;
252}
253
254bool
255ThreadPlanNull::ShouldStop (Event *event_ptr)
256{
257#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000258 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000259 __PRETTY_FUNCTION__,
260 m_thread.GetID(),
261 m_thread.GetProtocolID());
262#else
263 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
264 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000265 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000266 __PRETTY_FUNCTION__,
267 m_thread.GetID(),
268 m_thread.GetProtocolID());
269#endif
270 return true;
271}
272
273bool
274ThreadPlanNull::WillStop ()
275{
276#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000277 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000278 __PRETTY_FUNCTION__,
279 m_thread.GetID(),
280 m_thread.GetProtocolID());
281#else
282 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
283 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000284 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000285 __PRETTY_FUNCTION__,
286 m_thread.GetID(),
287 m_thread.GetProtocolID());
288#endif
289 return true;
290}
291
292bool
293ThreadPlanNull::DoPlanExplainsStop (Event *event_ptr)
294{
295#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000296 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000297 __PRETTY_FUNCTION__,
298 m_thread.GetID(),
299 m_thread.GetProtocolID());
300#else
301 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
302 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000303 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000304 __PRETTY_FUNCTION__,
305 m_thread.GetID(),
306 m_thread.GetProtocolID());
307#endif
308 return true;
309}
310
311// The null plan is never done.
312bool
313ThreadPlanNull::MischiefManaged ()
314{
315 // The null plan is never done.
316#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000317 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000318 __PRETTY_FUNCTION__,
319 m_thread.GetID(),
320 m_thread.GetProtocolID());
321#else
322 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
323 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000324 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000325 __PRETTY_FUNCTION__,
326 m_thread.GetID(),
327 m_thread.GetProtocolID());
328#endif
329 return false;
330}
331
332lldb::StateType
333ThreadPlanNull::GetPlanRunState ()
334{
335 // Not sure what to return here. This is a dead thread.
336#ifdef LLDB_CONFIGURATION_DEBUG
Michael Sartain89c862f2013-08-07 19:05:15 +0000337 fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000338 __PRETTY_FUNCTION__,
339 m_thread.GetID(),
340 m_thread.GetProtocolID());
341#else
342 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
343 if (log)
Michael Sartain89c862f2013-08-07 19:05:15 +0000344 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
Greg Clayton6e10f142013-07-30 00:23:06 +0000345 __PRETTY_FUNCTION__,
346 m_thread.GetID(),
347 m_thread.GetProtocolID());
348#endif
349 return eStateRunning;
350}