blob: 1c13b3df6313000dc864699e60ed560b0462cad9 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- Thread.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#include "lldb/lldb-private-log.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000011#include "lldb/Breakpoint/BreakpointLocation.h"
Greg Claytona830adb2010-10-04 01:05:56 +000012#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000013#include "lldb/Core/Log.h"
14#include "lldb/Core/Stream.h"
15#include "lldb/Core/StreamString.h"
Jim Ingham20594b12010-09-08 03:14:33 +000016#include "lldb/Core/RegularExpression.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000017#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Target/DynamicLoader.h"
19#include "lldb/Target/ExecutionContext.h"
Jim Inghamb66cd072010-09-28 01:25:32 +000020#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Target/Process.h"
22#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000023#include "lldb/Target/StopInfo.h"
Greg Clayton7661a982010-07-23 16:45:51 +000024#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Target/Thread.h"
26#include "lldb/Target/ThreadPlan.h"
27#include "lldb/Target/ThreadPlanCallFunction.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Target/ThreadPlanBase.h"
29#include "lldb/Target/ThreadPlanStepInstruction.h"
30#include "lldb/Target/ThreadPlanStepOut.h"
31#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
32#include "lldb/Target/ThreadPlanStepThrough.h"
33#include "lldb/Target/ThreadPlanStepInRange.h"
34#include "lldb/Target/ThreadPlanStepOverRange.h"
35#include "lldb/Target/ThreadPlanRunToAddress.h"
36#include "lldb/Target/ThreadPlanStepUntil.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000037#include "lldb/Target/ThreadSpec.h"
Jim Ingham71219082010-08-12 02:14:28 +000038#include "lldb/Target/Unwind.h"
Greg Clayton37f962e2011-08-22 02:49:39 +000039#include "Plugins/Process/Utility/UnwindLLDB.h"
40#include "UnwindMacOSXFrameBackchain.h"
41
Chris Lattner24943d22010-06-08 16:52:24 +000042
43using namespace lldb;
44using namespace lldb_private;
45
46Thread::Thread (Process &process, lldb::tid_t tid) :
47 UserID (tid),
Greg Clayton334d33a2012-01-30 07:41:31 +000048 ThreadInstanceSettings (GetSettingsController()),
Benjamin Kramer36a08102010-07-16 12:32:33 +000049 m_process (process),
Greg Clayton643ee732010-08-04 01:40:35 +000050 m_actual_stop_info_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_index_id (process.GetNextThreadIndexID ()),
52 m_reg_context_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000053 m_state (eStateUnloaded),
Greg Clayton782b9cc2010-08-25 00:35:26 +000054 m_state_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +000055 m_plan_stack (),
Chris Lattner24943d22010-06-08 16:52:24 +000056 m_completed_plan_stack(),
Greg Claytonc51ffbf2011-08-12 21:40:01 +000057 m_curr_frames_sp (),
58 m_prev_frames_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000059 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
Jim Ingham71219082010-08-12 02:14:28 +000060 m_resume_state (eStateRunning),
Jim Ingham149d1f52012-01-31 23:09:20 +000061 m_temporary_resume_state (eStateRunning),
Jim Inghamcdea2362010-11-18 02:47:07 +000062 m_unwinder_ap (),
Jim Ingham15dcb7c2011-01-20 02:03:18 +000063 m_destroy_called (false),
64 m_thread_stop_reason_stop_id (0)
Jim Ingham71219082010-08-12 02:14:28 +000065
Chris Lattner24943d22010-06-08 16:52:24 +000066{
Greg Claytone005f2c2010-11-06 01:53:30 +000067 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Chris Lattner24943d22010-06-08 16:52:24 +000068 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +000069 log->Printf ("%p Thread::Thread(tid = 0x%4.4llx)", this, GetID());
Chris Lattner24943d22010-06-08 16:52:24 +000070
71 QueueFundamentalPlan(true);
Caroline Tice1ebef442010-09-27 00:30:10 +000072 UpdateInstanceName();
Chris Lattner24943d22010-06-08 16:52:24 +000073}
74
75
76Thread::~Thread()
77{
Greg Claytone005f2c2010-11-06 01:53:30 +000078 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Chris Lattner24943d22010-06-08 16:52:24 +000079 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +000080 log->Printf ("%p Thread::~Thread(tid = 0x%4.4llx)", this, GetID());
Jim Inghamcdea2362010-11-18 02:47:07 +000081 /// If you hit this assert, it means your derived class forgot to call DoDestroy in its destructor.
82 assert (m_destroy_called);
83}
84
85void
86Thread::DestroyThread ()
87{
88 m_plan_stack.clear();
89 m_discarded_plan_stack.clear();
90 m_completed_plan_stack.clear();
91 m_destroy_called = true;
Chris Lattner24943d22010-06-08 16:52:24 +000092}
93
Jim Ingham6297a3a2010-10-20 00:39:53 +000094lldb::StopInfoSP
Greg Clayton643ee732010-08-04 01:40:35 +000095Thread::GetStopInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +000096{
Jim Ingham6297a3a2010-10-20 00:39:53 +000097 ThreadPlanSP plan_sp (GetCompletedPlan());
98 if (plan_sp)
Jim Ingham1586d972011-12-17 01:35:57 +000099 return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject());
Jim Ingham6297a3a2010-10-20 00:39:53 +0000100 else
Jim Ingham24e0d612011-08-09 00:32:52 +0000101 {
102 if (m_actual_stop_info_sp
103 && m_actual_stop_info_sp->IsValid()
104 && m_thread_stop_reason_stop_id == m_process.GetStopID())
105 return m_actual_stop_info_sp;
106 else
107 return GetPrivateStopReason ();
108 }
Chris Lattner24943d22010-06-08 16:52:24 +0000109}
110
Jim Ingham15dcb7c2011-01-20 02:03:18 +0000111void
112Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp)
113{
114 m_actual_stop_info_sp = stop_info_sp;
Jim Ingham24e0d612011-08-09 00:32:52 +0000115 if (m_actual_stop_info_sp)
116 m_actual_stop_info_sp->MakeStopInfoValid();
Jim Ingham15dcb7c2011-01-20 02:03:18 +0000117 m_thread_stop_reason_stop_id = GetProcess().GetStopID();
118}
119
120void
121Thread::SetStopInfoToNothing()
122{
123 // Note, we can't just NULL out the private reason, or the native thread implementation will try to
124 // go calculate it again. For now, just set it to a Unix Signal with an invalid signal number.
125 SetStopInfo (StopInfo::CreateStopReasonWithSignal (*this, LLDB_INVALID_SIGNAL_NUMBER));
126}
127
Chris Lattner24943d22010-06-08 16:52:24 +0000128bool
129Thread::ThreadStoppedForAReason (void)
130{
Greg Clayton643ee732010-08-04 01:40:35 +0000131 return GetPrivateStopReason () != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000132}
133
Jim Ingham15dcb7c2011-01-20 02:03:18 +0000134bool
135Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
136{
137 if (!SaveFrameZeroState(saved_state.register_backup))
138 return false;
139
140 saved_state.stop_info_sp = GetStopInfo();
141 saved_state.orig_stop_id = GetProcess().GetStopID();
142
143 return true;
144}
145
146bool
147Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
148{
149 RestoreSaveFrameZero(saved_state.register_backup);
Jim Ingham11a837d2011-01-25 02:47:23 +0000150 if (saved_state.stop_info_sp)
151 saved_state.stop_info_sp->MakeStopInfoValid();
Jim Ingham15dcb7c2011-01-20 02:03:18 +0000152 SetStopInfo(saved_state.stop_info_sp);
153 return true;
154}
155
Chris Lattner24943d22010-06-08 16:52:24 +0000156StateType
157Thread::GetState() const
158{
159 // If any other threads access this we will need a mutex for it
160 Mutex::Locker locker(m_state_mutex);
161 return m_state;
162}
163
164void
165Thread::SetState(StateType state)
166{
167 Mutex::Locker locker(m_state_mutex);
168 m_state = state;
169}
170
171void
172Thread::WillStop()
173{
174 ThreadPlan *current_plan = GetCurrentPlan();
175
176 // FIXME: I may decide to disallow threads with no plans. In which
177 // case this should go to an assert.
178
179 if (!current_plan)
180 return;
181
182 current_plan->WillStop();
183}
184
185void
186Thread::SetupForResume ()
187{
188 if (GetResumeState() != eStateSuspended)
189 {
190
191 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
192 // telling the current plan it will resume, since we might change what the current
193 // plan is.
194
195 lldb::addr_t pc = GetRegisterContext()->GetPC();
196 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
197 if (bp_site_sp && bp_site_sp->IsEnabled())
198 {
199 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
200 // special to step over a breakpoint.
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000201
202 ThreadPlan *cur_plan = GetCurrentPlan();
Chris Lattner24943d22010-06-08 16:52:24 +0000203
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000204 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
205 {
206 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
207 if (step_bp_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000208 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000209 ThreadPlanSP step_bp_plan_sp;
210 step_bp_plan->SetPrivate (true);
211
Chris Lattner24943d22010-06-08 16:52:24 +0000212 if (GetCurrentPlan()->RunState() != eStateStepping)
213 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000214 step_bp_plan->SetAutoContinue(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000215 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000216 step_bp_plan_sp.reset (step_bp_plan);
Chris Lattner24943d22010-06-08 16:52:24 +0000217 QueueThreadPlan (step_bp_plan_sp, false);
218 }
219 }
220 }
221 }
222}
223
224bool
225Thread::WillResume (StateType resume_state)
226{
227 // At this point clear the completed plan stack.
228 m_completed_plan_stack.clear();
229 m_discarded_plan_stack.clear();
230
Jim Ingham149d1f52012-01-31 23:09:20 +0000231 SetTemporaryResumeState(resume_state);
232
233 // This is a little dubious, but we are trying to limit how often we actually fetch stop info from
234 // the target, 'cause that slows down single stepping. So assume that if we got to the point where
235 // we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
236 // about the fact that we are resuming...
237 const uint32_t process_stop_id = GetProcess().GetStopID();
238 if (m_thread_stop_reason_stop_id == process_stop_id &&
239 (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid()))
240 {
241 StopInfo *stop_info = GetPrivateStopReason().get();
242 if (stop_info)
243 stop_info->WillResume (resume_state);
244 }
Chris Lattner24943d22010-06-08 16:52:24 +0000245
246 // Tell all the plans that we are about to resume in case they need to clear any state.
247 // We distinguish between the plan on the top of the stack and the lower
248 // plans in case a plan needs to do any special business before it runs.
249
250 ThreadPlan *plan_ptr = GetCurrentPlan();
251 plan_ptr->WillResume(resume_state, true);
252
253 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
254 {
255 plan_ptr->WillResume (resume_state, false);
256 }
Greg Clayton643ee732010-08-04 01:40:35 +0000257
Greg Clayton643ee732010-08-04 01:40:35 +0000258 m_actual_stop_info_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000259 return true;
260}
261
262void
263Thread::DidResume ()
264{
265 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
266}
267
268bool
269Thread::ShouldStop (Event* event_ptr)
270{
271 ThreadPlan *current_plan = GetCurrentPlan();
272 bool should_stop = true;
273
Greg Claytone005f2c2010-11-06 01:53:30 +0000274 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Ingham149d1f52012-01-31 23:09:20 +0000275
276 if (GetResumeState () == eStateSuspended)
277 {
278 if (log)
279 log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)",
280 __FUNCTION__,
281 GetID ());
282// log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)",
283// __FUNCTION__,
284// GetID (),
285// GetRegisterContext()->GetPC());
286 return false;
287 }
288
289 if (GetTemporaryResumeState () == eStateSuspended)
290 {
291 if (log)
292 log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)",
293 __FUNCTION__,
294 GetID ());
295// log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)",
296// __FUNCTION__,
297// GetID (),
298// GetRegisterContext()->GetPC());
299 return false;
300 }
301
302 if (ThreadStoppedForAReason() == false)
303 {
304 if (log)
305 log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since no stop reason)",
306 __FUNCTION__,
307 GetID (),
308 GetRegisterContext()->GetPC());
309 return false;
310 }
311
Chris Lattner24943d22010-06-08 16:52:24 +0000312 if (log)
313 {
Jim Ingham149d1f52012-01-31 23:09:20 +0000314 log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx",
315 __FUNCTION__,
316 GetID (),
317 GetRegisterContext()->GetPC());
Jim Inghame8f4e112011-10-15 00:23:43 +0000318 log->Printf ("^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
Chris Lattner24943d22010-06-08 16:52:24 +0000319 StreamString s;
Jim Inghame8f4e112011-10-15 00:23:43 +0000320 s.IndentMore();
Chris Lattner24943d22010-06-08 16:52:24 +0000321 DumpThreadPlans(&s);
Jim Inghame8f4e112011-10-15 00:23:43 +0000322 log->Printf ("Plan stack initial state:\n%s", s.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000323 }
Jim Ingham745ac7a2010-11-11 19:26:09 +0000324
325 // The top most plan always gets to do the trace log...
326 current_plan->DoTraceLog ();
Chris Lattner24943d22010-06-08 16:52:24 +0000327
Jim Inghamad382c52011-12-03 01:52:59 +0000328 // If the base plan doesn't understand why we stopped, then we have to find a plan that does.
329 // If that plan is still working, then we don't need to do any more work. If the plan that explains
330 // the stop is done, then we should pop all the plans below it, and pop it, and then let the plans above it decide
331 // whether they still need to do more work.
332
333 bool done_processing_current_plan = false;
334
335 if (!current_plan->PlanExplainsStop())
336 {
337 if (current_plan->TracerExplainsStop())
338 {
339 done_processing_current_plan = true;
340 should_stop = false;
341 }
342 else
343 {
344 // If the current plan doesn't explain the stop, then, find one that
345 // does and let it handle the situation.
346 ThreadPlan *plan_ptr = current_plan;
347 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
348 {
349 if (plan_ptr->PlanExplainsStop())
350 {
351 should_stop = plan_ptr->ShouldStop (event_ptr);
352
353 // plan_ptr explains the stop, next check whether plan_ptr is done, if so, then we should take it
354 // and all the plans below it off the stack.
355
356 if (plan_ptr->MischiefManaged())
357 {
358 // We're going to pop the plans up to AND INCLUDING the plan that explains the stop.
359 plan_ptr = GetPreviousPlan(plan_ptr);
360
361 do
362 {
363 if (should_stop)
364 current_plan->WillStop();
365 PopPlan();
366 }
367 while ((current_plan = GetCurrentPlan()) != plan_ptr);
368 done_processing_current_plan = false;
369 }
370 else
371 done_processing_current_plan = true;
372
373 break;
374 }
375
376 }
377 }
378 }
379
380 if (!done_processing_current_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000381 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000382 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
Jim Inghamf9f40c22011-02-08 05:20:59 +0000383
Jim Inghame8f4e112011-10-15 00:23:43 +0000384 if (log)
385 log->Printf("Plan %s explains stop, auto-continue %i.", current_plan->GetName(), over_ride_stop);
386
Jim Inghamf9f40c22011-02-08 05:20:59 +0000387 // We're starting from the base plan, so just let it decide;
388 if (PlanIsBasePlan(current_plan))
Chris Lattner24943d22010-06-08 16:52:24 +0000389 {
Jim Inghamf9f40c22011-02-08 05:20:59 +0000390 should_stop = current_plan->ShouldStop (event_ptr);
391 if (log)
Greg Clayton628cead2011-05-19 03:54:16 +0000392 log->Printf("Base plan says should stop: %i.", should_stop);
Jim Inghamf9f40c22011-02-08 05:20:59 +0000393 }
394 else
395 {
396 // Otherwise, don't let the base plan override what the other plans say to do, since
397 // presumably if there were other plans they would know what to do...
398 while (1)
Chris Lattner24943d22010-06-08 16:52:24 +0000399 {
Jim Inghamf9f40c22011-02-08 05:20:59 +0000400 if (PlanIsBasePlan(current_plan))
Chris Lattner24943d22010-06-08 16:52:24 +0000401 break;
Jim Inghamf9f40c22011-02-08 05:20:59 +0000402
403 should_stop = current_plan->ShouldStop(event_ptr);
404 if (log)
405 log->Printf("Plan %s should stop: %d.", current_plan->GetName(), should_stop);
406 if (current_plan->MischiefManaged())
407 {
408 if (should_stop)
409 current_plan->WillStop();
410
411 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
412 // Otherwise, see if the plan's parent wants to stop.
413
414 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
415 {
416 PopPlan();
417 break;
418 }
419 else
420 {
421
422 PopPlan();
423
424 current_plan = GetCurrentPlan();
425 if (current_plan == NULL)
426 {
427 break;
428 }
429 }
430
Chris Lattner24943d22010-06-08 16:52:24 +0000431 }
432 else
433 {
Jim Inghamf9f40c22011-02-08 05:20:59 +0000434 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000435 }
Chris Lattner24943d22010-06-08 16:52:24 +0000436 }
437 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000438 if (over_ride_stop)
439 should_stop = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000440 }
Chris Lattner24943d22010-06-08 16:52:24 +0000441
Jim Inghame8f4e112011-10-15 00:23:43 +0000442 if (log)
443 {
444 StreamString s;
445 s.IndentMore();
446 DumpThreadPlans(&s);
447 log->Printf ("Plan stack final state:\n%s", s.GetData());
448 log->Printf ("vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv", should_stop);
449 }
Chris Lattner24943d22010-06-08 16:52:24 +0000450 return should_stop;
451}
452
453Vote
454Thread::ShouldReportStop (Event* event_ptr)
455{
456 StateType thread_state = GetResumeState ();
Jim Ingham149d1f52012-01-31 23:09:20 +0000457 StateType temp_thread_state = GetTemporaryResumeState();
458
Greg Claytone005f2c2010-11-06 01:53:30 +0000459 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Greg Clayton5205f0b2010-09-03 17:10:42 +0000460
461 if (thread_state == eStateSuspended || thread_state == eStateInvalid)
462 {
463 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +0000464 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
Chris Lattner24943d22010-06-08 16:52:24 +0000465 return eVoteNoOpinion;
Greg Clayton5205f0b2010-09-03 17:10:42 +0000466 }
Chris Lattner24943d22010-06-08 16:52:24 +0000467
Jim Ingham149d1f52012-01-31 23:09:20 +0000468 if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid)
469 {
470 if (log)
471 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
472 return eVoteNoOpinion;
473 }
474
475 if (!ThreadStoppedForAReason())
476 {
477 if (log)
478 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion);
479 return eVoteNoOpinion;
480 }
481
Chris Lattner24943d22010-06-08 16:52:24 +0000482 if (m_completed_plan_stack.size() > 0)
483 {
484 // Don't use GetCompletedPlan here, since that suppresses private plans.
Greg Clayton5205f0b2010-09-03 17:10:42 +0000485 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +0000486 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for complete stack's back plan\n", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000487 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
488 }
489 else
Greg Clayton5205f0b2010-09-03 17:10:42 +0000490 {
491 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +0000492 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for current plan\n", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000493 return GetCurrentPlan()->ShouldReportStop (event_ptr);
Greg Clayton5205f0b2010-09-03 17:10:42 +0000494 }
Chris Lattner24943d22010-06-08 16:52:24 +0000495}
496
497Vote
498Thread::ShouldReportRun (Event* event_ptr)
499{
500 StateType thread_state = GetResumeState ();
Jim Inghamac959662011-01-24 06:34:17 +0000501
Chris Lattner24943d22010-06-08 16:52:24 +0000502 if (thread_state == eStateSuspended
503 || thread_state == eStateInvalid)
Jim Inghamac959662011-01-24 06:34:17 +0000504 {
Chris Lattner24943d22010-06-08 16:52:24 +0000505 return eVoteNoOpinion;
Jim Inghamac959662011-01-24 06:34:17 +0000506 }
507
508 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000509 if (m_completed_plan_stack.size() > 0)
510 {
511 // Don't use GetCompletedPlan here, since that suppresses private plans.
Jim Inghamac959662011-01-24 06:34:17 +0000512 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +0000513 log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.",
Jim Inghamac959662011-01-24 06:34:17 +0000514 GetIndexID(),
515 GetID(),
516 m_completed_plan_stack.back()->GetName());
517
Chris Lattner24943d22010-06-08 16:52:24 +0000518 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
519 }
520 else
Jim Inghamac959662011-01-24 06:34:17 +0000521 {
522 if (log)
Greg Clayton444e35b2011-10-19 18:09:39 +0000523 log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.",
Jim Inghamac959662011-01-24 06:34:17 +0000524 GetIndexID(),
525 GetID(),
526 GetCurrentPlan()->GetName());
527
Chris Lattner24943d22010-06-08 16:52:24 +0000528 return GetCurrentPlan()->ShouldReportRun (event_ptr);
Jim Inghamac959662011-01-24 06:34:17 +0000529 }
Chris Lattner24943d22010-06-08 16:52:24 +0000530}
531
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000532bool
533Thread::MatchesSpec (const ThreadSpec *spec)
534{
535 if (spec == NULL)
536 return true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000537
Jim Ingham649492b2010-06-18 01:00:58 +0000538 return spec->ThreadPassesBasicTests(this);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000539}
540
Chris Lattner24943d22010-06-08 16:52:24 +0000541void
542Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
543{
544 if (thread_plan_sp)
545 {
Jim Ingham745ac7a2010-11-11 19:26:09 +0000546 // If the thread plan doesn't already have a tracer, give it its parent's tracer:
547 if (!thread_plan_sp->GetThreadPlanTracer())
548 thread_plan_sp->SetThreadPlanTracer(m_plan_stack.back()->GetThreadPlanTracer());
Jim Ingham6297a3a2010-10-20 00:39:53 +0000549 m_plan_stack.push_back (thread_plan_sp);
Jim Ingham745ac7a2010-11-11 19:26:09 +0000550
Chris Lattner24943d22010-06-08 16:52:24 +0000551 thread_plan_sp->DidPush();
552
Greg Claytone005f2c2010-11-06 01:53:30 +0000553 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000554 if (log)
555 {
556 StreamString s;
557 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
Greg Clayton444e35b2011-10-19 18:09:39 +0000558 log->Printf("Pushing plan: \"%s\", tid = 0x%4.4llx.",
Chris Lattner24943d22010-06-08 16:52:24 +0000559 s.GetData(),
Jim Ingham6297a3a2010-10-20 00:39:53 +0000560 thread_plan_sp->GetThread().GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000561 }
562 }
563}
564
565void
566Thread::PopPlan ()
567{
Greg Claytone005f2c2010-11-06 01:53:30 +0000568 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000569
Jim Ingham6297a3a2010-10-20 00:39:53 +0000570 if (m_plan_stack.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000571 return;
572 else
573 {
574 ThreadPlanSP &plan = m_plan_stack.back();
575 if (log)
576 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000577 log->Printf("Popping plan: \"%s\", tid = 0x%4.4llx.", plan->GetName(), plan->GetThread().GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000578 }
579 m_completed_plan_stack.push_back (plan);
580 plan->WillPop();
581 m_plan_stack.pop_back();
582 }
583}
584
585void
586Thread::DiscardPlan ()
587{
588 if (m_plan_stack.size() > 1)
589 {
590 ThreadPlanSP &plan = m_plan_stack.back();
591 m_discarded_plan_stack.push_back (plan);
592 plan->WillPop();
593 m_plan_stack.pop_back();
594 }
595}
596
597ThreadPlan *
598Thread::GetCurrentPlan ()
599{
Jim Ingham6297a3a2010-10-20 00:39:53 +0000600 if (m_plan_stack.empty())
Chris Lattner24943d22010-06-08 16:52:24 +0000601 return NULL;
602 else
603 return m_plan_stack.back().get();
604}
605
606ThreadPlanSP
607Thread::GetCompletedPlan ()
608{
609 ThreadPlanSP empty_plan_sp;
610 if (!m_completed_plan_stack.empty())
611 {
612 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
613 {
614 ThreadPlanSP completed_plan_sp;
615 completed_plan_sp = m_completed_plan_stack[i];
616 if (!completed_plan_sp->GetPrivate ())
617 return completed_plan_sp;
618 }
619 }
620 return empty_plan_sp;
621}
622
Jim Ingham1586d972011-12-17 01:35:57 +0000623ValueObjectSP
624Thread::GetReturnValueObject ()
625{
626 if (!m_completed_plan_stack.empty())
627 {
628 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
629 {
630 ValueObjectSP return_valobj_sp;
631 return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject();
632 if (return_valobj_sp)
633 return return_valobj_sp;
634 }
635 }
636 return ValueObjectSP();
637}
638
Chris Lattner24943d22010-06-08 16:52:24 +0000639bool
640Thread::IsThreadPlanDone (ThreadPlan *plan)
641{
Chris Lattner24943d22010-06-08 16:52:24 +0000642 if (!m_completed_plan_stack.empty())
643 {
644 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
645 {
646 if (m_completed_plan_stack[i].get() == plan)
647 return true;
648 }
649 }
650 return false;
651}
652
653bool
654Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
655{
Chris Lattner24943d22010-06-08 16:52:24 +0000656 if (!m_discarded_plan_stack.empty())
657 {
658 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
659 {
660 if (m_discarded_plan_stack[i].get() == plan)
661 return true;
662 }
663 }
664 return false;
665}
666
667ThreadPlan *
668Thread::GetPreviousPlan (ThreadPlan *current_plan)
669{
670 if (current_plan == NULL)
671 return NULL;
672
673 int stack_size = m_completed_plan_stack.size();
674 for (int i = stack_size - 1; i > 0; i--)
675 {
676 if (current_plan == m_completed_plan_stack[i].get())
677 return m_completed_plan_stack[i-1].get();
678 }
679
680 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
681 {
Chris Lattner24943d22010-06-08 16:52:24 +0000682 if (m_plan_stack.size() > 0)
683 return m_plan_stack.back().get();
684 else
685 return NULL;
686 }
687
688 stack_size = m_plan_stack.size();
689 for (int i = stack_size - 1; i > 0; i--)
690 {
691 if (current_plan == m_plan_stack[i].get())
692 return m_plan_stack[i-1].get();
693 }
694 return NULL;
695}
696
697void
698Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
699{
700 if (abort_other_plans)
701 DiscardThreadPlans(true);
702
703 PushPlan (thread_plan_sp);
704}
705
Jim Ingham745ac7a2010-11-11 19:26:09 +0000706
707void
708Thread::EnableTracer (bool value, bool single_stepping)
709{
710 int stack_size = m_plan_stack.size();
711 for (int i = 0; i < stack_size; i++)
712 {
713 if (m_plan_stack[i]->GetThreadPlanTracer())
714 {
715 m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value);
716 m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping);
717 }
718 }
719}
720
721void
722Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp)
723{
724 int stack_size = m_plan_stack.size();
725 for (int i = 0; i < stack_size; i++)
726 m_plan_stack[i]->SetThreadPlanTracer(tracer_sp);
727}
728
Chris Lattner24943d22010-06-08 16:52:24 +0000729void
Jim Inghamea9d4262010-11-05 19:25:48 +0000730Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp)
731{
Greg Claytone005f2c2010-11-06 01:53:30 +0000732 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Inghamea9d4262010-11-05 19:25:48 +0000733 if (log)
734 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000735 log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_sp.get());
Jim Inghamea9d4262010-11-05 19:25:48 +0000736 }
737
738 int stack_size = m_plan_stack.size();
739
740 // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the
741 // stack, and if so discard up to and including it.
742
743 if (up_to_plan_sp.get() == NULL)
744 {
745 for (int i = stack_size - 1; i > 0; i--)
746 DiscardPlan();
747 }
748 else
749 {
750 bool found_it = false;
751 for (int i = stack_size - 1; i > 0; i--)
752 {
753 if (m_plan_stack[i] == up_to_plan_sp)
754 found_it = true;
755 }
756 if (found_it)
757 {
758 bool last_one = false;
759 for (int i = stack_size - 1; i > 0 && !last_one ; i--)
760 {
761 if (GetCurrentPlan() == up_to_plan_sp.get())
762 last_one = true;
763 DiscardPlan();
764 }
765 }
766 }
767 return;
768}
769
770void
Chris Lattner24943d22010-06-08 16:52:24 +0000771Thread::DiscardThreadPlans(bool force)
772{
Greg Claytone005f2c2010-11-06 01:53:30 +0000773 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000774 if (log)
775 {
Greg Clayton444e35b2011-10-19 18:09:39 +0000776 log->Printf("Discarding thread plans for thread (tid = 0x%4.4llx, force %d)", GetID(), force);
Chris Lattner24943d22010-06-08 16:52:24 +0000777 }
778
779 if (force)
780 {
781 int stack_size = m_plan_stack.size();
782 for (int i = stack_size - 1; i > 0; i--)
783 {
784 DiscardPlan();
785 }
786 return;
787 }
788
789 while (1)
790 {
791
792 int master_plan_idx;
793 bool discard;
794
795 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
796 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
797 {
798 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
799 {
800 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
801 break;
802 }
803 }
804
805 if (discard)
806 {
807 // First pop all the dependent plans:
808 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
809 {
810
811 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
812 // for the plan leaves it in a state that it is safe to pop the plan
813 // with no more notice?
814 DiscardPlan();
815 }
816
817 // Now discard the master plan itself.
818 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
819 // discard it's dependent plans, but not it...
820 if (master_plan_idx > 0)
821 {
822 DiscardPlan();
823 }
824 }
825 else
826 {
827 // If the master plan doesn't want to get discarded, then we're done.
828 break;
829 }
830
831 }
Chris Lattner24943d22010-06-08 16:52:24 +0000832}
833
834ThreadPlan *
835Thread::QueueFundamentalPlan (bool abort_other_plans)
836{
837 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
838 QueueThreadPlan (thread_plan_sp, abort_other_plans);
839 return thread_plan_sp.get();
840}
841
842ThreadPlan *
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000843Thread::QueueThreadPlanForStepSingleInstruction
844(
845 bool step_over,
846 bool abort_other_plans,
847 bool stop_other_threads
848)
Chris Lattner24943d22010-06-08 16:52:24 +0000849{
850 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
851 QueueThreadPlan (thread_plan_sp, abort_other_plans);
852 return thread_plan_sp.get();
853}
854
855ThreadPlan *
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000856Thread::QueueThreadPlanForStepRange
857(
858 bool abort_other_plans,
859 StepType type,
860 const AddressRange &range,
861 const SymbolContext &addr_context,
862 lldb::RunMode stop_other_threads,
863 bool avoid_code_without_debug_info
864)
Chris Lattner24943d22010-06-08 16:52:24 +0000865{
866 ThreadPlanSP thread_plan_sp;
867 if (type == eStepTypeInto)
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000868 {
869 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
870 if (avoid_code_without_debug_info)
871 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
872 else
873 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
874 thread_plan_sp.reset (plan);
875 }
Chris Lattner24943d22010-06-08 16:52:24 +0000876 else
877 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
878
879 QueueThreadPlan (thread_plan_sp, abort_other_plans);
880 return thread_plan_sp.get();
881}
882
883
884ThreadPlan *
885Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
886{
887 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
888 QueueThreadPlan (thread_plan_sp, abort_other_plans);
889 return thread_plan_sp.get();
890}
891
892ThreadPlan *
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000893Thread::QueueThreadPlanForStepOut
894(
895 bool abort_other_plans,
896 SymbolContext *addr_context,
897 bool first_insn,
898 bool stop_other_threads,
899 Vote stop_vote,
900 Vote run_vote,
901 uint32_t frame_idx
902)
Chris Lattner24943d22010-06-08 16:52:24 +0000903{
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000904 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this,
905 addr_context,
906 first_insn,
907 stop_other_threads,
908 stop_vote,
909 run_vote,
910 frame_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000911 QueueThreadPlan (thread_plan_sp, abort_other_plans);
912 return thread_plan_sp.get();
913}
914
915ThreadPlan *
916Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
917{
Jim Inghamad382c52011-12-03 01:52:59 +0000918 ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, stop_other_threads));
919 if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL))
920 return NULL;
921
Chris Lattner24943d22010-06-08 16:52:24 +0000922 QueueThreadPlan (thread_plan_sp, abort_other_plans);
923 return thread_plan_sp.get();
924}
925
926ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +0000927Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
928 Address& function,
929 lldb::addr_t arg,
930 bool stop_other_threads,
931 bool discard_on_error)
932{
Jim Ingham016ef882011-12-22 19:12:40 +0000933 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error));
Chris Lattner24943d22010-06-08 16:52:24 +0000934 QueueThreadPlan (thread_plan_sp, abort_other_plans);
935 return thread_plan_sp.get();
936}
937
938ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +0000939Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
940 Address &target_addr,
941 bool stop_other_threads)
942{
943 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
944 QueueThreadPlan (thread_plan_sp, abort_other_plans);
945 return thread_plan_sp.get();
946}
947
948ThreadPlan *
949Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000950 lldb::addr_t *address_list,
951 size_t num_addresses,
952 bool stop_other_threads,
953 uint32_t frame_idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000954{
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000955 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000956 QueueThreadPlan (thread_plan_sp, abort_other_plans);
957 return thread_plan_sp.get();
958
959}
960
961uint32_t
962Thread::GetIndexID () const
963{
964 return m_index_id;
965}
966
967void
968Thread::DumpThreadPlans (lldb_private::Stream *s) const
969{
970 uint32_t stack_size = m_plan_stack.size();
Greg Claytonf04d6612010-09-03 22:45:01 +0000971 int i;
Jim Inghame8f4e112011-10-15 00:23:43 +0000972 s->Indent();
Greg Clayton444e35b2011-10-19 18:09:39 +0000973 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4llx, stack_size = %d\n", GetIndexID(), GetID(), stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000974 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000975 {
Chris Lattner24943d22010-06-08 16:52:24 +0000976 s->IndentMore();
Jim Inghame8f4e112011-10-15 00:23:43 +0000977 s->Indent();
978 s->Printf ("Element %d: ", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000979 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
Chris Lattner24943d22010-06-08 16:52:24 +0000980 s->EOL();
Jim Inghame8f4e112011-10-15 00:23:43 +0000981 s->IndentLess();
Chris Lattner24943d22010-06-08 16:52:24 +0000982 }
983
Chris Lattner24943d22010-06-08 16:52:24 +0000984 stack_size = m_completed_plan_stack.size();
Jim Inghame8f4e112011-10-15 00:23:43 +0000985 if (stack_size > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000986 {
Jim Inghame8f4e112011-10-15 00:23:43 +0000987 s->Indent();
988 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
989 for (i = stack_size - 1; i >= 0; i--)
990 {
991 s->IndentMore();
992 s->Indent();
993 s->Printf ("Element %d: ", i);
994 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
995 s->EOL();
996 s->IndentLess();
997 }
Chris Lattner24943d22010-06-08 16:52:24 +0000998 }
999
1000 stack_size = m_discarded_plan_stack.size();
Jim Inghame8f4e112011-10-15 00:23:43 +00001001 if (stack_size > 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001002 {
Jim Inghame8f4e112011-10-15 00:23:43 +00001003 s->Indent();
1004 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
1005 for (i = stack_size - 1; i >= 0; i--)
1006 {
1007 s->IndentMore();
1008 s->Indent();
1009 s->Printf ("Element %d: ", i);
1010 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1011 s->EOL();
1012 s->IndentLess();
1013 }
Chris Lattner24943d22010-06-08 16:52:24 +00001014 }
1015
1016}
1017
1018Target *
1019Thread::CalculateTarget ()
1020{
1021 return m_process.CalculateTarget();
1022}
1023
1024Process *
1025Thread::CalculateProcess ()
1026{
1027 return &m_process;
1028}
1029
1030Thread *
1031Thread::CalculateThread ()
1032{
1033 return this;
1034}
1035
1036StackFrame *
1037Thread::CalculateStackFrame ()
1038{
1039 return NULL;
1040}
1041
1042void
Greg Claytona830adb2010-10-04 01:05:56 +00001043Thread::CalculateExecutionContext (ExecutionContext &exe_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +00001044{
Greg Claytona830adb2010-10-04 01:05:56 +00001045 m_process.CalculateExecutionContext (exe_ctx);
Greg Clayton567e7f32011-09-22 04:58:26 +00001046 exe_ctx.SetThreadPtr (this);
1047 exe_ctx.SetFramePtr (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00001048}
1049
Greg Clayton782b9cc2010-08-25 00:35:26 +00001050
1051StackFrameList &
1052Thread::GetStackFrameList ()
1053{
Greg Claytonc51ffbf2011-08-12 21:40:01 +00001054 if (!m_curr_frames_sp)
1055 m_curr_frames_sp.reset (new StackFrameList (*this, m_prev_frames_sp, true));
1056 return *m_curr_frames_sp;
Greg Clayton782b9cc2010-08-25 00:35:26 +00001057}
1058
Greg Clayton782b9cc2010-08-25 00:35:26 +00001059void
1060Thread::ClearStackFrames ()
1061{
Greg Claytonc51ffbf2011-08-12 21:40:01 +00001062 if (m_curr_frames_sp && m_curr_frames_sp->GetNumFrames (false) > 1)
1063 m_prev_frames_sp.swap (m_curr_frames_sp);
1064 m_curr_frames_sp.reset();
Jim Ingham71219082010-08-12 02:14:28 +00001065}
1066
1067lldb::StackFrameSP
Greg Clayton08d7d3a2011-01-06 22:15:06 +00001068Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
1069{
1070 return GetStackFrameList().GetFrameWithConcreteFrameIndex (unwind_idx);
1071}
1072
Chris Lattner24943d22010-06-08 16:52:24 +00001073void
Greg Claytona830adb2010-10-04 01:05:56 +00001074Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
Chris Lattner24943d22010-06-08 16:52:24 +00001075{
Greg Claytona830adb2010-10-04 01:05:56 +00001076 ExecutionContext exe_ctx;
Greg Clayton567e7f32011-09-22 04:58:26 +00001077 StackFrameSP frame_sp;
Greg Claytona830adb2010-10-04 01:05:56 +00001078 SymbolContext frame_sc;
1079 CalculateExecutionContext (exe_ctx);
Chris Lattner24943d22010-06-08 16:52:24 +00001080
Greg Claytona830adb2010-10-04 01:05:56 +00001081 if (frame_idx != LLDB_INVALID_INDEX32)
Chris Lattner24943d22010-06-08 16:52:24 +00001082 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001083 frame_sp = GetStackFrameAtIndex (frame_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001084 if (frame_sp)
1085 {
Greg Clayton567e7f32011-09-22 04:58:26 +00001086 exe_ctx.SetFrameSP(frame_sp);
1087 frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
Chris Lattner24943d22010-06-08 16:52:24 +00001088 }
1089 }
1090
Greg Claytona830adb2010-10-04 01:05:56 +00001091 const char *thread_format = GetProcess().GetTarget().GetDebugger().GetThreadFormat();
1092 assert (thread_format);
1093 const char *end = NULL;
1094 Debugger::FormatPrompt (thread_format,
Greg Clayton567e7f32011-09-22 04:58:26 +00001095 frame_sp ? &frame_sc : NULL,
Greg Claytona830adb2010-10-04 01:05:56 +00001096 &exe_ctx,
1097 NULL,
1098 strm,
1099 &end);
Chris Lattner24943d22010-06-08 16:52:24 +00001100}
1101
Greg Clayton990de7b2010-11-18 23:32:35 +00001102void
Caroline Tice2a456812011-03-10 22:14:10 +00001103Thread::SettingsInitialize ()
Jim Ingham20594b12010-09-08 03:14:33 +00001104{
Greg Clayton334d33a2012-01-30 07:41:31 +00001105 UserSettingsController::InitializeSettingsController (GetSettingsController(),
Greg Clayton990de7b2010-11-18 23:32:35 +00001106 SettingsController::global_settings_table,
1107 SettingsController::instance_settings_table);
Caroline Tice2a456812011-03-10 22:14:10 +00001108
1109 // Now call SettingsInitialize() on each 'child' setting of Thread.
1110 // Currently there are none.
Greg Clayton990de7b2010-11-18 23:32:35 +00001111}
Jim Ingham20594b12010-09-08 03:14:33 +00001112
Greg Clayton990de7b2010-11-18 23:32:35 +00001113void
Caroline Tice2a456812011-03-10 22:14:10 +00001114Thread::SettingsTerminate ()
Greg Clayton990de7b2010-11-18 23:32:35 +00001115{
Caroline Tice2a456812011-03-10 22:14:10 +00001116 // Must call SettingsTerminate() on each 'child' setting of Thread before terminating Thread settings.
1117 // Currently there are none.
1118
1119 // Now terminate Thread Settings.
1120
Greg Clayton990de7b2010-11-18 23:32:35 +00001121 UserSettingsControllerSP &usc = GetSettingsController();
1122 UserSettingsController::FinalizeSettingsController (usc);
1123 usc.reset();
1124}
Jim Ingham20594b12010-09-08 03:14:33 +00001125
Greg Clayton990de7b2010-11-18 23:32:35 +00001126UserSettingsControllerSP &
1127Thread::GetSettingsController ()
1128{
Greg Clayton334d33a2012-01-30 07:41:31 +00001129 static UserSettingsControllerSP g_settings_controller_sp;
1130 if (!g_settings_controller_sp)
1131 {
1132 g_settings_controller_sp.reset (new Thread::SettingsController);
1133 // The first shared pointer to Target::SettingsController in
1134 // g_settings_controller_sp must be fully created above so that
1135 // the TargetInstanceSettings can use a weak_ptr to refer back
1136 // to the master setttings controller
1137 InstanceSettingsSP default_instance_settings_sp (new ThreadInstanceSettings (g_settings_controller_sp,
1138 false,
1139 InstanceSettings::GetDefaultName().AsCString()));
1140
1141 g_settings_controller_sp->SetDefaultInstanceSettings (default_instance_settings_sp);
1142 }
1143 return g_settings_controller_sp;
Jim Ingham20594b12010-09-08 03:14:33 +00001144}
1145
Caroline Tice1ebef442010-09-27 00:30:10 +00001146void
1147Thread::UpdateInstanceName ()
1148{
1149 StreamString sstr;
1150 const char *name = GetName();
1151
1152 if (name && name[0] != '\0')
1153 sstr.Printf ("%s", name);
1154 else if ((GetIndexID() != 0) || (GetID() != 0))
Jason Molenda7e5fa7f2011-09-20 21:44:10 +00001155 sstr.Printf ("0x%4.4x", GetIndexID());
Caroline Tice1ebef442010-09-27 00:30:10 +00001156
1157 if (sstr.GetSize() > 0)
1158 Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData());
1159}
1160
Jim Inghamccd584d2010-09-23 17:40:12 +00001161lldb::StackFrameSP
1162Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
1163{
1164 return GetStackFrameList().GetStackFrameSPForStackFramePtr (stack_frame_ptr);
1165}
Caroline Tice7826c882010-10-26 03:11:13 +00001166
1167const char *
1168Thread::StopReasonAsCString (lldb::StopReason reason)
1169{
1170 switch (reason)
1171 {
1172 case eStopReasonInvalid: return "invalid";
1173 case eStopReasonNone: return "none";
1174 case eStopReasonTrace: return "trace";
1175 case eStopReasonBreakpoint: return "breakpoint";
1176 case eStopReasonWatchpoint: return "watchpoint";
1177 case eStopReasonSignal: return "signal";
1178 case eStopReasonException: return "exception";
1179 case eStopReasonPlanComplete: return "plan complete";
1180 }
1181
1182
1183 static char unknown_state_string[64];
1184 snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason);
1185 return unknown_state_string;
1186}
1187
1188const char *
1189Thread::RunModeAsCString (lldb::RunMode mode)
1190{
1191 switch (mode)
1192 {
1193 case eOnlyThisThread: return "only this thread";
1194 case eAllThreads: return "all threads";
1195 case eOnlyDuringStepping: return "only during stepping";
1196 }
1197
1198 static char unknown_state_string[64];
1199 snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode);
1200 return unknown_state_string;
1201}
Jim Ingham745ac7a2010-11-11 19:26:09 +00001202
Greg Claytonabe0fed2011-04-18 08:33:37 +00001203size_t
1204Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source)
1205{
1206 size_t num_frames_shown = 0;
1207 strm.Indent();
1208 strm.Printf("%c ", GetProcess().GetThreadList().GetSelectedThread().get() == this ? '*' : ' ');
Greg Claytonc5dca6c2011-08-12 06:47:54 +00001209 if (GetProcess().GetTarget().GetDebugger().GetUseExternalEditor())
Greg Claytonabe0fed2011-04-18 08:33:37 +00001210 {
Greg Claytonc5dca6c2011-08-12 06:47:54 +00001211 StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame);
Jim Inghamc2da8eb2011-08-16 00:07:28 +00001212 if (frame_sp)
Greg Claytonc5dca6c2011-08-12 06:47:54 +00001213 {
Jim Inghamc2da8eb2011-08-16 00:07:28 +00001214 SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry));
1215 if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file)
1216 {
1217 Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
1218 }
Greg Claytonc5dca6c2011-08-12 06:47:54 +00001219 }
Greg Claytonabe0fed2011-04-18 08:33:37 +00001220 }
1221
1222 DumpUsingSettingsFormat (strm, start_frame);
1223
1224 if (num_frames > 0)
1225 {
1226 strm.IndentMore();
1227
1228 const bool show_frame_info = true;
1229 const uint32_t source_lines_before = 3;
1230 const uint32_t source_lines_after = 3;
Jim Ingham7868bcc2011-07-26 02:39:59 +00001231 strm.IndentMore ();
Greg Claytonabe0fed2011-04-18 08:33:37 +00001232 num_frames_shown = GetStackFrameList ().GetStatus (strm,
1233 start_frame,
1234 num_frames,
1235 show_frame_info,
1236 num_frames_with_source,
1237 source_lines_before,
1238 source_lines_after);
1239 strm.IndentLess();
Jim Ingham7868bcc2011-07-26 02:39:59 +00001240 strm.IndentLess();
Greg Claytonabe0fed2011-04-18 08:33:37 +00001241 }
1242 return num_frames_shown;
1243}
1244
1245size_t
1246Thread::GetStackFrameStatus (Stream& strm,
1247 uint32_t first_frame,
1248 uint32_t num_frames,
1249 bool show_frame_info,
1250 uint32_t num_frames_with_source,
1251 uint32_t source_lines_before,
1252 uint32_t source_lines_after)
1253{
1254 return GetStackFrameList().GetStatus (strm,
1255 first_frame,
1256 num_frames,
1257 show_frame_info,
1258 num_frames_with_source,
1259 source_lines_before,
1260 source_lines_after);
1261}
1262
Peter Collingbournee426d852011-06-03 20:40:54 +00001263bool
1264Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
1265{
1266 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
1267 if (frame_sp)
1268 {
1269 checkpoint.SetStackID(frame_sp->GetStackID());
1270 return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData());
1271 }
1272 return false;
1273}
Greg Claytonabe0fed2011-04-18 08:33:37 +00001274
Peter Collingbournee426d852011-06-03 20:40:54 +00001275bool
1276Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
1277{
1278 lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
1279 if (frame_sp)
1280 {
1281 bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
1282
1283 // Clear out all stack frames as our world just changed.
1284 ClearStackFrames();
1285 frame_sp->GetRegisterContext()->InvalidateIfNeeded(true);
1286
1287 return ret;
1288 }
1289 return false;
1290}
Greg Claytonabe0fed2011-04-18 08:33:37 +00001291
Greg Clayton37f962e2011-08-22 02:49:39 +00001292Unwind *
1293Thread::GetUnwinder ()
1294{
1295 if (m_unwinder_ap.get() == NULL)
1296 {
1297 const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
1298 const llvm::Triple::ArchType machine = target_arch.GetMachine();
1299 switch (machine)
1300 {
1301 case llvm::Triple::x86_64:
1302 case llvm::Triple::x86:
1303 case llvm::Triple::arm:
1304 case llvm::Triple::thumb:
1305 m_unwinder_ap.reset (new UnwindLLDB (*this));
1306 break;
1307
1308 default:
1309 if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple)
1310 m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
1311 break;
1312 }
1313 }
1314 return m_unwinder_ap.get();
1315}
1316
1317
Greg Clayton990de7b2010-11-18 23:32:35 +00001318#pragma mark "Thread::SettingsController"
Jim Ingham745ac7a2010-11-11 19:26:09 +00001319//--------------------------------------------------------------
Greg Clayton990de7b2010-11-18 23:32:35 +00001320// class Thread::SettingsController
Jim Ingham745ac7a2010-11-11 19:26:09 +00001321//--------------------------------------------------------------
1322
Greg Clayton990de7b2010-11-18 23:32:35 +00001323Thread::SettingsController::SettingsController () :
Jim Ingham745ac7a2010-11-11 19:26:09 +00001324 UserSettingsController ("thread", Process::GetSettingsController())
1325{
Jim Ingham745ac7a2010-11-11 19:26:09 +00001326}
1327
Greg Clayton990de7b2010-11-18 23:32:35 +00001328Thread::SettingsController::~SettingsController ()
Jim Ingham745ac7a2010-11-11 19:26:09 +00001329{
1330}
1331
1332lldb::InstanceSettingsSP
Greg Clayton990de7b2010-11-18 23:32:35 +00001333Thread::SettingsController::CreateInstanceSettings (const char *instance_name)
Jim Ingham745ac7a2010-11-11 19:26:09 +00001334{
Greg Clayton334d33a2012-01-30 07:41:31 +00001335 lldb::InstanceSettingsSP new_settings_sp (new ThreadInstanceSettings (GetSettingsController(),
1336 false,
1337 instance_name));
Jim Ingham745ac7a2010-11-11 19:26:09 +00001338 return new_settings_sp;
1339}
1340
1341#pragma mark "ThreadInstanceSettings"
1342//--------------------------------------------------------------
1343// class ThreadInstanceSettings
1344//--------------------------------------------------------------
1345
Greg Clayton334d33a2012-01-30 07:41:31 +00001346ThreadInstanceSettings::ThreadInstanceSettings (const UserSettingsControllerSP &owner_sp, bool live_instance, const char *name) :
1347 InstanceSettings (owner_sp, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
Jim Ingham745ac7a2010-11-11 19:26:09 +00001348 m_avoid_regexp_ap (),
1349 m_trace_enabled (false)
1350{
1351 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1352 // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers.
1353 // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
1354 // This is true for CreateInstanceName() too.
1355
1356 if (GetInstanceName() == InstanceSettings::InvalidName())
1357 {
1358 ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
Greg Clayton334d33a2012-01-30 07:41:31 +00001359 owner_sp->RegisterInstanceSettings (this);
Jim Ingham745ac7a2010-11-11 19:26:09 +00001360 }
1361
1362 if (live_instance)
1363 {
Greg Clayton334d33a2012-01-30 07:41:31 +00001364 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name),false);
Jim Ingham745ac7a2010-11-11 19:26:09 +00001365 }
1366}
1367
1368ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) :
Greg Clayton334d33a2012-01-30 07:41:31 +00001369 InstanceSettings (Thread::GetSettingsController(), CreateInstanceName().AsCString()),
Jim Ingham745ac7a2010-11-11 19:26:09 +00001370 m_avoid_regexp_ap (),
1371 m_trace_enabled (rhs.m_trace_enabled)
1372{
1373 if (m_instance_name != InstanceSettings::GetDefaultName())
1374 {
Greg Clayton334d33a2012-01-30 07:41:31 +00001375 UserSettingsControllerSP owner_sp (m_owner_wp.lock());
1376 if (owner_sp)
1377 {
1378 CopyInstanceSettings (owner_sp->FindPendingSettings (m_instance_name), false);
1379 owner_sp->RemovePendingSettings (m_instance_name);
1380 }
Jim Ingham745ac7a2010-11-11 19:26:09 +00001381 }
1382 if (rhs.m_avoid_regexp_ap.get() != NULL)
1383 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
1384}
1385
1386ThreadInstanceSettings::~ThreadInstanceSettings ()
1387{
1388}
1389
1390ThreadInstanceSettings&
1391ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs)
1392{
1393 if (this != &rhs)
1394 {
1395 if (rhs.m_avoid_regexp_ap.get() != NULL)
1396 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
1397 else
1398 m_avoid_regexp_ap.reset(NULL);
1399 }
1400 m_trace_enabled = rhs.m_trace_enabled;
1401 return *this;
1402}
1403
1404
1405void
1406ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1407 const char *index_value,
1408 const char *value,
1409 const ConstString &instance_name,
1410 const SettingEntry &entry,
Greg Claytonb3448432011-03-24 21:19:54 +00001411 VarSetOperationType op,
Jim Ingham745ac7a2010-11-11 19:26:09 +00001412 Error &err,
1413 bool pending)
1414{
1415 if (var_name == StepAvoidRegexpVarName())
1416 {
1417 std::string regexp_text;
1418 if (m_avoid_regexp_ap.get() != NULL)
1419 regexp_text.append (m_avoid_regexp_ap->GetText());
1420 UserSettingsController::UpdateStringVariable (op, regexp_text, value, err);
1421 if (regexp_text.empty())
1422 m_avoid_regexp_ap.reset();
1423 else
1424 {
1425 m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str()));
1426
1427 }
1428 }
1429 else if (var_name == GetTraceThreadVarName())
1430 {
1431 bool success;
1432 bool result = Args::StringToBoolean(value, false, &success);
1433
1434 if (success)
1435 {
1436 m_trace_enabled = result;
1437 if (!pending)
1438 {
1439 Thread *myself = static_cast<Thread *> (this);
1440 myself->EnableTracer(m_trace_enabled, true);
1441 }
1442 }
1443 else
1444 {
1445 err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value);
1446 }
1447
1448 }
1449}
1450
1451void
1452ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1453 bool pending)
1454{
1455 if (new_settings.get() == NULL)
1456 return;
1457
1458 ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get();
1459 if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL)
1460 m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText()));
1461 else
1462 m_avoid_regexp_ap.reset ();
1463}
1464
1465bool
1466ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
1467 const ConstString &var_name,
1468 StringList &value,
1469 Error *err)
1470{
1471 if (var_name == StepAvoidRegexpVarName())
1472 {
1473 if (m_avoid_regexp_ap.get() != NULL)
1474 {
1475 std::string regexp_text("\"");
1476 regexp_text.append(m_avoid_regexp_ap->GetText());
1477 regexp_text.append ("\"");
1478 value.AppendString (regexp_text.c_str());
1479 }
1480
1481 }
1482 else if (var_name == GetTraceThreadVarName())
1483 {
1484 value.AppendString(m_trace_enabled ? "true" : "false");
1485 }
1486 else
1487 {
1488 if (err)
1489 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1490 return false;
1491 }
1492 return true;
1493}
1494
1495const ConstString
1496ThreadInstanceSettings::CreateInstanceName ()
1497{
1498 static int instance_count = 1;
1499 StreamString sstr;
1500
1501 sstr.Printf ("thread_%d", instance_count);
1502 ++instance_count;
1503
1504 const ConstString ret_val (sstr.GetData());
1505 return ret_val;
1506}
1507
1508const ConstString &
1509ThreadInstanceSettings::StepAvoidRegexpVarName ()
1510{
1511 static ConstString step_avoid_var_name ("step-avoid-regexp");
1512
1513 return step_avoid_var_name;
1514}
1515
1516const ConstString &
1517ThreadInstanceSettings::GetTraceThreadVarName ()
1518{
1519 static ConstString trace_thread_var_name ("trace-thread");
1520
1521 return trace_thread_var_name;
1522}
1523
1524//--------------------------------------------------
Greg Clayton990de7b2010-11-18 23:32:35 +00001525// SettingsController Variable Tables
Jim Ingham745ac7a2010-11-11 19:26:09 +00001526//--------------------------------------------------
1527
1528SettingEntry
Greg Clayton990de7b2010-11-18 23:32:35 +00001529Thread::SettingsController::global_settings_table[] =
Jim Ingham745ac7a2010-11-11 19:26:09 +00001530{
1531 //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"},
1532 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1533};
1534
1535
1536SettingEntry
Greg Clayton990de7b2010-11-18 23:32:35 +00001537Thread::SettingsController::instance_settings_table[] =
Jim Ingham745ac7a2010-11-11 19:26:09 +00001538{
1539 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
1540 { "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." },
1541 { "trace-thread", eSetVarTypeBoolean, "false", NULL, false, false, "If true, this thread will single-step and log execution." },
1542 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1543};