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