blob: 0a6cc828329eebe366b408f6662bb912dac41183 [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"
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "lldb/Core/Log.h"
13#include "lldb/Core/Stream.h"
14#include "lldb/Core/StreamString.h"
15#include "lldb/Host/Host.h"
16#include "lldb/Target/DynamicLoader.h"
17#include "lldb/Target/ExecutionContext.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000020#include "lldb/Target/StopInfo.h"
Greg Clayton7661a982010-07-23 16:45:51 +000021#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Target/Thread.h"
23#include "lldb/Target/ThreadPlan.h"
24#include "lldb/Target/ThreadPlanCallFunction.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Target/ThreadPlanBase.h"
26#include "lldb/Target/ThreadPlanStepInstruction.h"
27#include "lldb/Target/ThreadPlanStepOut.h"
28#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
29#include "lldb/Target/ThreadPlanStepThrough.h"
30#include "lldb/Target/ThreadPlanStepInRange.h"
31#include "lldb/Target/ThreadPlanStepOverRange.h"
32#include "lldb/Target/ThreadPlanRunToAddress.h"
33#include "lldb/Target/ThreadPlanStepUntil.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000034#include "lldb/Target/ThreadSpec.h"
Jim Ingham71219082010-08-12 02:14:28 +000035#include "lldb/Target/Unwind.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
40Thread::Thread (Process &process, lldb::tid_t tid) :
41 UserID (tid),
Benjamin Kramer36a08102010-07-16 12:32:33 +000042 m_process (process),
Greg Clayton643ee732010-08-04 01:40:35 +000043 m_public_stop_info_sp (),
44 m_actual_stop_info_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000045 m_index_id (process.GetNextThreadIndexID ()),
46 m_reg_context_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000047 m_state (eStateUnloaded),
48 m_plan_stack (),
49 m_immediate_plan_stack(),
50 m_completed_plan_stack(),
51 m_state_mutex (Mutex::eMutexTypeRecursive),
Greg Clayton33ed1702010-08-24 00:45:41 +000052 m_concrete_frames (),
53 m_inlined_frames (),
54 m_inlined_frame_info (),
55 m_show_inlined_frames (true),
Chris Lattner24943d22010-06-08 16:52:24 +000056 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
Jim Ingham71219082010-08-12 02:14:28 +000057 m_resume_state (eStateRunning),
58 m_unwinder_ap ()
59
Chris Lattner24943d22010-06-08 16:52:24 +000060{
61 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
62 if (log)
63 log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
64
65 QueueFundamentalPlan(true);
66}
67
68
69Thread::~Thread()
70{
71 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
72 if (log)
73 log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
74}
75
76int
77Thread::GetResumeSignal () const
78{
79 return m_resume_signal;
80}
81
82void
83Thread::SetResumeSignal (int signal)
84{
85 m_resume_signal = signal;
86}
87
88StateType
89Thread::GetResumeState () const
90{
91 return m_resume_state;
92}
93
94void
95Thread::SetResumeState (StateType state)
96{
97 m_resume_state = state;
98}
99
Greg Clayton643ee732010-08-04 01:40:35 +0000100StopInfo *
101Thread::GetStopInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000102{
Greg Clayton643ee732010-08-04 01:40:35 +0000103 if (m_public_stop_info_sp.get() == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000104 {
Greg Clayton643ee732010-08-04 01:40:35 +0000105 ThreadPlanSP plan_sp (GetCompletedPlan());
106 if (plan_sp)
107 m_public_stop_info_sp = StopInfo::CreateStopReasonWithPlan (plan_sp);
108 else
109 m_public_stop_info_sp = GetPrivateStopReason ();
Chris Lattner24943d22010-06-08 16:52:24 +0000110 }
Greg Clayton643ee732010-08-04 01:40:35 +0000111 return m_public_stop_info_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000112}
113
114bool
115Thread::ThreadStoppedForAReason (void)
116{
Greg Clayton643ee732010-08-04 01:40:35 +0000117 return GetPrivateStopReason () != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000118}
119
120StateType
121Thread::GetState() const
122{
123 // If any other threads access this we will need a mutex for it
124 Mutex::Locker locker(m_state_mutex);
125 return m_state;
126}
127
128void
129Thread::SetState(StateType state)
130{
131 Mutex::Locker locker(m_state_mutex);
132 m_state = state;
133}
134
135void
136Thread::WillStop()
137{
138 ThreadPlan *current_plan = GetCurrentPlan();
139
140 // FIXME: I may decide to disallow threads with no plans. In which
141 // case this should go to an assert.
142
143 if (!current_plan)
144 return;
145
146 current_plan->WillStop();
147}
148
149void
150Thread::SetupForResume ()
151{
152 if (GetResumeState() != eStateSuspended)
153 {
154
155 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
156 // telling the current plan it will resume, since we might change what the current
157 // plan is.
158
159 lldb::addr_t pc = GetRegisterContext()->GetPC();
160 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
161 if (bp_site_sp && bp_site_sp->IsEnabled())
162 {
163 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
164 // special to step over a breakpoint.
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000165
166 ThreadPlan *cur_plan = GetCurrentPlan();
Chris Lattner24943d22010-06-08 16:52:24 +0000167
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000168 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
169 {
170 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
171 if (step_bp_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000172 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000173 ThreadPlanSP step_bp_plan_sp;
174 step_bp_plan->SetPrivate (true);
175
Chris Lattner24943d22010-06-08 16:52:24 +0000176 if (GetCurrentPlan()->RunState() != eStateStepping)
177 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000178 step_bp_plan->SetAutoContinue(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000179 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000180 step_bp_plan_sp.reset (step_bp_plan);
Chris Lattner24943d22010-06-08 16:52:24 +0000181 QueueThreadPlan (step_bp_plan_sp, false);
182 }
183 }
184 }
185 }
186}
187
188bool
189Thread::WillResume (StateType resume_state)
190{
191 // At this point clear the completed plan stack.
192 m_completed_plan_stack.clear();
193 m_discarded_plan_stack.clear();
194
Greg Clayton643ee732010-08-04 01:40:35 +0000195 StopInfo *stop_info = GetPrivateStopReason().get();
196 if (stop_info)
197 stop_info->WillResume (resume_state);
Chris Lattner24943d22010-06-08 16:52:24 +0000198
199 // Tell all the plans that we are about to resume in case they need to clear any state.
200 // We distinguish between the plan on the top of the stack and the lower
201 // plans in case a plan needs to do any special business before it runs.
202
203 ThreadPlan *plan_ptr = GetCurrentPlan();
204 plan_ptr->WillResume(resume_state, true);
205
206 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
207 {
208 plan_ptr->WillResume (resume_state, false);
209 }
Greg Clayton643ee732010-08-04 01:40:35 +0000210
211 m_public_stop_info_sp.reset();
212 m_actual_stop_info_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000213 return true;
214}
215
216void
217Thread::DidResume ()
218{
219 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
220}
221
222bool
223Thread::ShouldStop (Event* event_ptr)
224{
225 ThreadPlan *current_plan = GetCurrentPlan();
226 bool should_stop = true;
227
228 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
229 if (log)
230 {
231 StreamString s;
232 DumpThreadPlans(&s);
233 log->PutCString (s.GetData());
234 }
235
236 if (current_plan->PlanExplainsStop())
237 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000238 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000239 while (1)
240 {
241 should_stop = current_plan->ShouldStop(event_ptr);
242 if (current_plan->MischiefManaged())
243 {
244 if (should_stop)
245 current_plan->WillStop();
246
247 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
248 // Otherwise, see if the plan's parent wants to stop.
249
250 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
251 {
252 PopPlan();
253 break;
254 }
255 else
256 {
257
258 PopPlan();
259
260 current_plan = GetCurrentPlan();
261 if (current_plan == NULL)
262 {
263 break;
264 }
265 }
266
267 }
268 else
269 {
270 break;
271 }
272 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000273 if (over_ride_stop)
274 should_stop = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000275 }
276 else
277 {
278 // If the current plan doesn't explain the stop, then, find one that
279 // does and let it handle the situation.
280 ThreadPlan *plan_ptr = current_plan;
281 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
282 {
283 if (plan_ptr->PlanExplainsStop())
284 {
285 should_stop = plan_ptr->ShouldStop (event_ptr);
286 break;
287 }
288
289 }
290 }
291
292 return should_stop;
293}
294
295Vote
296Thread::ShouldReportStop (Event* event_ptr)
297{
298 StateType thread_state = GetResumeState ();
299 if (thread_state == eStateSuspended
300 || thread_state == eStateInvalid)
301 return eVoteNoOpinion;
302
303 if (m_completed_plan_stack.size() > 0)
304 {
305 // Don't use GetCompletedPlan here, since that suppresses private plans.
306 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
307 }
308 else
309 return GetCurrentPlan()->ShouldReportStop (event_ptr);
310}
311
312Vote
313Thread::ShouldReportRun (Event* event_ptr)
314{
315 StateType thread_state = GetResumeState ();
316 if (thread_state == eStateSuspended
317 || thread_state == eStateInvalid)
318 return eVoteNoOpinion;
319
320 if (m_completed_plan_stack.size() > 0)
321 {
322 // Don't use GetCompletedPlan here, since that suppresses private plans.
323 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
324 }
325 else
326 return GetCurrentPlan()->ShouldReportRun (event_ptr);
327}
328
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000329bool
330Thread::MatchesSpec (const ThreadSpec *spec)
331{
332 if (spec == NULL)
333 return true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000334
Jim Ingham649492b2010-06-18 01:00:58 +0000335 return spec->ThreadPassesBasicTests(this);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000336}
337
Chris Lattner24943d22010-06-08 16:52:24 +0000338void
339Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
340{
341 if (thread_plan_sp)
342 {
343 if (thread_plan_sp->IsImmediate())
344 m_immediate_plan_stack.push_back (thread_plan_sp);
345 else
346 m_plan_stack.push_back (thread_plan_sp);
347
348 thread_plan_sp->DidPush();
349
350 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
351 if (log)
352 {
353 StreamString s;
354 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
355 log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.",
356 s.GetData(),
357 thread_plan_sp->GetThread().GetID(),
358 thread_plan_sp->IsImmediate() ? "true" : "false");
359 }
360 }
361}
362
363void
364Thread::PopPlan ()
365{
366 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
367
368 if (!m_immediate_plan_stack.empty())
369 {
370 ThreadPlanSP &plan = m_immediate_plan_stack.back();
371 if (log)
372 {
373 log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID());
374 }
375 plan->WillPop();
376 m_immediate_plan_stack.pop_back();
377 }
378 else if (m_plan_stack.empty())
379 return;
380 else
381 {
382 ThreadPlanSP &plan = m_plan_stack.back();
383 if (log)
384 {
385 log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID());
386 }
387 m_completed_plan_stack.push_back (plan);
388 plan->WillPop();
389 m_plan_stack.pop_back();
390 }
391}
392
393void
394Thread::DiscardPlan ()
395{
396 if (m_plan_stack.size() > 1)
397 {
398 ThreadPlanSP &plan = m_plan_stack.back();
399 m_discarded_plan_stack.push_back (plan);
400 plan->WillPop();
401 m_plan_stack.pop_back();
402 }
403}
404
405ThreadPlan *
406Thread::GetCurrentPlan ()
407{
408 if (!m_immediate_plan_stack.empty())
409 return m_immediate_plan_stack.back().get();
410 else if (m_plan_stack.empty())
411 return NULL;
412 else
413 return m_plan_stack.back().get();
414}
415
416ThreadPlanSP
417Thread::GetCompletedPlan ()
418{
419 ThreadPlanSP empty_plan_sp;
420 if (!m_completed_plan_stack.empty())
421 {
422 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
423 {
424 ThreadPlanSP completed_plan_sp;
425 completed_plan_sp = m_completed_plan_stack[i];
426 if (!completed_plan_sp->GetPrivate ())
427 return completed_plan_sp;
428 }
429 }
430 return empty_plan_sp;
431}
432
433bool
434Thread::IsThreadPlanDone (ThreadPlan *plan)
435{
436 ThreadPlanSP empty_plan_sp;
437 if (!m_completed_plan_stack.empty())
438 {
439 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
440 {
441 if (m_completed_plan_stack[i].get() == plan)
442 return true;
443 }
444 }
445 return false;
446}
447
448bool
449Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
450{
451 ThreadPlanSP empty_plan_sp;
452 if (!m_discarded_plan_stack.empty())
453 {
454 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
455 {
456 if (m_discarded_plan_stack[i].get() == plan)
457 return true;
458 }
459 }
460 return false;
461}
462
463ThreadPlan *
464Thread::GetPreviousPlan (ThreadPlan *current_plan)
465{
466 if (current_plan == NULL)
467 return NULL;
468
469 int stack_size = m_completed_plan_stack.size();
470 for (int i = stack_size - 1; i > 0; i--)
471 {
472 if (current_plan == m_completed_plan_stack[i].get())
473 return m_completed_plan_stack[i-1].get();
474 }
475
476 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
477 {
478 if (m_immediate_plan_stack.size() > 0)
479 return m_immediate_plan_stack.back().get();
480 else if (m_plan_stack.size() > 0)
481 return m_plan_stack.back().get();
482 else
483 return NULL;
484 }
485
486 stack_size = m_immediate_plan_stack.size();
487 for (int i = stack_size - 1; i > 0; i--)
488 {
489 if (current_plan == m_immediate_plan_stack[i].get())
490 return m_immediate_plan_stack[i-1].get();
491 }
492 if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
493 {
494 if (m_plan_stack.size() > 0)
495 return m_plan_stack.back().get();
496 else
497 return NULL;
498 }
499
500 stack_size = m_plan_stack.size();
501 for (int i = stack_size - 1; i > 0; i--)
502 {
503 if (current_plan == m_plan_stack[i].get())
504 return m_plan_stack[i-1].get();
505 }
506 return NULL;
507}
508
509void
510Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
511{
512 if (abort_other_plans)
513 DiscardThreadPlans(true);
514
515 PushPlan (thread_plan_sp);
516}
517
518void
519Thread::DiscardThreadPlans(bool force)
520{
521 // FIXME: It is not always safe to just discard plans. Some, like the step over
522 // breakpoint trap can't be discarded in general (though you can if you plan to
523 // force a return from a function, for instance.
524 // For now I'm just not clearing immediate plans, but I need a way for plans to
525 // say they really need to be kept on, and then a way to override that. Humm...
526
527 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
528 if (log)
529 {
530 log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force);
531 }
532
533 if (force)
534 {
535 int stack_size = m_plan_stack.size();
536 for (int i = stack_size - 1; i > 0; i--)
537 {
538 DiscardPlan();
539 }
540 return;
541 }
542
543 while (1)
544 {
545
546 int master_plan_idx;
547 bool discard;
548
549 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
550 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
551 {
552 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
553 {
554 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
555 break;
556 }
557 }
558
559 if (discard)
560 {
561 // First pop all the dependent plans:
562 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
563 {
564
565 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
566 // for the plan leaves it in a state that it is safe to pop the plan
567 // with no more notice?
568 DiscardPlan();
569 }
570
571 // Now discard the master plan itself.
572 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
573 // discard it's dependent plans, but not it...
574 if (master_plan_idx > 0)
575 {
576 DiscardPlan();
577 }
578 }
579 else
580 {
581 // If the master plan doesn't want to get discarded, then we're done.
582 break;
583 }
584
585 }
586 // FIXME: What should we do about the immediate plans?
587}
588
589ThreadPlan *
590Thread::QueueFundamentalPlan (bool abort_other_plans)
591{
592 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
593 QueueThreadPlan (thread_plan_sp, abort_other_plans);
594 return thread_plan_sp.get();
595}
596
597ThreadPlan *
598Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
599{
600 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
601 QueueThreadPlan (thread_plan_sp, abort_other_plans);
602 return thread_plan_sp.get();
603}
604
605ThreadPlan *
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000606Thread::QueueThreadPlanForStepRange
607(
608 bool abort_other_plans,
609 StepType type,
610 const AddressRange &range,
611 const SymbolContext &addr_context,
612 lldb::RunMode stop_other_threads,
613 bool avoid_code_without_debug_info
614)
Chris Lattner24943d22010-06-08 16:52:24 +0000615{
616 ThreadPlanSP thread_plan_sp;
617 if (type == eStepTypeInto)
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000618 {
619 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
620 if (avoid_code_without_debug_info)
621 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
622 else
623 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
624 thread_plan_sp.reset (plan);
625 }
Chris Lattner24943d22010-06-08 16:52:24 +0000626 else
627 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
628
629 QueueThreadPlan (thread_plan_sp, abort_other_plans);
630 return thread_plan_sp.get();
631}
632
633
634ThreadPlan *
635Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
636{
637 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
638 QueueThreadPlan (thread_plan_sp, abort_other_plans);
639 return thread_plan_sp.get();
640}
641
642ThreadPlan *
643Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
644 bool stop_other_threads, Vote stop_vote, Vote run_vote)
645{
646 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
647 QueueThreadPlan (thread_plan_sp, abort_other_plans);
648 return thread_plan_sp.get();
649}
650
651ThreadPlan *
652Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
653{
654 ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
655 if (thread_plan_sp.get() == NULL)
656 {
657 thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
658 if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
Greg Claytonf8e98a62010-07-23 15:37:46 +0000659 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000660 }
661 QueueThreadPlan (thread_plan_sp, abort_other_plans);
662 return thread_plan_sp.get();
663}
664
665ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +0000666Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
667 Address& function,
668 lldb::addr_t arg,
669 bool stop_other_threads,
670 bool discard_on_error)
671{
672 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
673 QueueThreadPlan (thread_plan_sp, abort_other_plans);
674 return thread_plan_sp.get();
675}
676
677ThreadPlan *
678Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
679 Address& function,
680 ValueList &args,
681 bool stop_other_threads,
682 bool discard_on_error)
683{
684 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
685 QueueThreadPlan (thread_plan_sp, abort_other_plans);
686 return thread_plan_sp.get();
687}
688
689ThreadPlan *
690Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
691 Address &target_addr,
692 bool stop_other_threads)
693{
694 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
695 QueueThreadPlan (thread_plan_sp, abort_other_plans);
696 return thread_plan_sp.get();
697}
698
699ThreadPlan *
700Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
701 lldb::addr_t *address_list,
702 size_t num_addresses,
703 bool stop_other_threads)
704{
705 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
706 QueueThreadPlan (thread_plan_sp, abort_other_plans);
707 return thread_plan_sp.get();
708
709}
710
711uint32_t
712Thread::GetIndexID () const
713{
714 return m_index_id;
715}
716
717void
718Thread::DumpThreadPlans (lldb_private::Stream *s) const
719{
720 uint32_t stack_size = m_plan_stack.size();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000721 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x - %d elements.\n", GetIndexID(), GetID(), stack_size);
Chris Lattner24943d22010-06-08 16:52:24 +0000722 for (int i = stack_size - 1; i > 0; i--)
723 {
724 s->Printf ("Element %d: ", i);
725 s->IndentMore();
726 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
727 s->IndentLess();
728 s->EOL();
729 }
730
731 stack_size = m_immediate_plan_stack.size();
732 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
733 for (int i = stack_size - 1; i > 0; i--)
734 {
735 s->Printf ("Element %d: ", i);
736 s->IndentMore();
737 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
738 s->IndentLess();
739 s->EOL();
740 }
741
742 stack_size = m_completed_plan_stack.size();
743 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
744 for (int i = stack_size - 1; i > 0; i--)
745 {
746 s->Printf ("Element %d: ", i);
747 s->IndentMore();
748 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
749 s->IndentLess();
750 s->EOL();
751 }
752
753 stack_size = m_discarded_plan_stack.size();
754 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
755 for (int i = stack_size - 1; i > 0; i--)
756 {
757 s->Printf ("Element %d: ", i);
758 s->IndentMore();
759 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
760 s->IndentLess();
761 s->EOL();
762 }
763
764}
765
766Target *
767Thread::CalculateTarget ()
768{
769 return m_process.CalculateTarget();
770}
771
772Process *
773Thread::CalculateProcess ()
774{
775 return &m_process;
776}
777
778Thread *
779Thread::CalculateThread ()
780{
781 return this;
782}
783
784StackFrame *
785Thread::CalculateStackFrame ()
786{
787 return NULL;
788}
789
790void
791Thread::Calculate (ExecutionContext &exe_ctx)
792{
793 m_process.Calculate (exe_ctx);
794 exe_ctx.thread = this;
795 exe_ctx.frame = NULL;
796}
797
Jim Ingham71219082010-08-12 02:14:28 +0000798uint32_t
799Thread::GetStackFrameCount()
800{
801 Unwind *unwinder = GetUnwinder ();
802 if (unwinder)
Greg Clayton33ed1702010-08-24 00:45:41 +0000803 {
804 if (m_show_inlined_frames)
805 {
806 if (m_inlined_frame_info.empty())
807 {
808 // If we are going to show inlined stack frames as actual frames,
809 // we need to calculate all concrete frames first, then iterate
810 // through all of them and count up how many inlined functions are
811 // in each frame. We can then fill in m_inlined_frame_info with
812 // the concrete frame index and inlined depth
813 const uint32_t concrete_frame_count = unwinder->GetFrameCount();
814
815 addr_t pc, cfa;
816 InlinedFrameInfo inlined_frame_info;
817
818 StackFrameSP frame_sp;
819 for (uint32_t idx=0; idx<concrete_frame_count; ++idx)
820 {
821 if (idx == 0)
822 {
823 GetRegisterContext();
824 assert (m_reg_context_sp.get());
825 frame_sp.reset (new StackFrame (0, 0, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), 0, m_reg_context_sp->GetPC(), NULL));
826 }
827 else
828 {
829 const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
830 assert (success);
831 frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, *this, cfa, 0, pc, NULL));
832 }
833 m_concrete_frames.SetFrameAtIndex(idx, frame_sp);
834 Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block;
835
836 inlined_frame_info.concrete_frame_index = idx;
837 inlined_frame_info.inline_height = 0;
838 inlined_frame_info.block = block;
839 m_inlined_frame_info.push_back (inlined_frame_info);
840
841 if (block)
842 {
843 Block *inlined_block;
844 if (block->InlinedFunctionInfo())
845 inlined_block = block;
846 else
847 inlined_block = block->GetInlinedParent ();
848
849 while (inlined_block)
850 {
851 inlined_frame_info.block = inlined_block;
852 inlined_frame_info.inline_height++;
853 m_inlined_frame_info.push_back (inlined_frame_info);
854 inlined_block = inlined_block->GetInlinedParent ();
855 }
856 }
857 }
858 }
859 return m_inlined_frame_info.size();
860 }
861 else
862 {
863 return unwinder->GetFrameCount();
864 }
865 }
Jim Ingham71219082010-08-12 02:14:28 +0000866 return 0;
867}
868
869lldb::StackFrameSP
870Thread::GetStackFrameAtIndex (uint32_t idx)
871{
872
Greg Clayton33ed1702010-08-24 00:45:41 +0000873 StackFrameSP frame_sp;
874
875 if (m_show_inlined_frames)
876 frame_sp = m_inlined_frames.GetFrameAtIndex(idx);
877 else
878 frame_sp = m_concrete_frames.GetFrameAtIndex(idx);
Jim Ingham71219082010-08-12 02:14:28 +0000879
880 if (frame_sp.get())
881 return frame_sp;
882
883 // Don't try and fetch a frame while process is running
884// FIXME: This check isn't right because IsRunning checks the Public state, but this
885// is work you need to do - for instance in ShouldStop & friends - before the public
886// state has been changed.
887// if (m_process.IsRunning())
888// return frame_sp;
889
890 // Special case the first frame (idx == 0) so that we don't need to
891 // know how many stack frames there are to get it. If we need any other
892 // frames, then we do need to know if "idx" is a valid index.
893 if (idx == 0)
894 {
895 // If this is the first frame, we want to share the thread register
896 // context with the stack frame at index zero.
897 GetRegisterContext();
898 assert (m_reg_context_sp.get());
Greg Clayton33ed1702010-08-24 00:45:41 +0000899 frame_sp.reset (new StackFrame (0, 0, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), 0, m_reg_context_sp->GetPC(), NULL));
Jim Ingham71219082010-08-12 02:14:28 +0000900 }
901 else if (idx < GetStackFrameCount())
902 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000903 if (m_show_inlined_frames)
Jim Ingham71219082010-08-12 02:14:28 +0000904 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000905 if (m_inlined_frame_info[idx].inline_height == 0)
906 {
907 // Same as the concrete stack frame if block is NULL
908 frame_sp = m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index);
909 }
910 else
911 {
912 // We have blocks that were above an inlined function. Inlined
913 // functions are represented as blocks with non-NULL inline
914 // function info. Here we must reconstruct a frame by looking
915 // at the block
916 StackFrameSP previous_frame_sp (GetStackFrameAtIndex (idx-1));
917
918 SymbolContext inline_sc;
919
920 Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent();
921
922 if (inlined_parent_block)
923 inlined_parent_block->CalculateSymbolContext (&inline_sc);
924 else
925 {
926 Block *parent_block = m_inlined_frame_info[idx].block->GetParent();
927 parent_block->CalculateSymbolContext(&inline_sc);
928 }
929
930 InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo();
931 assert (inline_info);
932 inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetPC();
933 inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
934 inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
935 inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
936
937 StackFrameSP concrete_frame_sp (m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index));
938 assert (previous_frame_sp.get());
939 AddressRange range;
940 m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_sp->GetPC(), range);
941
942 frame_sp.reset (new StackFrame (idx,
943 m_inlined_frame_info[idx].concrete_frame_index,
944 *this,
945 concrete_frame_sp->GetRegisterContextSP (),
946 concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA
947 m_inlined_frame_info[idx].inline_height, // Inline height
948 range.GetBaseAddress(),
949 &inline_sc)); // The symbol context for this inline frame
950
951 }
952
953 }
954 else
955 {
956 Unwind *unwinder = GetUnwinder ();
957 if (unwinder)
958 {
959 addr_t pc, cfa;
960 if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
961 frame_sp.reset (new StackFrame (idx, idx, *this, cfa, 0, pc, NULL));
962 }
Jim Ingham71219082010-08-12 02:14:28 +0000963 }
964 }
Greg Clayton33ed1702010-08-24 00:45:41 +0000965 if (m_show_inlined_frames)
966 m_inlined_frames.SetFrameAtIndex(idx, frame_sp);
967 else
968 m_concrete_frames.SetFrameAtIndex(idx, frame_sp);
Jim Ingham71219082010-08-12 02:14:28 +0000969 return frame_sp;
970}
971
Chris Lattner24943d22010-06-08 16:52:24 +0000972lldb::StackFrameSP
973Thread::GetCurrentFrame ()
974{
Greg Clayton33ed1702010-08-24 00:45:41 +0000975 return GetStackFrameAtIndex (m_concrete_frames.GetCurrentFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000976}
977
978uint32_t
979Thread::SetCurrentFrame (lldb_private::StackFrame *frame)
980{
Greg Clayton33ed1702010-08-24 00:45:41 +0000981 return m_concrete_frames.SetCurrentFrame(frame);
Chris Lattner24943d22010-06-08 16:52:24 +0000982}
983
984void
Greg Clayton33ed1702010-08-24 00:45:41 +0000985Thread::SetCurrentFrameByIndex (uint32_t idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000986{
Greg Clayton33ed1702010-08-24 00:45:41 +0000987 m_concrete_frames.SetCurrentFrameByIndex(idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000988}
989
990void
991Thread::DumpInfo
992(
993 Stream &strm,
994 bool show_stop_reason,
995 bool show_name,
996 bool show_queue,
Greg Clayton33ed1702010-08-24 00:45:41 +0000997 uint32_t idx
Chris Lattner24943d22010-06-08 16:52:24 +0000998)
999{
1000 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
1001
Greg Clayton33ed1702010-08-24 00:45:41 +00001002 if (idx != LLDB_INVALID_INDEX32)
Chris Lattner24943d22010-06-08 16:52:24 +00001003 {
Greg Clayton33ed1702010-08-24 00:45:41 +00001004 StackFrameSP frame_sp(GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +00001005 if (frame_sp)
1006 {
1007 strm.PutCString(", ");
1008 frame_sp->Dump (&strm, false);
1009 }
1010 }
1011
1012 if (show_stop_reason)
1013 {
Greg Clayton643ee732010-08-04 01:40:35 +00001014 StopInfo *stop_info = GetStopInfo();
1015
1016 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +00001017 {
Greg Clayton643ee732010-08-04 01:40:35 +00001018 const char *stop_description = stop_info->GetDescription();
1019 if (stop_description)
1020 strm.Printf (", stop reason = %s", stop_description);
Chris Lattner24943d22010-06-08 16:52:24 +00001021 }
1022 }
1023
1024 if (show_name)
1025 {
1026 const char *name = GetName();
1027 if (name && name[0])
1028 strm.Printf(", name = %s", name);
1029 }
1030
1031 if (show_queue)
1032 {
1033 const char *queue = GetQueueName();
1034 if (queue && queue[0])
1035 strm.Printf(", queue = %s", queue);
1036 }
1037}
1038
1039lldb::ThreadSP
1040Thread::GetSP ()
1041{
1042 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
1043}