blob: 2f852cc3eae4597b08e020c2d6555a9929e991fc [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"
11#include "lldb/Core/Log.h"
12#include "lldb/Core/Stream.h"
13#include "lldb/Core/StreamString.h"
14#include "lldb/Host/Host.h"
15#include "lldb/Target/DynamicLoader.h"
16#include "lldb/Target/ExecutionContext.h"
17#include "lldb/Target/Process.h"
18#include "lldb/Target/RegisterContext.h"
19#include "lldb/Target/Thread.h"
20#include "lldb/Target/ThreadPlan.h"
21#include "lldb/Target/ThreadPlanCallFunction.h"
22#include "lldb/Target/ThreadPlanContinue.h"
23#include "lldb/Target/ThreadPlanBase.h"
24#include "lldb/Target/ThreadPlanStepInstruction.h"
25#include "lldb/Target/ThreadPlanStepOut.h"
26#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
27#include "lldb/Target/ThreadPlanStepThrough.h"
28#include "lldb/Target/ThreadPlanStepInRange.h"
29#include "lldb/Target/ThreadPlanStepOverRange.h"
30#include "lldb/Target/ThreadPlanRunToAddress.h"
31#include "lldb/Target/ThreadPlanStepUntil.h"
32
33using namespace lldb;
34using namespace lldb_private;
35
36Thread::Thread (Process &process, lldb::tid_t tid) :
37 UserID (tid),
38 m_index_id (process.GetNextThreadIndexID ()),
39 m_reg_context_sp (),
40 m_process (process),
41 m_state (eStateUnloaded),
42 m_plan_stack (),
43 m_immediate_plan_stack(),
44 m_completed_plan_stack(),
45 m_state_mutex (Mutex::eMutexTypeRecursive),
46 m_frames (),
47 m_current_frame_idx (0),
48 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
49 m_resume_state (eStateRunning)
50{
51 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
52 if (log)
53 log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
54
55 QueueFundamentalPlan(true);
56}
57
58
59Thread::~Thread()
60{
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
66int
67Thread::GetResumeSignal () const
68{
69 return m_resume_signal;
70}
71
72void
73Thread::SetResumeSignal (int signal)
74{
75 m_resume_signal = signal;
76}
77
78StateType
79Thread::GetResumeState () const
80{
81 return m_resume_state;
82}
83
84void
85Thread::SetResumeState (StateType state)
86{
87 m_resume_state = state;
88}
89
90Thread::StopInfo::StopInfo(Thread *thread) :
91 m_reason (eStopReasonInvalid),
92 m_description (),
93 m_thread (thread),
94 m_details ()
95{
96 m_description[0] = '\0';
97}
98
99Thread::StopInfo::~StopInfo()
100{
101}
102
103
104void
105Thread::StopInfo::Clear()
106{
107 m_reason = eStopReasonInvalid;
108 m_completed_plan_sp.reset();
109 m_description[0] = '\0';
110 ::bzero (&m_details, sizeof(m_details));
111}
112
113StopReason
114Thread::StopInfo::GetStopReason() const
115{
116 return m_reason;
117}
118
119const char *
120Thread::StopInfo::GetStopDescription() const
121{
122 if (m_description[0])
123 return m_description;
124 return NULL;
125}
126
127void
128Thread::StopInfo::SetStopDescription(const char *desc)
129{
130 if (desc && desc[0])
131 {
132 ::snprintf (m_description, sizeof(m_description), "%s", desc);
133 }
134 else
135 {
136 m_description[0] = '\0';
137 }
138}
139
140void
141Thread::StopInfo::SetThread (Thread* thread)
142{
143 m_thread = thread;
144}
145
146Thread *
147Thread::StopInfo::GetThread ()
148{
149 return m_thread;
150}
151
152lldb::user_id_t
153Thread::StopInfo::GetBreakpointSiteID() const
154{
155 if (m_reason == eStopReasonBreakpoint)
156 return m_details.breakpoint.bp_site_id;
157 return LLDB_INVALID_BREAK_ID;
158}
159
160void
161Thread::StopInfo::SetStopReasonWithBreakpointSiteID (lldb::user_id_t bp_site_id)
162{
163 m_reason = eStopReasonBreakpoint;
164 m_details.breakpoint.bp_site_id = bp_site_id;
165}
166
167lldb::user_id_t
168Thread::StopInfo::GetWatchpointID() const
169{
170 if (m_reason == eStopReasonWatchpoint)
171 return m_details.watchpoint.watch_id;
172 return LLDB_INVALID_WATCH_ID;
173}
174
175void
176Thread::StopInfo::SetStopReasonWithWatchpointID (lldb::user_id_t watch_id)
177{
178 m_reason = eStopReasonWatchpoint;
179 m_details.watchpoint.watch_id = watch_id;
180}
181
182
183int
184Thread::StopInfo::GetSignal() const
185{
186 if (m_reason == eStopReasonSignal)
187 return m_details.signal.signo;
188 return 0;
189}
190
191lldb::user_id_t
192Thread::StopInfo::GetPlanID() const
193{
194 if (m_reason == eStopReasonPlanComplete)
195 return m_completed_plan_sp->GetID();
196 return LLDB_INVALID_UID;
197}
198
199void
200Thread::StopInfo::SetStopReasonWithSignal (int signo)
201{
202 m_reason = eStopReasonSignal;
203 m_details.signal.signo = signo;
204}
205
206void
207Thread::StopInfo::SetStopReasonToTrace ()
208{
209 m_reason = eStopReasonTrace;
210}
211
212uint32_t
213Thread::StopInfo::GetExceptionType() const
214{
215 if (m_reason == eStopReasonException)
216 return m_details.exception.type;
217 return 0;
218}
219
220size_t
221Thread::StopInfo::GetExceptionDataCount() const
222{
223 if (m_reason == eStopReasonException)
224 return m_details.exception.data_count;
225 return 0;
226}
227
228void
229Thread::StopInfo::SetStopReasonWithException (uint32_t exc_type, size_t exc_data_count)
230{
231 m_reason = eStopReasonException;
232 m_details.exception.type = exc_type;
233 m_details.exception.data_count = exc_data_count;
234}
235
236void
237Thread::StopInfo::SetStopReasonWithPlan (ThreadPlanSP &thread_plan_sp)
238{
239 m_reason = eStopReasonPlanComplete;
240 m_completed_plan_sp = thread_plan_sp;
241}
242
243void
244Thread::StopInfo::SetStopReasonToNone ()
245{
246 Clear();
247 m_reason = eStopReasonNone;
248}
249
250lldb::addr_t
251Thread::StopInfo::GetExceptionDataAtIndex (uint32_t idx) const
252{
253 if (m_reason == eStopReasonException && idx < m_details.exception.data_count)
254 return m_details.exception.data[idx];
255 return 0;
256
257}
258
259
260bool
261Thread::StopInfo::SetExceptionDataAtIndex (uint32_t idx, lldb::addr_t data)
262{
263 if (m_reason == eStopReasonException && idx < m_details.exception.data_count)
264 {
265 m_details.exception.data[idx] = data;
266 return true;
267 }
268 return false;
269}
270
271void
272Thread::StopInfo::Dump (Stream *s) const
273{
274 if (m_description[0])
275 s->Printf("%s", m_description);
276 else
277 {
278 switch (m_reason)
279 {
280 case eStopReasonInvalid:
281 s->PutCString("invalid");
282 break;
283
284 case eStopReasonNone:
285 s->PutCString("none");
286 break;
287
288 case eStopReasonTrace:
289 s->PutCString("trace");
290 break;
291
292 case eStopReasonBreakpoint:
293 {
294 bool no_details = true;
295 s->PutCString ("breakpoint ");
296 if (m_thread)
297 {
298 BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByID(m_details.breakpoint.bp_site_id);
299 if (bp_site_sp)
300 {
301 bp_site_sp->GetDescription(s, lldb::eDescriptionLevelBrief);
302 no_details = false;
303 }
304 }
305
306 if (no_details)
307 s->Printf ("site id: %d", m_details.breakpoint.bp_site_id);
308 }
309 break;
310
311 case eStopReasonWatchpoint:
312 s->Printf("watchpoint (site id = %u)", m_details.watchpoint.watch_id);
313 break;
314
315 case eStopReasonSignal:
316 {
317 s->Printf("signal: signo = %i", m_details.signal.signo);
318 const char * signal_name = m_thread->GetProcess().GetUnixSignals().GetSignalAsCString (m_details.signal.signo);
319 if (signal_name)
320 s->Printf(" (%s)", signal_name);
321 }
322 break;
323
324 case eStopReasonException:
325 {
326 s->Printf("exception: type = 0x%8.8x, data_count = %zu", m_details.exception.type, m_details.exception.data_count);
327 uint32_t i;
328 for (i=0; i<m_details.exception.data_count; ++i)
329 {
330 s->Printf(", data[%u] = 0x%8.8llx", i, m_details.exception.data[i]);
331 }
332 }
333 break;
334
335 case eStopReasonPlanComplete:
336 {
337 m_completed_plan_sp->GetDescription (s, lldb::eDescriptionLevelBrief);
338 }
339 break;
340 }
341 }
342}
343
344bool
345Thread::GetStopInfo (Thread::StopInfo *stop_info)
346{
347 stop_info->SetThread(this);
348 ThreadPlanSP completed_plan = GetCompletedPlan();
349 if (completed_plan != NULL)
350 {
351 stop_info->Clear ();
352 stop_info->SetStopReasonWithPlan (completed_plan);
353 return true;
354 }
355 else
356 return GetRawStopReason (stop_info);
357}
358
359bool
360Thread::ThreadStoppedForAReason (void)
361{
362 Thread::StopInfo stop_info;
363 stop_info.SetThread(this);
364 if (GetRawStopReason (&stop_info))
365 {
366 StopReason reason = stop_info.GetStopReason();
367 if (reason == eStopReasonInvalid || reason == eStopReasonNone)
368 return false;
369 else
370 return true;
371 }
372 else
373 return false;
374}
375
376StateType
377Thread::GetState() const
378{
379 // If any other threads access this we will need a mutex for it
380 Mutex::Locker locker(m_state_mutex);
381 return m_state;
382}
383
384void
385Thread::SetState(StateType state)
386{
387 Mutex::Locker locker(m_state_mutex);
388 m_state = state;
389}
390
391void
392Thread::WillStop()
393{
394 ThreadPlan *current_plan = GetCurrentPlan();
395
396 // FIXME: I may decide to disallow threads with no plans. In which
397 // case this should go to an assert.
398
399 if (!current_plan)
400 return;
401
402 current_plan->WillStop();
403}
404
405void
406Thread::SetupForResume ()
407{
408 if (GetResumeState() != eStateSuspended)
409 {
410
411 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
412 // telling the current plan it will resume, since we might change what the current
413 // plan is.
414
415 lldb::addr_t pc = GetRegisterContext()->GetPC();
416 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
417 if (bp_site_sp && bp_site_sp->IsEnabled())
418 {
419 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
420 // special to step over a breakpoint.
421
422 ThreadPlan *cur_plan = GetCurrentPlan();
423 ThreadPlanStepOverBreakpoint *step_over_bp = dynamic_cast<ThreadPlanStepOverBreakpoint *> (cur_plan);
424 if (step_over_bp == NULL)
425 {
426
427 ThreadPlanSP step_bp_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
428 if (step_bp_plan_sp)
429 {
430 if (GetCurrentPlan()->RunState() != eStateStepping)
431 {
432 ThreadPlanSP continue_plan_sp (new ThreadPlanContinue(*this, false, eVoteNo, eVoteNoOpinion));
433 continue_plan_sp->SetPrivate (true);
434 QueueThreadPlan (continue_plan_sp, false);
435 }
436 step_bp_plan_sp->SetPrivate (true);
437 QueueThreadPlan (step_bp_plan_sp, false);
438 }
439 }
440 }
441 }
442}
443
444bool
445Thread::WillResume (StateType resume_state)
446{
447 // At this point clear the completed plan stack.
448 m_completed_plan_stack.clear();
449 m_discarded_plan_stack.clear();
450
451 // If this thread stopped with a signal, work out what its resume state should
452 // be. Note if the thread resume state is already set, then don't override it,
453 // the user must have asked us to resume with some other signal.
454
455 if (GetResumeSignal() == LLDB_INVALID_SIGNAL_NUMBER)
456 {
457 Thread::StopInfo stop_info;
458 GetRawStopReason(&stop_info);
459
460 StopReason reason = stop_info.GetStopReason();
461 if (reason == eStopReasonSignal)
462 {
463 UnixSignals &signals = GetProcess().GetUnixSignals();
464 int32_t signo = stop_info.GetSignal();
465 if (!signals.GetShouldSuppress(signo))
466 {
467 SetResumeSignal(signo);
468 }
469 }
470 }
471
472 // Tell all the plans that we are about to resume in case they need to clear any state.
473 // We distinguish between the plan on the top of the stack and the lower
474 // plans in case a plan needs to do any special business before it runs.
475
476 ThreadPlan *plan_ptr = GetCurrentPlan();
477 plan_ptr->WillResume(resume_state, true);
478
479 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
480 {
481 plan_ptr->WillResume (resume_state, false);
482 }
483 return true;
484}
485
486void
487Thread::DidResume ()
488{
489 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
490}
491
492bool
493Thread::ShouldStop (Event* event_ptr)
494{
495 ThreadPlan *current_plan = GetCurrentPlan();
496 bool should_stop = true;
497
498 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
499 if (log)
500 {
501 StreamString s;
502 DumpThreadPlans(&s);
503 log->PutCString (s.GetData());
504 }
505
506 if (current_plan->PlanExplainsStop())
507 {
508 while (1)
509 {
510 should_stop = current_plan->ShouldStop(event_ptr);
511 if (current_plan->MischiefManaged())
512 {
513 if (should_stop)
514 current_plan->WillStop();
515
516 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
517 // Otherwise, see if the plan's parent wants to stop.
518
519 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
520 {
521 PopPlan();
522 break;
523 }
524 else
525 {
526
527 PopPlan();
528
529 current_plan = GetCurrentPlan();
530 if (current_plan == NULL)
531 {
532 break;
533 }
534 }
535
536 }
537 else
538 {
539 break;
540 }
541 }
542 }
543 else
544 {
545 // If the current plan doesn't explain the stop, then, find one that
546 // does and let it handle the situation.
547 ThreadPlan *plan_ptr = current_plan;
548 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
549 {
550 if (plan_ptr->PlanExplainsStop())
551 {
552 should_stop = plan_ptr->ShouldStop (event_ptr);
553 break;
554 }
555
556 }
557 }
558
559 return should_stop;
560}
561
562Vote
563Thread::ShouldReportStop (Event* event_ptr)
564{
565 StateType thread_state = GetResumeState ();
566 if (thread_state == eStateSuspended
567 || thread_state == eStateInvalid)
568 return eVoteNoOpinion;
569
570 if (m_completed_plan_stack.size() > 0)
571 {
572 // Don't use GetCompletedPlan here, since that suppresses private plans.
573 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
574 }
575 else
576 return GetCurrentPlan()->ShouldReportStop (event_ptr);
577}
578
579Vote
580Thread::ShouldReportRun (Event* event_ptr)
581{
582 StateType thread_state = GetResumeState ();
583 if (thread_state == eStateSuspended
584 || thread_state == eStateInvalid)
585 return eVoteNoOpinion;
586
587 if (m_completed_plan_stack.size() > 0)
588 {
589 // Don't use GetCompletedPlan here, since that suppresses private plans.
590 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
591 }
592 else
593 return GetCurrentPlan()->ShouldReportRun (event_ptr);
594}
595
596void
597Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
598{
599 if (thread_plan_sp)
600 {
601 if (thread_plan_sp->IsImmediate())
602 m_immediate_plan_stack.push_back (thread_plan_sp);
603 else
604 m_plan_stack.push_back (thread_plan_sp);
605
606 thread_plan_sp->DidPush();
607
608 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
609 if (log)
610 {
611 StreamString s;
612 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
613 log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.",
614 s.GetData(),
615 thread_plan_sp->GetThread().GetID(),
616 thread_plan_sp->IsImmediate() ? "true" : "false");
617 }
618 }
619}
620
621void
622Thread::PopPlan ()
623{
624 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
625
626 if (!m_immediate_plan_stack.empty())
627 {
628 ThreadPlanSP &plan = m_immediate_plan_stack.back();
629 if (log)
630 {
631 log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID());
632 }
633 plan->WillPop();
634 m_immediate_plan_stack.pop_back();
635 }
636 else if (m_plan_stack.empty())
637 return;
638 else
639 {
640 ThreadPlanSP &plan = m_plan_stack.back();
641 if (log)
642 {
643 log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID());
644 }
645 m_completed_plan_stack.push_back (plan);
646 plan->WillPop();
647 m_plan_stack.pop_back();
648 }
649}
650
651void
652Thread::DiscardPlan ()
653{
654 if (m_plan_stack.size() > 1)
655 {
656 ThreadPlanSP &plan = m_plan_stack.back();
657 m_discarded_plan_stack.push_back (plan);
658 plan->WillPop();
659 m_plan_stack.pop_back();
660 }
661}
662
663ThreadPlan *
664Thread::GetCurrentPlan ()
665{
666 if (!m_immediate_plan_stack.empty())
667 return m_immediate_plan_stack.back().get();
668 else if (m_plan_stack.empty())
669 return NULL;
670 else
671 return m_plan_stack.back().get();
672}
673
674ThreadPlanSP
675Thread::GetCompletedPlan ()
676{
677 ThreadPlanSP empty_plan_sp;
678 if (!m_completed_plan_stack.empty())
679 {
680 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
681 {
682 ThreadPlanSP completed_plan_sp;
683 completed_plan_sp = m_completed_plan_stack[i];
684 if (!completed_plan_sp->GetPrivate ())
685 return completed_plan_sp;
686 }
687 }
688 return empty_plan_sp;
689}
690
691bool
692Thread::IsThreadPlanDone (ThreadPlan *plan)
693{
694 ThreadPlanSP empty_plan_sp;
695 if (!m_completed_plan_stack.empty())
696 {
697 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
698 {
699 if (m_completed_plan_stack[i].get() == plan)
700 return true;
701 }
702 }
703 return false;
704}
705
706bool
707Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
708{
709 ThreadPlanSP empty_plan_sp;
710 if (!m_discarded_plan_stack.empty())
711 {
712 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
713 {
714 if (m_discarded_plan_stack[i].get() == plan)
715 return true;
716 }
717 }
718 return false;
719}
720
721ThreadPlan *
722Thread::GetPreviousPlan (ThreadPlan *current_plan)
723{
724 if (current_plan == NULL)
725 return NULL;
726
727 int stack_size = m_completed_plan_stack.size();
728 for (int i = stack_size - 1; i > 0; i--)
729 {
730 if (current_plan == m_completed_plan_stack[i].get())
731 return m_completed_plan_stack[i-1].get();
732 }
733
734 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
735 {
736 if (m_immediate_plan_stack.size() > 0)
737 return m_immediate_plan_stack.back().get();
738 else if (m_plan_stack.size() > 0)
739 return m_plan_stack.back().get();
740 else
741 return NULL;
742 }
743
744 stack_size = m_immediate_plan_stack.size();
745 for (int i = stack_size - 1; i > 0; i--)
746 {
747 if (current_plan == m_immediate_plan_stack[i].get())
748 return m_immediate_plan_stack[i-1].get();
749 }
750 if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
751 {
752 if (m_plan_stack.size() > 0)
753 return m_plan_stack.back().get();
754 else
755 return NULL;
756 }
757
758 stack_size = m_plan_stack.size();
759 for (int i = stack_size - 1; i > 0; i--)
760 {
761 if (current_plan == m_plan_stack[i].get())
762 return m_plan_stack[i-1].get();
763 }
764 return NULL;
765}
766
767void
768Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
769{
770 if (abort_other_plans)
771 DiscardThreadPlans(true);
772
773 PushPlan (thread_plan_sp);
774}
775
776void
777Thread::DiscardThreadPlans(bool force)
778{
779 // FIXME: It is not always safe to just discard plans. Some, like the step over
780 // breakpoint trap can't be discarded in general (though you can if you plan to
781 // force a return from a function, for instance.
782 // For now I'm just not clearing immediate plans, but I need a way for plans to
783 // say they really need to be kept on, and then a way to override that. Humm...
784
785 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
786 if (log)
787 {
788 log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force);
789 }
790
791 if (force)
792 {
793 int stack_size = m_plan_stack.size();
794 for (int i = stack_size - 1; i > 0; i--)
795 {
796 DiscardPlan();
797 }
798 return;
799 }
800
801 while (1)
802 {
803
804 int master_plan_idx;
805 bool discard;
806
807 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
808 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
809 {
810 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
811 {
812 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
813 break;
814 }
815 }
816
817 if (discard)
818 {
819 // First pop all the dependent plans:
820 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
821 {
822
823 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
824 // for the plan leaves it in a state that it is safe to pop the plan
825 // with no more notice?
826 DiscardPlan();
827 }
828
829 // Now discard the master plan itself.
830 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
831 // discard it's dependent plans, but not it...
832 if (master_plan_idx > 0)
833 {
834 DiscardPlan();
835 }
836 }
837 else
838 {
839 // If the master plan doesn't want to get discarded, then we're done.
840 break;
841 }
842
843 }
844 // FIXME: What should we do about the immediate plans?
845}
846
847ThreadPlan *
848Thread::QueueFundamentalPlan (bool abort_other_plans)
849{
850 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
851 QueueThreadPlan (thread_plan_sp, abort_other_plans);
852 return thread_plan_sp.get();
853}
854
855ThreadPlan *
856Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
857{
858 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
859 QueueThreadPlan (thread_plan_sp, abort_other_plans);
860 return thread_plan_sp.get();
861}
862
863ThreadPlan *
864Thread::QueueThreadPlanForStepRange (bool abort_other_plans, StepType type, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_other_threads)
865{
866 ThreadPlanSP thread_plan_sp;
867 if (type == eStepTypeInto)
868 thread_plan_sp.reset (new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads));
869 else
870 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
871
872 QueueThreadPlan (thread_plan_sp, abort_other_plans);
873 return thread_plan_sp.get();
874}
875
876
877ThreadPlan *
878Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
879{
880 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
881 QueueThreadPlan (thread_plan_sp, abort_other_plans);
882 return thread_plan_sp.get();
883}
884
885ThreadPlan *
886Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
887 bool stop_other_threads, Vote stop_vote, Vote run_vote)
888{
889 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
890 QueueThreadPlan (thread_plan_sp, abort_other_plans);
891 return thread_plan_sp.get();
892}
893
894ThreadPlan *
895Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
896{
897 ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
898 if (thread_plan_sp.get() == NULL)
899 {
900 thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
901 if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
902 return false;
903 }
904 QueueThreadPlan (thread_plan_sp, abort_other_plans);
905 return thread_plan_sp.get();
906}
907
908ThreadPlan *
909Thread::QueueThreadPlanForContinue (bool abort_other_plans, bool stop_other_threads, Vote stop_vote, Vote run_vote, bool immediate)
910{
911 ThreadPlanSP thread_plan_sp (new ThreadPlanContinue (*this, stop_other_threads, stop_vote, run_vote, immediate));
912 QueueThreadPlan (thread_plan_sp, abort_other_plans);
913 return thread_plan_sp.get();
914}
915
916ThreadPlan *
917Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
918 Address& function,
919 lldb::addr_t arg,
920 bool stop_other_threads,
921 bool discard_on_error)
922{
923 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
924 QueueThreadPlan (thread_plan_sp, abort_other_plans);
925 return thread_plan_sp.get();
926}
927
928ThreadPlan *
929Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
930 Address& function,
931 ValueList &args,
932 bool stop_other_threads,
933 bool discard_on_error)
934{
935 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
936 QueueThreadPlan (thread_plan_sp, abort_other_plans);
937 return thread_plan_sp.get();
938}
939
940ThreadPlan *
941Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
942 Address &target_addr,
943 bool stop_other_threads)
944{
945 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
946 QueueThreadPlan (thread_plan_sp, abort_other_plans);
947 return thread_plan_sp.get();
948}
949
950ThreadPlan *
951Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
952 lldb::addr_t *address_list,
953 size_t num_addresses,
954 bool stop_other_threads)
955{
956 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
957 QueueThreadPlan (thread_plan_sp, abort_other_plans);
958 return thread_plan_sp.get();
959
960}
961
962uint32_t
963Thread::GetIndexID () const
964{
965 return m_index_id;
966}
967
968void
969Thread::DumpThreadPlans (lldb_private::Stream *s) const
970{
971 uint32_t stack_size = m_plan_stack.size();
972 s->Printf ("Plan Stack: %d elements.\n", stack_size);
973 for (int i = stack_size - 1; i > 0; i--)
974 {
975 s->Printf ("Element %d: ", i);
976 s->IndentMore();
977 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
978 s->IndentLess();
979 s->EOL();
980 }
981
982 stack_size = m_immediate_plan_stack.size();
983 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
984 for (int i = stack_size - 1; i > 0; i--)
985 {
986 s->Printf ("Element %d: ", i);
987 s->IndentMore();
988 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
989 s->IndentLess();
990 s->EOL();
991 }
992
993 stack_size = m_completed_plan_stack.size();
994 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
995 for (int i = stack_size - 1; i > 0; i--)
996 {
997 s->Printf ("Element %d: ", i);
998 s->IndentMore();
999 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1000 s->IndentLess();
1001 s->EOL();
1002 }
1003
1004 stack_size = m_discarded_plan_stack.size();
1005 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
1006 for (int i = stack_size - 1; i > 0; i--)
1007 {
1008 s->Printf ("Element %d: ", i);
1009 s->IndentMore();
1010 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1011 s->IndentLess();
1012 s->EOL();
1013 }
1014
1015}
1016
1017Target *
1018Thread::CalculateTarget ()
1019{
1020 return m_process.CalculateTarget();
1021}
1022
1023Process *
1024Thread::CalculateProcess ()
1025{
1026 return &m_process;
1027}
1028
1029Thread *
1030Thread::CalculateThread ()
1031{
1032 return this;
1033}
1034
1035StackFrame *
1036Thread::CalculateStackFrame ()
1037{
1038 return NULL;
1039}
1040
1041void
1042Thread::Calculate (ExecutionContext &exe_ctx)
1043{
1044 m_process.Calculate (exe_ctx);
1045 exe_ctx.thread = this;
1046 exe_ctx.frame = NULL;
1047}
1048
1049lldb::StackFrameSP
1050Thread::GetCurrentFrame ()
1051{
1052 return GetStackFrameAtIndex (m_frames.GetCurrentFrameIndex());
1053}
1054
1055uint32_t
1056Thread::SetCurrentFrame (lldb_private::StackFrame *frame)
1057{
1058 return m_frames.SetCurrentFrame(frame);
1059}
1060
1061void
1062Thread::SetCurrentFrameByIndex (uint32_t frame_idx)
1063{
1064 m_frames.SetCurrentFrameByIndex(frame_idx);
1065}
1066
1067void
1068Thread::DumpInfo
1069(
1070 Stream &strm,
1071 bool show_stop_reason,
1072 bool show_name,
1073 bool show_queue,
1074 uint32_t frame_idx
1075)
1076{
1077 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
1078
1079 if (frame_idx != LLDB_INVALID_INDEX32)
1080 {
1081 StackFrameSP frame_sp(GetStackFrameAtIndex (frame_idx));
1082 if (frame_sp)
1083 {
1084 strm.PutCString(", ");
1085 frame_sp->Dump (&strm, false);
1086 }
1087 }
1088
1089 if (show_stop_reason)
1090 {
1091 Thread::StopInfo thread_stop_info;
1092 if (GetStopInfo(&thread_stop_info))
1093 {
1094 if (thread_stop_info.GetStopReason() != eStopReasonNone)
1095 {
1096 strm.PutCString(", stop reason = ");
1097 thread_stop_info.Dump(&strm);
1098 }
1099 }
1100 }
1101
1102 if (show_name)
1103 {
1104 const char *name = GetName();
1105 if (name && name[0])
1106 strm.Printf(", name = %s", name);
1107 }
1108
1109 if (show_queue)
1110 {
1111 const char *queue = GetQueueName();
1112 if (queue && queue[0])
1113 strm.Printf(", queue = %s", queue);
1114 }
1115}
1116
1117lldb::ThreadSP
1118Thread::GetSP ()
1119{
1120 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
1121}