blob: ce9216a746680166a124485f134cce8ea1b4e791 [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),
Greg Clayton782b9cc2010-08-25 00:35:26 +000048 m_state_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +000049 m_plan_stack (),
50 m_immediate_plan_stack(),
51 m_completed_plan_stack(),
Greg Claytonf40e3082010-08-26 02:28:22 +000052 m_curr_frames_ap (),
Chris Lattner24943d22010-06-08 16:52:24 +000053 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
Jim Ingham71219082010-08-12 02:14:28 +000054 m_resume_state (eStateRunning),
55 m_unwinder_ap ()
56
Chris Lattner24943d22010-06-08 16:52:24 +000057{
58 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
59 if (log)
60 log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
61
62 QueueFundamentalPlan(true);
63}
64
65
66Thread::~Thread()
67{
68 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
69 if (log)
70 log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
71}
72
73int
74Thread::GetResumeSignal () const
75{
76 return m_resume_signal;
77}
78
79void
80Thread::SetResumeSignal (int signal)
81{
82 m_resume_signal = signal;
83}
84
85StateType
86Thread::GetResumeState () const
87{
88 return m_resume_state;
89}
90
91void
92Thread::SetResumeState (StateType state)
93{
94 m_resume_state = state;
95}
96
Greg Clayton643ee732010-08-04 01:40:35 +000097StopInfo *
98Thread::GetStopInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +000099{
Greg Clayton643ee732010-08-04 01:40:35 +0000100 if (m_public_stop_info_sp.get() == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000101 {
Greg Clayton643ee732010-08-04 01:40:35 +0000102 ThreadPlanSP plan_sp (GetCompletedPlan());
103 if (plan_sp)
104 m_public_stop_info_sp = StopInfo::CreateStopReasonWithPlan (plan_sp);
105 else
106 m_public_stop_info_sp = GetPrivateStopReason ();
Chris Lattner24943d22010-06-08 16:52:24 +0000107 }
Greg Clayton643ee732010-08-04 01:40:35 +0000108 return m_public_stop_info_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000109}
110
111bool
112Thread::ThreadStoppedForAReason (void)
113{
Greg Clayton643ee732010-08-04 01:40:35 +0000114 return GetPrivateStopReason () != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000115}
116
117StateType
118Thread::GetState() const
119{
120 // If any other threads access this we will need a mutex for it
121 Mutex::Locker locker(m_state_mutex);
122 return m_state;
123}
124
125void
126Thread::SetState(StateType state)
127{
128 Mutex::Locker locker(m_state_mutex);
129 m_state = state;
130}
131
132void
133Thread::WillStop()
134{
135 ThreadPlan *current_plan = GetCurrentPlan();
136
137 // FIXME: I may decide to disallow threads with no plans. In which
138 // case this should go to an assert.
139
140 if (!current_plan)
141 return;
142
143 current_plan->WillStop();
144}
145
146void
147Thread::SetupForResume ()
148{
149 if (GetResumeState() != eStateSuspended)
150 {
151
152 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
153 // telling the current plan it will resume, since we might change what the current
154 // plan is.
155
156 lldb::addr_t pc = GetRegisterContext()->GetPC();
157 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
158 if (bp_site_sp && bp_site_sp->IsEnabled())
159 {
160 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
161 // special to step over a breakpoint.
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000162
163 ThreadPlan *cur_plan = GetCurrentPlan();
Chris Lattner24943d22010-06-08 16:52:24 +0000164
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000165 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
166 {
167 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
168 if (step_bp_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000169 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000170 ThreadPlanSP step_bp_plan_sp;
171 step_bp_plan->SetPrivate (true);
172
Chris Lattner24943d22010-06-08 16:52:24 +0000173 if (GetCurrentPlan()->RunState() != eStateStepping)
174 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000175 step_bp_plan->SetAutoContinue(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000176 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000177 step_bp_plan_sp.reset (step_bp_plan);
Chris Lattner24943d22010-06-08 16:52:24 +0000178 QueueThreadPlan (step_bp_plan_sp, false);
179 }
180 }
181 }
182 }
183}
184
185bool
186Thread::WillResume (StateType resume_state)
187{
188 // At this point clear the completed plan stack.
189 m_completed_plan_stack.clear();
190 m_discarded_plan_stack.clear();
191
Greg Clayton643ee732010-08-04 01:40:35 +0000192 StopInfo *stop_info = GetPrivateStopReason().get();
193 if (stop_info)
194 stop_info->WillResume (resume_state);
Chris Lattner24943d22010-06-08 16:52:24 +0000195
196 // Tell all the plans that we are about to resume in case they need to clear any state.
197 // We distinguish between the plan on the top of the stack and the lower
198 // plans in case a plan needs to do any special business before it runs.
199
200 ThreadPlan *plan_ptr = GetCurrentPlan();
201 plan_ptr->WillResume(resume_state, true);
202
203 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
204 {
205 plan_ptr->WillResume (resume_state, false);
206 }
Greg Clayton643ee732010-08-04 01:40:35 +0000207
208 m_public_stop_info_sp.reset();
209 m_actual_stop_info_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000210 return true;
211}
212
213void
214Thread::DidResume ()
215{
216 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
217}
218
219bool
220Thread::ShouldStop (Event* event_ptr)
221{
222 ThreadPlan *current_plan = GetCurrentPlan();
223 bool should_stop = true;
224
225 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
226 if (log)
227 {
228 StreamString s;
229 DumpThreadPlans(&s);
230 log->PutCString (s.GetData());
231 }
232
233 if (current_plan->PlanExplainsStop())
234 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000235 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000236 while (1)
237 {
238 should_stop = current_plan->ShouldStop(event_ptr);
239 if (current_plan->MischiefManaged())
240 {
241 if (should_stop)
242 current_plan->WillStop();
243
244 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
245 // Otherwise, see if the plan's parent wants to stop.
246
247 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
248 {
249 PopPlan();
250 break;
251 }
252 else
253 {
254
255 PopPlan();
256
257 current_plan = GetCurrentPlan();
258 if (current_plan == NULL)
259 {
260 break;
261 }
262 }
263
264 }
265 else
266 {
267 break;
268 }
269 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000270 if (over_ride_stop)
271 should_stop = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000272 }
273 else
274 {
275 // If the current plan doesn't explain the stop, then, find one that
276 // does and let it handle the situation.
277 ThreadPlan *plan_ptr = current_plan;
278 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
279 {
280 if (plan_ptr->PlanExplainsStop())
281 {
282 should_stop = plan_ptr->ShouldStop (event_ptr);
283 break;
284 }
285
286 }
287 }
288
289 return should_stop;
290}
291
292Vote
293Thread::ShouldReportStop (Event* event_ptr)
294{
295 StateType thread_state = GetResumeState ();
Greg Clayton5205f0b2010-09-03 17:10:42 +0000296 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
297
298 if (thread_state == eStateSuspended || thread_state == eStateInvalid)
299 {
300 if (log)
301 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
Chris Lattner24943d22010-06-08 16:52:24 +0000302 return eVoteNoOpinion;
Greg Clayton5205f0b2010-09-03 17:10:42 +0000303 }
Chris Lattner24943d22010-06-08 16:52:24 +0000304
305 if (m_completed_plan_stack.size() > 0)
306 {
307 // Don't use GetCompletedPlan here, since that suppresses private plans.
Greg Clayton5205f0b2010-09-03 17:10:42 +0000308 if (log)
309 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote for complete stack's back plan\n", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000310 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
311 }
312 else
Greg Clayton5205f0b2010-09-03 17:10:42 +0000313 {
314 if (log)
315 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote for current plan\n", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000316 return GetCurrentPlan()->ShouldReportStop (event_ptr);
Greg Clayton5205f0b2010-09-03 17:10:42 +0000317 }
Chris Lattner24943d22010-06-08 16:52:24 +0000318}
319
320Vote
321Thread::ShouldReportRun (Event* event_ptr)
322{
323 StateType thread_state = GetResumeState ();
324 if (thread_state == eStateSuspended
325 || thread_state == eStateInvalid)
326 return eVoteNoOpinion;
327
328 if (m_completed_plan_stack.size() > 0)
329 {
330 // Don't use GetCompletedPlan here, since that suppresses private plans.
331 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
332 }
333 else
334 return GetCurrentPlan()->ShouldReportRun (event_ptr);
335}
336
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000337bool
338Thread::MatchesSpec (const ThreadSpec *spec)
339{
340 if (spec == NULL)
341 return true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000342
Jim Ingham649492b2010-06-18 01:00:58 +0000343 return spec->ThreadPassesBasicTests(this);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000344}
345
Chris Lattner24943d22010-06-08 16:52:24 +0000346void
347Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
348{
349 if (thread_plan_sp)
350 {
351 if (thread_plan_sp->IsImmediate())
352 m_immediate_plan_stack.push_back (thread_plan_sp);
353 else
354 m_plan_stack.push_back (thread_plan_sp);
355
356 thread_plan_sp->DidPush();
357
358 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
359 if (log)
360 {
361 StreamString s;
362 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
363 log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.",
364 s.GetData(),
365 thread_plan_sp->GetThread().GetID(),
366 thread_plan_sp->IsImmediate() ? "true" : "false");
367 }
368 }
369}
370
371void
372Thread::PopPlan ()
373{
374 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
375
376 if (!m_immediate_plan_stack.empty())
377 {
378 ThreadPlanSP &plan = m_immediate_plan_stack.back();
379 if (log)
380 {
381 log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID());
382 }
383 plan->WillPop();
384 m_immediate_plan_stack.pop_back();
385 }
386 else if (m_plan_stack.empty())
387 return;
388 else
389 {
390 ThreadPlanSP &plan = m_plan_stack.back();
391 if (log)
392 {
393 log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID());
394 }
395 m_completed_plan_stack.push_back (plan);
396 plan->WillPop();
397 m_plan_stack.pop_back();
398 }
399}
400
401void
402Thread::DiscardPlan ()
403{
404 if (m_plan_stack.size() > 1)
405 {
406 ThreadPlanSP &plan = m_plan_stack.back();
407 m_discarded_plan_stack.push_back (plan);
408 plan->WillPop();
409 m_plan_stack.pop_back();
410 }
411}
412
413ThreadPlan *
414Thread::GetCurrentPlan ()
415{
416 if (!m_immediate_plan_stack.empty())
417 return m_immediate_plan_stack.back().get();
418 else if (m_plan_stack.empty())
419 return NULL;
420 else
421 return m_plan_stack.back().get();
422}
423
424ThreadPlanSP
425Thread::GetCompletedPlan ()
426{
427 ThreadPlanSP empty_plan_sp;
428 if (!m_completed_plan_stack.empty())
429 {
430 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
431 {
432 ThreadPlanSP completed_plan_sp;
433 completed_plan_sp = m_completed_plan_stack[i];
434 if (!completed_plan_sp->GetPrivate ())
435 return completed_plan_sp;
436 }
437 }
438 return empty_plan_sp;
439}
440
441bool
442Thread::IsThreadPlanDone (ThreadPlan *plan)
443{
444 ThreadPlanSP empty_plan_sp;
445 if (!m_completed_plan_stack.empty())
446 {
447 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
448 {
449 if (m_completed_plan_stack[i].get() == plan)
450 return true;
451 }
452 }
453 return false;
454}
455
456bool
457Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
458{
459 ThreadPlanSP empty_plan_sp;
460 if (!m_discarded_plan_stack.empty())
461 {
462 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
463 {
464 if (m_discarded_plan_stack[i].get() == plan)
465 return true;
466 }
467 }
468 return false;
469}
470
471ThreadPlan *
472Thread::GetPreviousPlan (ThreadPlan *current_plan)
473{
474 if (current_plan == NULL)
475 return NULL;
476
477 int stack_size = m_completed_plan_stack.size();
478 for (int i = stack_size - 1; i > 0; i--)
479 {
480 if (current_plan == m_completed_plan_stack[i].get())
481 return m_completed_plan_stack[i-1].get();
482 }
483
484 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
485 {
486 if (m_immediate_plan_stack.size() > 0)
487 return m_immediate_plan_stack.back().get();
488 else if (m_plan_stack.size() > 0)
489 return m_plan_stack.back().get();
490 else
491 return NULL;
492 }
493
494 stack_size = m_immediate_plan_stack.size();
495 for (int i = stack_size - 1; i > 0; i--)
496 {
497 if (current_plan == m_immediate_plan_stack[i].get())
498 return m_immediate_plan_stack[i-1].get();
499 }
500 if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
501 {
502 if (m_plan_stack.size() > 0)
503 return m_plan_stack.back().get();
504 else
505 return NULL;
506 }
507
508 stack_size = m_plan_stack.size();
509 for (int i = stack_size - 1; i > 0; i--)
510 {
511 if (current_plan == m_plan_stack[i].get())
512 return m_plan_stack[i-1].get();
513 }
514 return NULL;
515}
516
517void
518Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
519{
520 if (abort_other_plans)
521 DiscardThreadPlans(true);
522
523 PushPlan (thread_plan_sp);
524}
525
526void
527Thread::DiscardThreadPlans(bool force)
528{
529 // FIXME: It is not always safe to just discard plans. Some, like the step over
530 // breakpoint trap can't be discarded in general (though you can if you plan to
531 // force a return from a function, for instance.
532 // For now I'm just not clearing immediate plans, but I need a way for plans to
533 // say they really need to be kept on, and then a way to override that. Humm...
534
535 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
536 if (log)
537 {
538 log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force);
539 }
540
541 if (force)
542 {
543 int stack_size = m_plan_stack.size();
544 for (int i = stack_size - 1; i > 0; i--)
545 {
546 DiscardPlan();
547 }
548 return;
549 }
550
551 while (1)
552 {
553
554 int master_plan_idx;
555 bool discard;
556
557 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
558 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
559 {
560 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
561 {
562 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
563 break;
564 }
565 }
566
567 if (discard)
568 {
569 // First pop all the dependent plans:
570 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
571 {
572
573 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
574 // for the plan leaves it in a state that it is safe to pop the plan
575 // with no more notice?
576 DiscardPlan();
577 }
578
579 // Now discard the master plan itself.
580 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
581 // discard it's dependent plans, but not it...
582 if (master_plan_idx > 0)
583 {
584 DiscardPlan();
585 }
586 }
587 else
588 {
589 // If the master plan doesn't want to get discarded, then we're done.
590 break;
591 }
592
593 }
594 // FIXME: What should we do about the immediate plans?
595}
596
597ThreadPlan *
598Thread::QueueFundamentalPlan (bool abort_other_plans)
599{
600 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
601 QueueThreadPlan (thread_plan_sp, abort_other_plans);
602 return thread_plan_sp.get();
603}
604
605ThreadPlan *
606Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
607{
608 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
609 QueueThreadPlan (thread_plan_sp, abort_other_plans);
610 return thread_plan_sp.get();
611}
612
613ThreadPlan *
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000614Thread::QueueThreadPlanForStepRange
615(
616 bool abort_other_plans,
617 StepType type,
618 const AddressRange &range,
619 const SymbolContext &addr_context,
620 lldb::RunMode stop_other_threads,
621 bool avoid_code_without_debug_info
622)
Chris Lattner24943d22010-06-08 16:52:24 +0000623{
624 ThreadPlanSP thread_plan_sp;
625 if (type == eStepTypeInto)
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000626 {
627 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
628 if (avoid_code_without_debug_info)
629 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
630 else
631 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
632 thread_plan_sp.reset (plan);
633 }
Chris Lattner24943d22010-06-08 16:52:24 +0000634 else
635 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
636
637 QueueThreadPlan (thread_plan_sp, abort_other_plans);
638 return thread_plan_sp.get();
639}
640
641
642ThreadPlan *
643Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
644{
645 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
646 QueueThreadPlan (thread_plan_sp, abort_other_plans);
647 return thread_plan_sp.get();
648}
649
650ThreadPlan *
651Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
652 bool stop_other_threads, Vote stop_vote, Vote run_vote)
653{
654 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
655 QueueThreadPlan (thread_plan_sp, abort_other_plans);
656 return thread_plan_sp.get();
657}
658
659ThreadPlan *
660Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
661{
662 ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
663 if (thread_plan_sp.get() == NULL)
664 {
665 thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
666 if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
Greg Claytonf8e98a62010-07-23 15:37:46 +0000667 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000668 }
669 QueueThreadPlan (thread_plan_sp, abort_other_plans);
670 return thread_plan_sp.get();
671}
672
673ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +0000674Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
675 Address& function,
676 lldb::addr_t arg,
677 bool stop_other_threads,
678 bool discard_on_error)
679{
680 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
681 QueueThreadPlan (thread_plan_sp, abort_other_plans);
682 return thread_plan_sp.get();
683}
684
685ThreadPlan *
686Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
687 Address& function,
688 ValueList &args,
689 bool stop_other_threads,
690 bool discard_on_error)
691{
692 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
693 QueueThreadPlan (thread_plan_sp, abort_other_plans);
694 return thread_plan_sp.get();
695}
696
697ThreadPlan *
698Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
699 Address &target_addr,
700 bool stop_other_threads)
701{
702 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
703 QueueThreadPlan (thread_plan_sp, abort_other_plans);
704 return thread_plan_sp.get();
705}
706
707ThreadPlan *
708Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
709 lldb::addr_t *address_list,
710 size_t num_addresses,
711 bool stop_other_threads)
712{
713 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
714 QueueThreadPlan (thread_plan_sp, abort_other_plans);
715 return thread_plan_sp.get();
716
717}
718
719uint32_t
720Thread::GetIndexID () const
721{
722 return m_index_id;
723}
724
725void
726Thread::DumpThreadPlans (lldb_private::Stream *s) const
727{
728 uint32_t stack_size = m_plan_stack.size();
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000729 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 +0000730 for (int i = stack_size - 1; i > 0; i--)
731 {
732 s->Printf ("Element %d: ", i);
733 s->IndentMore();
734 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
735 s->IndentLess();
736 s->EOL();
737 }
738
739 stack_size = m_immediate_plan_stack.size();
740 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
741 for (int i = stack_size - 1; i > 0; i--)
742 {
743 s->Printf ("Element %d: ", i);
744 s->IndentMore();
745 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
746 s->IndentLess();
747 s->EOL();
748 }
749
750 stack_size = m_completed_plan_stack.size();
751 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
752 for (int i = stack_size - 1; i > 0; i--)
753 {
754 s->Printf ("Element %d: ", i);
755 s->IndentMore();
756 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
757 s->IndentLess();
758 s->EOL();
759 }
760
761 stack_size = m_discarded_plan_stack.size();
762 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
763 for (int i = stack_size - 1; i > 0; i--)
764 {
765 s->Printf ("Element %d: ", i);
766 s->IndentMore();
767 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
768 s->IndentLess();
769 s->EOL();
770 }
771
772}
773
774Target *
775Thread::CalculateTarget ()
776{
777 return m_process.CalculateTarget();
778}
779
780Process *
781Thread::CalculateProcess ()
782{
783 return &m_process;
784}
785
786Thread *
787Thread::CalculateThread ()
788{
789 return this;
790}
791
792StackFrame *
793Thread::CalculateStackFrame ()
794{
795 return NULL;
796}
797
798void
799Thread::Calculate (ExecutionContext &exe_ctx)
800{
801 m_process.Calculate (exe_ctx);
802 exe_ctx.thread = this;
803 exe_ctx.frame = NULL;
804}
805
Greg Clayton782b9cc2010-08-25 00:35:26 +0000806
807StackFrameList &
808Thread::GetStackFrameList ()
809{
Greg Claytonf40e3082010-08-26 02:28:22 +0000810 if (m_curr_frames_ap.get() == NULL)
Greg Clayton5205f0b2010-09-03 17:10:42 +0000811 m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_sp, true));
Greg Claytonf40e3082010-08-26 02:28:22 +0000812 return *m_curr_frames_ap;
Greg Clayton782b9cc2010-08-25 00:35:26 +0000813}
814
815
816
Jim Ingham71219082010-08-12 02:14:28 +0000817uint32_t
818Thread::GetStackFrameCount()
819{
Greg Clayton782b9cc2010-08-25 00:35:26 +0000820 return GetStackFrameList().GetNumFrames();
821}
Greg Clayton33ed1702010-08-24 00:45:41 +0000822
Greg Clayton33ed1702010-08-24 00:45:41 +0000823
Greg Clayton782b9cc2010-08-25 00:35:26 +0000824void
825Thread::ClearStackFrames ()
826{
Greg Clayton5205f0b2010-09-03 17:10:42 +0000827 if (m_curr_frames_ap.get() && m_curr_frames_ap->GetNumFrames (false) > 1)
828 m_prev_frames_sp.reset (m_curr_frames_ap.release());
829 else
830 m_curr_frames_ap.release();
831
832// StackFrameList::Merge (m_curr_frames_ap, m_prev_frames_sp);
833// assert (m_curr_frames_ap.get() == NULL);
Jim Ingham71219082010-08-12 02:14:28 +0000834}
835
836lldb::StackFrameSP
837Thread::GetStackFrameAtIndex (uint32_t idx)
838{
Greg Clayton72b71582010-09-02 21:44:10 +0000839 return GetStackFrameList().GetFrameAtIndex(idx);
Jim Ingham71219082010-08-12 02:14:28 +0000840}
841
Chris Lattner24943d22010-06-08 16:52:24 +0000842lldb::StackFrameSP
Jim Inghamc8332952010-08-26 21:32:51 +0000843Thread::GetSelectedFrame ()
Chris Lattner24943d22010-06-08 16:52:24 +0000844{
Jim Inghamc8332952010-08-26 21:32:51 +0000845 return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000846}
847
848uint32_t
Jim Inghamc8332952010-08-26 21:32:51 +0000849Thread::SetSelectedFrame (lldb_private::StackFrame *frame)
Chris Lattner24943d22010-06-08 16:52:24 +0000850{
Jim Inghamc8332952010-08-26 21:32:51 +0000851 return GetStackFrameList().SetSelectedFrame(frame);
Chris Lattner24943d22010-06-08 16:52:24 +0000852}
853
854void
Jim Inghamc8332952010-08-26 21:32:51 +0000855Thread::SetSelectedFrameByIndex (uint32_t idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000856{
Jim Inghamc8332952010-08-26 21:32:51 +0000857 GetStackFrameList().SetSelectedFrameByIndex(idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000858}
859
860void
861Thread::DumpInfo
862(
863 Stream &strm,
864 bool show_stop_reason,
865 bool show_name,
866 bool show_queue,
Greg Clayton33ed1702010-08-24 00:45:41 +0000867 uint32_t idx
Chris Lattner24943d22010-06-08 16:52:24 +0000868)
869{
870 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
871
Greg Clayton33ed1702010-08-24 00:45:41 +0000872 if (idx != LLDB_INVALID_INDEX32)
Chris Lattner24943d22010-06-08 16:52:24 +0000873 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000874 StackFrameSP frame_sp(GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000875 if (frame_sp)
876 {
877 strm.PutCString(", ");
Greg Clayton72b71582010-09-02 21:44:10 +0000878 frame_sp->Dump (&strm, false, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000879 }
880 }
881
882 if (show_stop_reason)
883 {
Greg Clayton643ee732010-08-04 01:40:35 +0000884 StopInfo *stop_info = GetStopInfo();
885
886 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +0000887 {
Greg Clayton643ee732010-08-04 01:40:35 +0000888 const char *stop_description = stop_info->GetDescription();
889 if (stop_description)
890 strm.Printf (", stop reason = %s", stop_description);
Chris Lattner24943d22010-06-08 16:52:24 +0000891 }
892 }
893
894 if (show_name)
895 {
896 const char *name = GetName();
897 if (name && name[0])
898 strm.Printf(", name = %s", name);
899 }
900
901 if (show_queue)
902 {
903 const char *queue = GetQueueName();
904 if (queue && queue[0])
905 strm.Printf(", queue = %s", queue);
906 }
907}
908
909lldb::ThreadSP
910Thread::GetSP ()
911{
912 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
913}