blob: 050c103b2ca3d0a5c35f32f4857ab2cbbc062eab [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);
Greg Claytonf04d6612010-09-03 22:45:01 +0000363 log->Printf("Pushing plan: \"%s\", tid = 0x%4.4x, immediate = %s.",
Chris Lattner24943d22010-06-08 16:52:24 +0000364 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 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000381 log->Printf("Popping plan: \"%s\", tid = 0x%4.4x, immediate = true.", plan->GetName(), plan->GetThread().GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000382 }
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 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000393 log->Printf("Popping plan: \"%s\", tid = 0x%4.4x, immediate = false.", plan->GetName(), plan->GetThread().GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000394 }
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 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000538 log->Printf("Discarding thread plans for thread (tid = 0x%4.4x, force %d)", GetID(), force);
Chris Lattner24943d22010-06-08 16:52:24 +0000539 }
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();
Greg Claytonf04d6612010-09-03 22:45:01 +0000729 int i;
730 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x, stack_size = %d\n", GetIndexID(), GetID(), stack_size);
731 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000732 {
733 s->Printf ("Element %d: ", i);
734 s->IndentMore();
735 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
736 s->IndentLess();
737 s->EOL();
738 }
739
740 stack_size = m_immediate_plan_stack.size();
741 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000742 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000743 {
744 s->Printf ("Element %d: ", i);
745 s->IndentMore();
746 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
747 s->IndentLess();
748 s->EOL();
749 }
750
751 stack_size = m_completed_plan_stack.size();
752 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000753 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000754 {
755 s->Printf ("Element %d: ", i);
756 s->IndentMore();
757 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
758 s->IndentLess();
759 s->EOL();
760 }
761
762 stack_size = m_discarded_plan_stack.size();
763 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000764 for (int i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000765 {
766 s->Printf ("Element %d: ", i);
767 s->IndentMore();
768 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
769 s->IndentLess();
770 s->EOL();
771 }
772
773}
774
775Target *
776Thread::CalculateTarget ()
777{
778 return m_process.CalculateTarget();
779}
780
781Process *
782Thread::CalculateProcess ()
783{
784 return &m_process;
785}
786
787Thread *
788Thread::CalculateThread ()
789{
790 return this;
791}
792
793StackFrame *
794Thread::CalculateStackFrame ()
795{
796 return NULL;
797}
798
799void
800Thread::Calculate (ExecutionContext &exe_ctx)
801{
802 m_process.Calculate (exe_ctx);
803 exe_ctx.thread = this;
804 exe_ctx.frame = NULL;
805}
806
Greg Clayton782b9cc2010-08-25 00:35:26 +0000807
808StackFrameList &
809Thread::GetStackFrameList ()
810{
Greg Claytonf40e3082010-08-26 02:28:22 +0000811 if (m_curr_frames_ap.get() == NULL)
Greg Clayton5205f0b2010-09-03 17:10:42 +0000812 m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_sp, true));
Greg Claytonf40e3082010-08-26 02:28:22 +0000813 return *m_curr_frames_ap;
Greg Clayton782b9cc2010-08-25 00:35:26 +0000814}
815
816
817
Jim Ingham71219082010-08-12 02:14:28 +0000818uint32_t
819Thread::GetStackFrameCount()
820{
Greg Clayton782b9cc2010-08-25 00:35:26 +0000821 return GetStackFrameList().GetNumFrames();
822}
Greg Clayton33ed1702010-08-24 00:45:41 +0000823
Greg Clayton33ed1702010-08-24 00:45:41 +0000824
Greg Clayton782b9cc2010-08-25 00:35:26 +0000825void
826Thread::ClearStackFrames ()
827{
Greg Clayton5205f0b2010-09-03 17:10:42 +0000828 if (m_curr_frames_ap.get() && m_curr_frames_ap->GetNumFrames (false) > 1)
829 m_prev_frames_sp.reset (m_curr_frames_ap.release());
830 else
831 m_curr_frames_ap.release();
832
833// StackFrameList::Merge (m_curr_frames_ap, m_prev_frames_sp);
834// assert (m_curr_frames_ap.get() == NULL);
Jim Ingham71219082010-08-12 02:14:28 +0000835}
836
837lldb::StackFrameSP
838Thread::GetStackFrameAtIndex (uint32_t idx)
839{
Greg Clayton72b71582010-09-02 21:44:10 +0000840 return GetStackFrameList().GetFrameAtIndex(idx);
Jim Ingham71219082010-08-12 02:14:28 +0000841}
842
Chris Lattner24943d22010-06-08 16:52:24 +0000843lldb::StackFrameSP
Jim Inghamc8332952010-08-26 21:32:51 +0000844Thread::GetSelectedFrame ()
Chris Lattner24943d22010-06-08 16:52:24 +0000845{
Jim Inghamc8332952010-08-26 21:32:51 +0000846 return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000847}
848
849uint32_t
Jim Inghamc8332952010-08-26 21:32:51 +0000850Thread::SetSelectedFrame (lldb_private::StackFrame *frame)
Chris Lattner24943d22010-06-08 16:52:24 +0000851{
Jim Inghamc8332952010-08-26 21:32:51 +0000852 return GetStackFrameList().SetSelectedFrame(frame);
Chris Lattner24943d22010-06-08 16:52:24 +0000853}
854
855void
Jim Inghamc8332952010-08-26 21:32:51 +0000856Thread::SetSelectedFrameByIndex (uint32_t idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000857{
Jim Inghamc8332952010-08-26 21:32:51 +0000858 GetStackFrameList().SetSelectedFrameByIndex(idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000859}
860
861void
862Thread::DumpInfo
863(
864 Stream &strm,
865 bool show_stop_reason,
866 bool show_name,
867 bool show_queue,
Greg Clayton33ed1702010-08-24 00:45:41 +0000868 uint32_t idx
Chris Lattner24943d22010-06-08 16:52:24 +0000869)
870{
871 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
872
Greg Clayton33ed1702010-08-24 00:45:41 +0000873 if (idx != LLDB_INVALID_INDEX32)
Chris Lattner24943d22010-06-08 16:52:24 +0000874 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000875 StackFrameSP frame_sp(GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000876 if (frame_sp)
877 {
878 strm.PutCString(", ");
Greg Clayton72b71582010-09-02 21:44:10 +0000879 frame_sp->Dump (&strm, false, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000880 }
881 }
882
883 if (show_stop_reason)
884 {
Greg Clayton643ee732010-08-04 01:40:35 +0000885 StopInfo *stop_info = GetStopInfo();
886
887 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +0000888 {
Greg Clayton643ee732010-08-04 01:40:35 +0000889 const char *stop_description = stop_info->GetDescription();
890 if (stop_description)
891 strm.Printf (", stop reason = %s", stop_description);
Chris Lattner24943d22010-06-08 16:52:24 +0000892 }
893 }
894
895 if (show_name)
896 {
897 const char *name = GetName();
898 if (name && name[0])
899 strm.Printf(", name = %s", name);
900 }
901
902 if (show_queue)
903 {
904 const char *queue = GetQueueName();
905 if (queue && queue[0])
906 strm.Printf(", queue = %s", queue);
907 }
908}
909
910lldb::ThreadSP
911Thread::GetSP ()
912{
913 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
914}