blob: efbcad7fa4d3f429febf8cf5363497a39bec158d [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),
52 m_frames (),
53 m_current_frame_idx (0),
54 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
Jim Ingham71219082010-08-12 02:14:28 +000055 m_resume_state (eStateRunning),
56 m_unwinder_ap ()
57
Chris Lattner24943d22010-06-08 16:52:24 +000058{
59 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
60 if (log)
61 log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
62
63 QueueFundamentalPlan(true);
64}
65
66
67Thread::~Thread()
68{
69 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
70 if (log)
71 log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
72}
73
74int
75Thread::GetResumeSignal () const
76{
77 return m_resume_signal;
78}
79
80void
81Thread::SetResumeSignal (int signal)
82{
83 m_resume_signal = signal;
84}
85
86StateType
87Thread::GetResumeState () const
88{
89 return m_resume_state;
90}
91
92void
93Thread::SetResumeState (StateType state)
94{
95 m_resume_state = state;
96}
97
Greg Clayton643ee732010-08-04 01:40:35 +000098StopInfo *
99Thread::GetStopInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000100{
Greg Clayton643ee732010-08-04 01:40:35 +0000101 if (m_public_stop_info_sp.get() == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000102 {
Greg Clayton643ee732010-08-04 01:40:35 +0000103 ThreadPlanSP plan_sp (GetCompletedPlan());
104 if (plan_sp)
105 m_public_stop_info_sp = StopInfo::CreateStopReasonWithPlan (plan_sp);
106 else
107 m_public_stop_info_sp = GetPrivateStopReason ();
Chris Lattner24943d22010-06-08 16:52:24 +0000108 }
Greg Clayton643ee732010-08-04 01:40:35 +0000109 return m_public_stop_info_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000110}
111
112bool
113Thread::ThreadStoppedForAReason (void)
114{
Greg Clayton643ee732010-08-04 01:40:35 +0000115 return GetPrivateStopReason () != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000116}
117
118StateType
119Thread::GetState() const
120{
121 // If any other threads access this we will need a mutex for it
122 Mutex::Locker locker(m_state_mutex);
123 return m_state;
124}
125
126void
127Thread::SetState(StateType state)
128{
129 Mutex::Locker locker(m_state_mutex);
130 m_state = state;
131}
132
133void
134Thread::WillStop()
135{
136 ThreadPlan *current_plan = GetCurrentPlan();
137
138 // FIXME: I may decide to disallow threads with no plans. In which
139 // case this should go to an assert.
140
141 if (!current_plan)
142 return;
143
144 current_plan->WillStop();
145}
146
147void
148Thread::SetupForResume ()
149{
150 if (GetResumeState() != eStateSuspended)
151 {
152
153 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
154 // telling the current plan it will resume, since we might change what the current
155 // plan is.
156
157 lldb::addr_t pc = GetRegisterContext()->GetPC();
158 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
159 if (bp_site_sp && bp_site_sp->IsEnabled())
160 {
161 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
162 // special to step over a breakpoint.
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000163
164 ThreadPlan *cur_plan = GetCurrentPlan();
Chris Lattner24943d22010-06-08 16:52:24 +0000165
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000166 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
167 {
168 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
169 if (step_bp_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000170 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000171 ThreadPlanSP step_bp_plan_sp;
172 step_bp_plan->SetPrivate (true);
173
Chris Lattner24943d22010-06-08 16:52:24 +0000174 if (GetCurrentPlan()->RunState() != eStateStepping)
175 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000176 step_bp_plan->SetAutoContinue(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000177 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000178 step_bp_plan_sp.reset (step_bp_plan);
Chris Lattner24943d22010-06-08 16:52:24 +0000179 QueueThreadPlan (step_bp_plan_sp, false);
180 }
181 }
182 }
183 }
184}
185
186bool
187Thread::WillResume (StateType resume_state)
188{
189 // At this point clear the completed plan stack.
190 m_completed_plan_stack.clear();
191 m_discarded_plan_stack.clear();
192
Greg Clayton643ee732010-08-04 01:40:35 +0000193 StopInfo *stop_info = GetPrivateStopReason().get();
194 if (stop_info)
195 stop_info->WillResume (resume_state);
Chris Lattner24943d22010-06-08 16:52:24 +0000196
197 // Tell all the plans that we are about to resume in case they need to clear any state.
198 // We distinguish between the plan on the top of the stack and the lower
199 // plans in case a plan needs to do any special business before it runs.
200
201 ThreadPlan *plan_ptr = GetCurrentPlan();
202 plan_ptr->WillResume(resume_state, true);
203
204 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
205 {
206 plan_ptr->WillResume (resume_state, false);
207 }
Greg Clayton643ee732010-08-04 01:40:35 +0000208
209 m_public_stop_info_sp.reset();
210 m_actual_stop_info_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000211 return true;
212}
213
214void
215Thread::DidResume ()
216{
217 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
218}
219
220bool
221Thread::ShouldStop (Event* event_ptr)
222{
223 ThreadPlan *current_plan = GetCurrentPlan();
224 bool should_stop = true;
225
226 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
227 if (log)
228 {
229 StreamString s;
230 DumpThreadPlans(&s);
231 log->PutCString (s.GetData());
232 }
233
234 if (current_plan->PlanExplainsStop())
235 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000236 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000237 while (1)
238 {
239 should_stop = current_plan->ShouldStop(event_ptr);
240 if (current_plan->MischiefManaged())
241 {
242 if (should_stop)
243 current_plan->WillStop();
244
245 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
246 // Otherwise, see if the plan's parent wants to stop.
247
248 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
249 {
250 PopPlan();
251 break;
252 }
253 else
254 {
255
256 PopPlan();
257
258 current_plan = GetCurrentPlan();
259 if (current_plan == NULL)
260 {
261 break;
262 }
263 }
264
265 }
266 else
267 {
268 break;
269 }
270 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000271 if (over_ride_stop)
272 should_stop = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000273 }
274 else
275 {
276 // If the current plan doesn't explain the stop, then, find one that
277 // does and let it handle the situation.
278 ThreadPlan *plan_ptr = current_plan;
279 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
280 {
281 if (plan_ptr->PlanExplainsStop())
282 {
283 should_stop = plan_ptr->ShouldStop (event_ptr);
284 break;
285 }
286
287 }
288 }
289
290 return should_stop;
291}
292
293Vote
294Thread::ShouldReportStop (Event* event_ptr)
295{
296 StateType thread_state = GetResumeState ();
297 if (thread_state == eStateSuspended
298 || thread_state == eStateInvalid)
299 return eVoteNoOpinion;
300
301 if (m_completed_plan_stack.size() > 0)
302 {
303 // Don't use GetCompletedPlan here, since that suppresses private plans.
304 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
305 }
306 else
307 return GetCurrentPlan()->ShouldReportStop (event_ptr);
308}
309
310Vote
311Thread::ShouldReportRun (Event* event_ptr)
312{
313 StateType thread_state = GetResumeState ();
314 if (thread_state == eStateSuspended
315 || thread_state == eStateInvalid)
316 return eVoteNoOpinion;
317
318 if (m_completed_plan_stack.size() > 0)
319 {
320 // Don't use GetCompletedPlan here, since that suppresses private plans.
321 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
322 }
323 else
324 return GetCurrentPlan()->ShouldReportRun (event_ptr);
325}
326
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000327bool
328Thread::MatchesSpec (const ThreadSpec *spec)
329{
330 if (spec == NULL)
331 return true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000332
Jim Ingham649492b2010-06-18 01:00:58 +0000333 return spec->ThreadPassesBasicTests(this);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000334}
335
Chris Lattner24943d22010-06-08 16:52:24 +0000336void
337Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
338{
339 if (thread_plan_sp)
340 {
341 if (thread_plan_sp->IsImmediate())
342 m_immediate_plan_stack.push_back (thread_plan_sp);
343 else
344 m_plan_stack.push_back (thread_plan_sp);
345
346 thread_plan_sp->DidPush();
347
348 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
349 if (log)
350 {
351 StreamString s;
352 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
353 log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.",
354 s.GetData(),
355 thread_plan_sp->GetThread().GetID(),
356 thread_plan_sp->IsImmediate() ? "true" : "false");
357 }
358 }
359}
360
361void
362Thread::PopPlan ()
363{
364 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
365
366 if (!m_immediate_plan_stack.empty())
367 {
368 ThreadPlanSP &plan = m_immediate_plan_stack.back();
369 if (log)
370 {
371 log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID());
372 }
373 plan->WillPop();
374 m_immediate_plan_stack.pop_back();
375 }
376 else if (m_plan_stack.empty())
377 return;
378 else
379 {
380 ThreadPlanSP &plan = m_plan_stack.back();
381 if (log)
382 {
383 log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID());
384 }
385 m_completed_plan_stack.push_back (plan);
386 plan->WillPop();
387 m_plan_stack.pop_back();
388 }
389}
390
391void
392Thread::DiscardPlan ()
393{
394 if (m_plan_stack.size() > 1)
395 {
396 ThreadPlanSP &plan = m_plan_stack.back();
397 m_discarded_plan_stack.push_back (plan);
398 plan->WillPop();
399 m_plan_stack.pop_back();
400 }
401}
402
403ThreadPlan *
404Thread::GetCurrentPlan ()
405{
406 if (!m_immediate_plan_stack.empty())
407 return m_immediate_plan_stack.back().get();
408 else if (m_plan_stack.empty())
409 return NULL;
410 else
411 return m_plan_stack.back().get();
412}
413
414ThreadPlanSP
415Thread::GetCompletedPlan ()
416{
417 ThreadPlanSP empty_plan_sp;
418 if (!m_completed_plan_stack.empty())
419 {
420 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
421 {
422 ThreadPlanSP completed_plan_sp;
423 completed_plan_sp = m_completed_plan_stack[i];
424 if (!completed_plan_sp->GetPrivate ())
425 return completed_plan_sp;
426 }
427 }
428 return empty_plan_sp;
429}
430
431bool
432Thread::IsThreadPlanDone (ThreadPlan *plan)
433{
434 ThreadPlanSP empty_plan_sp;
435 if (!m_completed_plan_stack.empty())
436 {
437 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
438 {
439 if (m_completed_plan_stack[i].get() == plan)
440 return true;
441 }
442 }
443 return false;
444}
445
446bool
447Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
448{
449 ThreadPlanSP empty_plan_sp;
450 if (!m_discarded_plan_stack.empty())
451 {
452 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
453 {
454 if (m_discarded_plan_stack[i].get() == plan)
455 return true;
456 }
457 }
458 return false;
459}
460
461ThreadPlan *
462Thread::GetPreviousPlan (ThreadPlan *current_plan)
463{
464 if (current_plan == NULL)
465 return NULL;
466
467 int stack_size = m_completed_plan_stack.size();
468 for (int i = stack_size - 1; i > 0; i--)
469 {
470 if (current_plan == m_completed_plan_stack[i].get())
471 return m_completed_plan_stack[i-1].get();
472 }
473
474 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
475 {
476 if (m_immediate_plan_stack.size() > 0)
477 return m_immediate_plan_stack.back().get();
478 else if (m_plan_stack.size() > 0)
479 return m_plan_stack.back().get();
480 else
481 return NULL;
482 }
483
484 stack_size = m_immediate_plan_stack.size();
485 for (int i = stack_size - 1; i > 0; i--)
486 {
487 if (current_plan == m_immediate_plan_stack[i].get())
488 return m_immediate_plan_stack[i-1].get();
489 }
490 if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
491 {
492 if (m_plan_stack.size() > 0)
493 return m_plan_stack.back().get();
494 else
495 return NULL;
496 }
497
498 stack_size = m_plan_stack.size();
499 for (int i = stack_size - 1; i > 0; i--)
500 {
501 if (current_plan == m_plan_stack[i].get())
502 return m_plan_stack[i-1].get();
503 }
504 return NULL;
505}
506
507void
508Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
509{
510 if (abort_other_plans)
511 DiscardThreadPlans(true);
512
513 PushPlan (thread_plan_sp);
514}
515
516void
517Thread::DiscardThreadPlans(bool force)
518{
519 // FIXME: It is not always safe to just discard plans. Some, like the step over
520 // breakpoint trap can't be discarded in general (though you can if you plan to
521 // force a return from a function, for instance.
522 // For now I'm just not clearing immediate plans, but I need a way for plans to
523 // say they really need to be kept on, and then a way to override that. Humm...
524
525 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
526 if (log)
527 {
528 log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force);
529 }
530
531 if (force)
532 {
533 int stack_size = m_plan_stack.size();
534 for (int i = stack_size - 1; i > 0; i--)
535 {
536 DiscardPlan();
537 }
538 return;
539 }
540
541 while (1)
542 {
543
544 int master_plan_idx;
545 bool discard;
546
547 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
548 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
549 {
550 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
551 {
552 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
553 break;
554 }
555 }
556
557 if (discard)
558 {
559 // First pop all the dependent plans:
560 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
561 {
562
563 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
564 // for the plan leaves it in a state that it is safe to pop the plan
565 // with no more notice?
566 DiscardPlan();
567 }
568
569 // Now discard the master plan itself.
570 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
571 // discard it's dependent plans, but not it...
572 if (master_plan_idx > 0)
573 {
574 DiscardPlan();
575 }
576 }
577 else
578 {
579 // If the master plan doesn't want to get discarded, then we're done.
580 break;
581 }
582
583 }
584 // FIXME: What should we do about the immediate plans?
585}
586
587ThreadPlan *
588Thread::QueueFundamentalPlan (bool abort_other_plans)
589{
590 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
591 QueueThreadPlan (thread_plan_sp, abort_other_plans);
592 return thread_plan_sp.get();
593}
594
595ThreadPlan *
596Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
597{
598 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
599 QueueThreadPlan (thread_plan_sp, abort_other_plans);
600 return thread_plan_sp.get();
601}
602
603ThreadPlan *
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000604Thread::QueueThreadPlanForStepRange
605(
606 bool abort_other_plans,
607 StepType type,
608 const AddressRange &range,
609 const SymbolContext &addr_context,
610 lldb::RunMode stop_other_threads,
611 bool avoid_code_without_debug_info
612)
Chris Lattner24943d22010-06-08 16:52:24 +0000613{
614 ThreadPlanSP thread_plan_sp;
615 if (type == eStepTypeInto)
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000616 {
617 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
618 if (avoid_code_without_debug_info)
619 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
620 else
621 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
622 thread_plan_sp.reset (plan);
623 }
Chris Lattner24943d22010-06-08 16:52:24 +0000624 else
625 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
626
627 QueueThreadPlan (thread_plan_sp, abort_other_plans);
628 return thread_plan_sp.get();
629}
630
631
632ThreadPlan *
633Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
634{
635 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
636 QueueThreadPlan (thread_plan_sp, abort_other_plans);
637 return thread_plan_sp.get();
638}
639
640ThreadPlan *
641Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
642 bool stop_other_threads, Vote stop_vote, Vote run_vote)
643{
644 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
645 QueueThreadPlan (thread_plan_sp, abort_other_plans);
646 return thread_plan_sp.get();
647}
648
649ThreadPlan *
650Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
651{
652 ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
653 if (thread_plan_sp.get() == NULL)
654 {
655 thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
656 if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
Greg Claytonf8e98a62010-07-23 15:37:46 +0000657 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000658 }
659 QueueThreadPlan (thread_plan_sp, abort_other_plans);
660 return thread_plan_sp.get();
661}
662
663ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +0000664Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
665 Address& function,
666 lldb::addr_t arg,
667 bool stop_other_threads,
668 bool discard_on_error)
669{
670 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
671 QueueThreadPlan (thread_plan_sp, abort_other_plans);
672 return thread_plan_sp.get();
673}
674
675ThreadPlan *
676Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
677 Address& function,
678 ValueList &args,
679 bool stop_other_threads,
680 bool discard_on_error)
681{
682 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
683 QueueThreadPlan (thread_plan_sp, abort_other_plans);
684 return thread_plan_sp.get();
685}
686
687ThreadPlan *
688Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
689 Address &target_addr,
690 bool stop_other_threads)
691{
692 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
693 QueueThreadPlan (thread_plan_sp, abort_other_plans);
694 return thread_plan_sp.get();
695}
696
697ThreadPlan *
698Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
699 lldb::addr_t *address_list,
700 size_t num_addresses,
701 bool stop_other_threads)
702{
703 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
704 QueueThreadPlan (thread_plan_sp, abort_other_plans);
705 return thread_plan_sp.get();
706
707}
708
709uint32_t
710Thread::GetIndexID () const
711{
712 return m_index_id;
713}
714
715void
716Thread::DumpThreadPlans (lldb_private::Stream *s) const
717{
718 uint32_t stack_size = m_plan_stack.size();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000719 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 +0000720 for (int i = stack_size - 1; i > 0; i--)
721 {
722 s->Printf ("Element %d: ", i);
723 s->IndentMore();
724 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
725 s->IndentLess();
726 s->EOL();
727 }
728
729 stack_size = m_immediate_plan_stack.size();
730 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
731 for (int i = stack_size - 1; i > 0; i--)
732 {
733 s->Printf ("Element %d: ", i);
734 s->IndentMore();
735 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
736 s->IndentLess();
737 s->EOL();
738 }
739
740 stack_size = m_completed_plan_stack.size();
741 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
742 for (int i = stack_size - 1; i > 0; i--)
743 {
744 s->Printf ("Element %d: ", i);
745 s->IndentMore();
746 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
747 s->IndentLess();
748 s->EOL();
749 }
750
751 stack_size = m_discarded_plan_stack.size();
752 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
753 for (int i = stack_size - 1; i > 0; i--)
754 {
755 s->Printf ("Element %d: ", i);
756 s->IndentMore();
757 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
758 s->IndentLess();
759 s->EOL();
760 }
761
762}
763
764Target *
765Thread::CalculateTarget ()
766{
767 return m_process.CalculateTarget();
768}
769
770Process *
771Thread::CalculateProcess ()
772{
773 return &m_process;
774}
775
776Thread *
777Thread::CalculateThread ()
778{
779 return this;
780}
781
782StackFrame *
783Thread::CalculateStackFrame ()
784{
785 return NULL;
786}
787
788void
789Thread::Calculate (ExecutionContext &exe_ctx)
790{
791 m_process.Calculate (exe_ctx);
792 exe_ctx.thread = this;
793 exe_ctx.frame = NULL;
794}
795
Jim Ingham71219082010-08-12 02:14:28 +0000796uint32_t
797Thread::GetStackFrameCount()
798{
799 Unwind *unwinder = GetUnwinder ();
800 if (unwinder)
801 return unwinder->GetFrameCount();
802 return 0;
803}
804
805lldb::StackFrameSP
806Thread::GetStackFrameAtIndex (uint32_t idx)
807{
808
809 StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx));
810
811 if (frame_sp.get())
812 return frame_sp;
813
814 // Don't try and fetch a frame while process is running
815// FIXME: This check isn't right because IsRunning checks the Public state, but this
816// is work you need to do - for instance in ShouldStop & friends - before the public
817// state has been changed.
818// if (m_process.IsRunning())
819// return frame_sp;
820
821 // Special case the first frame (idx == 0) so that we don't need to
822 // know how many stack frames there are to get it. If we need any other
823 // frames, then we do need to know if "idx" is a valid index.
824 if (idx == 0)
825 {
826 // If this is the first frame, we want to share the thread register
827 // context with the stack frame at index zero.
828 GetRegisterContext();
829 assert (m_reg_context_sp.get());
830 frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC()));
831 }
832 else if (idx < GetStackFrameCount())
833 {
834 Unwind *unwinder = GetUnwinder ();
835 if (unwinder)
836 {
837 addr_t pc, cfa;
838 if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
839 frame_sp.reset (new StackFrame (idx, *this, cfa, pc));
840 }
841 }
842 m_frames.SetFrameAtIndex(idx, frame_sp);
843 return frame_sp;
844}
845
Chris Lattner24943d22010-06-08 16:52:24 +0000846lldb::StackFrameSP
847Thread::GetCurrentFrame ()
848{
849 return GetStackFrameAtIndex (m_frames.GetCurrentFrameIndex());
850}
851
852uint32_t
853Thread::SetCurrentFrame (lldb_private::StackFrame *frame)
854{
855 return m_frames.SetCurrentFrame(frame);
856}
857
858void
859Thread::SetCurrentFrameByIndex (uint32_t frame_idx)
860{
861 m_frames.SetCurrentFrameByIndex(frame_idx);
862}
863
864void
865Thread::DumpInfo
866(
867 Stream &strm,
868 bool show_stop_reason,
869 bool show_name,
870 bool show_queue,
871 uint32_t frame_idx
872)
873{
874 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
875
876 if (frame_idx != LLDB_INVALID_INDEX32)
877 {
878 StackFrameSP frame_sp(GetStackFrameAtIndex (frame_idx));
879 if (frame_sp)
880 {
881 strm.PutCString(", ");
882 frame_sp->Dump (&strm, false);
883 }
884 }
885
886 if (show_stop_reason)
887 {
Greg Clayton643ee732010-08-04 01:40:35 +0000888 StopInfo *stop_info = GetStopInfo();
889
890 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +0000891 {
Greg Clayton643ee732010-08-04 01:40:35 +0000892 const char *stop_description = stop_info->GetDescription();
893 if (stop_description)
894 strm.Printf (", stop reason = %s", stop_description);
Chris Lattner24943d22010-06-08 16:52:24 +0000895 }
896 }
897
898 if (show_name)
899 {
900 const char *name = GetName();
901 if (name && name[0])
902 strm.Printf(", name = %s", name);
903 }
904
905 if (show_queue)
906 {
907 const char *queue = GetQueueName();
908 if (queue && queue[0])
909 strm.Printf(", queue = %s", queue);
910 }
911}
912
913lldb::ThreadSP
914Thread::GetSP ()
915{
916 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
917}