blob: d4fbfdf3bfb40c1d8b78d7a245d56579c2c9a842 [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"
Jim Ingham20594b12010-09-08 03:14:33 +000015#include "lldb/Core/RegularExpression.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Host/Host.h"
17#include "lldb/Target/DynamicLoader.h"
18#include "lldb/Target/ExecutionContext.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000021#include "lldb/Target/StopInfo.h"
Greg Clayton7661a982010-07-23 16:45:51 +000022#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Target/Thread.h"
24#include "lldb/Target/ThreadPlan.h"
25#include "lldb/Target/ThreadPlanCallFunction.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Target/ThreadPlanBase.h"
27#include "lldb/Target/ThreadPlanStepInstruction.h"
28#include "lldb/Target/ThreadPlanStepOut.h"
29#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
30#include "lldb/Target/ThreadPlanStepThrough.h"
31#include "lldb/Target/ThreadPlanStepInRange.h"
32#include "lldb/Target/ThreadPlanStepOverRange.h"
33#include "lldb/Target/ThreadPlanRunToAddress.h"
34#include "lldb/Target/ThreadPlanStepUntil.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000035#include "lldb/Target/ThreadSpec.h"
Jim Ingham71219082010-08-12 02:14:28 +000036#include "lldb/Target/Unwind.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
38using namespace lldb;
39using namespace lldb_private;
40
41Thread::Thread (Process &process, lldb::tid_t tid) :
42 UserID (tid),
Jim Ingham20594b12010-09-08 03:14:33 +000043 ThreadInstanceSettings (*(Thread::GetSettingsController().get())),
Benjamin Kramer36a08102010-07-16 12:32:33 +000044 m_process (process),
Greg Clayton643ee732010-08-04 01:40:35 +000045 m_public_stop_info_sp (),
46 m_actual_stop_info_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000047 m_index_id (process.GetNextThreadIndexID ()),
48 m_reg_context_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000049 m_state (eStateUnloaded),
Greg Clayton782b9cc2010-08-25 00:35:26 +000050 m_state_mutex (Mutex::eMutexTypeRecursive),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_plan_stack (),
52 m_immediate_plan_stack(),
53 m_completed_plan_stack(),
Greg Claytonf40e3082010-08-26 02:28:22 +000054 m_curr_frames_ap (),
Chris Lattner24943d22010-06-08 16:52:24 +000055 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
Jim Ingham71219082010-08-12 02:14:28 +000056 m_resume_state (eStateRunning),
57 m_unwinder_ap ()
58
Chris Lattner24943d22010-06-08 16:52:24 +000059{
60 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
61 if (log)
62 log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
63
64 QueueFundamentalPlan(true);
Caroline Tice1ebef442010-09-27 00:30:10 +000065 UpdateInstanceName();
Chris Lattner24943d22010-06-08 16:52:24 +000066}
67
68
69Thread::~Thread()
70{
71 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
72 if (log)
73 log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
74}
75
76int
77Thread::GetResumeSignal () const
78{
79 return m_resume_signal;
80}
81
82void
83Thread::SetResumeSignal (int signal)
84{
85 m_resume_signal = signal;
86}
87
88StateType
89Thread::GetResumeState () const
90{
91 return m_resume_state;
92}
93
94void
95Thread::SetResumeState (StateType state)
96{
97 m_resume_state = state;
98}
99
Greg Clayton643ee732010-08-04 01:40:35 +0000100StopInfo *
101Thread::GetStopInfo ()
Chris Lattner24943d22010-06-08 16:52:24 +0000102{
Greg Clayton643ee732010-08-04 01:40:35 +0000103 if (m_public_stop_info_sp.get() == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000104 {
Greg Clayton643ee732010-08-04 01:40:35 +0000105 ThreadPlanSP plan_sp (GetCompletedPlan());
106 if (plan_sp)
107 m_public_stop_info_sp = StopInfo::CreateStopReasonWithPlan (plan_sp);
108 else
109 m_public_stop_info_sp = GetPrivateStopReason ();
Chris Lattner24943d22010-06-08 16:52:24 +0000110 }
Greg Clayton643ee732010-08-04 01:40:35 +0000111 return m_public_stop_info_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000112}
113
114bool
115Thread::ThreadStoppedForAReason (void)
116{
Greg Clayton643ee732010-08-04 01:40:35 +0000117 return GetPrivateStopReason () != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000118}
119
120StateType
121Thread::GetState() const
122{
123 // If any other threads access this we will need a mutex for it
124 Mutex::Locker locker(m_state_mutex);
125 return m_state;
126}
127
128void
129Thread::SetState(StateType state)
130{
131 Mutex::Locker locker(m_state_mutex);
132 m_state = state;
133}
134
135void
136Thread::WillStop()
137{
138 ThreadPlan *current_plan = GetCurrentPlan();
139
140 // FIXME: I may decide to disallow threads with no plans. In which
141 // case this should go to an assert.
142
143 if (!current_plan)
144 return;
145
146 current_plan->WillStop();
147}
148
149void
150Thread::SetupForResume ()
151{
152 if (GetResumeState() != eStateSuspended)
153 {
154
155 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
156 // telling the current plan it will resume, since we might change what the current
157 // plan is.
158
159 lldb::addr_t pc = GetRegisterContext()->GetPC();
160 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
161 if (bp_site_sp && bp_site_sp->IsEnabled())
162 {
163 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
164 // special to step over a breakpoint.
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000165
166 ThreadPlan *cur_plan = GetCurrentPlan();
Chris Lattner24943d22010-06-08 16:52:24 +0000167
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000168 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
169 {
170 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
171 if (step_bp_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000172 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000173 ThreadPlanSP step_bp_plan_sp;
174 step_bp_plan->SetPrivate (true);
175
Chris Lattner24943d22010-06-08 16:52:24 +0000176 if (GetCurrentPlan()->RunState() != eStateStepping)
177 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000178 step_bp_plan->SetAutoContinue(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000179 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000180 step_bp_plan_sp.reset (step_bp_plan);
Chris Lattner24943d22010-06-08 16:52:24 +0000181 QueueThreadPlan (step_bp_plan_sp, false);
182 }
183 }
184 }
185 }
186}
187
188bool
189Thread::WillResume (StateType resume_state)
190{
191 // At this point clear the completed plan stack.
192 m_completed_plan_stack.clear();
193 m_discarded_plan_stack.clear();
194
Greg Clayton643ee732010-08-04 01:40:35 +0000195 StopInfo *stop_info = GetPrivateStopReason().get();
196 if (stop_info)
197 stop_info->WillResume (resume_state);
Chris Lattner24943d22010-06-08 16:52:24 +0000198
199 // Tell all the plans that we are about to resume in case they need to clear any state.
200 // We distinguish between the plan on the top of the stack and the lower
201 // plans in case a plan needs to do any special business before it runs.
202
203 ThreadPlan *plan_ptr = GetCurrentPlan();
204 plan_ptr->WillResume(resume_state, true);
205
206 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
207 {
208 plan_ptr->WillResume (resume_state, false);
209 }
Greg Clayton643ee732010-08-04 01:40:35 +0000210
211 m_public_stop_info_sp.reset();
212 m_actual_stop_info_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000213 return true;
214}
215
216void
217Thread::DidResume ()
218{
219 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
220}
221
222bool
223Thread::ShouldStop (Event* event_ptr)
224{
225 ThreadPlan *current_plan = GetCurrentPlan();
226 bool should_stop = true;
227
228 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
229 if (log)
230 {
231 StreamString s;
232 DumpThreadPlans(&s);
233 log->PutCString (s.GetData());
234 }
235
236 if (current_plan->PlanExplainsStop())
237 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000238 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000239 while (1)
240 {
241 should_stop = current_plan->ShouldStop(event_ptr);
242 if (current_plan->MischiefManaged())
243 {
244 if (should_stop)
245 current_plan->WillStop();
246
247 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
248 // Otherwise, see if the plan's parent wants to stop.
249
250 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
251 {
252 PopPlan();
253 break;
254 }
255 else
256 {
257
258 PopPlan();
259
260 current_plan = GetCurrentPlan();
261 if (current_plan == NULL)
262 {
263 break;
264 }
265 }
266
267 }
268 else
269 {
270 break;
271 }
272 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000273 if (over_ride_stop)
274 should_stop = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000275 }
276 else
277 {
278 // If the current plan doesn't explain the stop, then, find one that
279 // does and let it handle the situation.
280 ThreadPlan *plan_ptr = current_plan;
281 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
282 {
283 if (plan_ptr->PlanExplainsStop())
284 {
285 should_stop = plan_ptr->ShouldStop (event_ptr);
286 break;
287 }
288
289 }
290 }
291
292 return should_stop;
293}
294
295Vote
296Thread::ShouldReportStop (Event* event_ptr)
297{
298 StateType thread_state = GetResumeState ();
Greg Clayton5205f0b2010-09-03 17:10:42 +0000299 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
300
301 if (thread_state == eStateSuspended || thread_state == eStateInvalid)
302 {
303 if (log)
304 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 +0000305 return eVoteNoOpinion;
Greg Clayton5205f0b2010-09-03 17:10:42 +0000306 }
Chris Lattner24943d22010-06-08 16:52:24 +0000307
308 if (m_completed_plan_stack.size() > 0)
309 {
310 // Don't use GetCompletedPlan here, since that suppresses private plans.
Greg Clayton5205f0b2010-09-03 17:10:42 +0000311 if (log)
312 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 +0000313 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
314 }
315 else
Greg Clayton5205f0b2010-09-03 17:10:42 +0000316 {
317 if (log)
318 log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote for current plan\n", GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000319 return GetCurrentPlan()->ShouldReportStop (event_ptr);
Greg Clayton5205f0b2010-09-03 17:10:42 +0000320 }
Chris Lattner24943d22010-06-08 16:52:24 +0000321}
322
323Vote
324Thread::ShouldReportRun (Event* event_ptr)
325{
326 StateType thread_state = GetResumeState ();
327 if (thread_state == eStateSuspended
328 || thread_state == eStateInvalid)
329 return eVoteNoOpinion;
330
331 if (m_completed_plan_stack.size() > 0)
332 {
333 // Don't use GetCompletedPlan here, since that suppresses private plans.
334 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
335 }
336 else
337 return GetCurrentPlan()->ShouldReportRun (event_ptr);
338}
339
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000340bool
341Thread::MatchesSpec (const ThreadSpec *spec)
342{
343 if (spec == NULL)
344 return true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000345
Jim Ingham649492b2010-06-18 01:00:58 +0000346 return spec->ThreadPassesBasicTests(this);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000347}
348
Chris Lattner24943d22010-06-08 16:52:24 +0000349void
350Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
351{
352 if (thread_plan_sp)
353 {
354 if (thread_plan_sp->IsImmediate())
355 m_immediate_plan_stack.push_back (thread_plan_sp);
356 else
357 m_plan_stack.push_back (thread_plan_sp);
358
359 thread_plan_sp->DidPush();
360
361 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
362 if (log)
363 {
364 StreamString s;
365 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
Greg Claytonf04d6612010-09-03 22:45:01 +0000366 log->Printf("Pushing plan: \"%s\", tid = 0x%4.4x, immediate = %s.",
Chris Lattner24943d22010-06-08 16:52:24 +0000367 s.GetData(),
368 thread_plan_sp->GetThread().GetID(),
369 thread_plan_sp->IsImmediate() ? "true" : "false");
370 }
371 }
372}
373
374void
375Thread::PopPlan ()
376{
377 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
378
379 if (!m_immediate_plan_stack.empty())
380 {
381 ThreadPlanSP &plan = m_immediate_plan_stack.back();
382 if (log)
383 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000384 log->Printf("Popping plan: \"%s\", tid = 0x%4.4x, immediate = true.", plan->GetName(), plan->GetThread().GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000385 }
386 plan->WillPop();
387 m_immediate_plan_stack.pop_back();
388 }
389 else if (m_plan_stack.empty())
390 return;
391 else
392 {
393 ThreadPlanSP &plan = m_plan_stack.back();
394 if (log)
395 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000396 log->Printf("Popping plan: \"%s\", tid = 0x%4.4x, immediate = false.", plan->GetName(), plan->GetThread().GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000397 }
398 m_completed_plan_stack.push_back (plan);
399 plan->WillPop();
400 m_plan_stack.pop_back();
401 }
402}
403
404void
405Thread::DiscardPlan ()
406{
407 if (m_plan_stack.size() > 1)
408 {
409 ThreadPlanSP &plan = m_plan_stack.back();
410 m_discarded_plan_stack.push_back (plan);
411 plan->WillPop();
412 m_plan_stack.pop_back();
413 }
414}
415
416ThreadPlan *
417Thread::GetCurrentPlan ()
418{
419 if (!m_immediate_plan_stack.empty())
420 return m_immediate_plan_stack.back().get();
421 else if (m_plan_stack.empty())
422 return NULL;
423 else
424 return m_plan_stack.back().get();
425}
426
427ThreadPlanSP
428Thread::GetCompletedPlan ()
429{
430 ThreadPlanSP empty_plan_sp;
431 if (!m_completed_plan_stack.empty())
432 {
433 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
434 {
435 ThreadPlanSP completed_plan_sp;
436 completed_plan_sp = m_completed_plan_stack[i];
437 if (!completed_plan_sp->GetPrivate ())
438 return completed_plan_sp;
439 }
440 }
441 return empty_plan_sp;
442}
443
444bool
445Thread::IsThreadPlanDone (ThreadPlan *plan)
446{
447 ThreadPlanSP empty_plan_sp;
448 if (!m_completed_plan_stack.empty())
449 {
450 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
451 {
452 if (m_completed_plan_stack[i].get() == plan)
453 return true;
454 }
455 }
456 return false;
457}
458
459bool
460Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
461{
462 ThreadPlanSP empty_plan_sp;
463 if (!m_discarded_plan_stack.empty())
464 {
465 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
466 {
467 if (m_discarded_plan_stack[i].get() == plan)
468 return true;
469 }
470 }
471 return false;
472}
473
474ThreadPlan *
475Thread::GetPreviousPlan (ThreadPlan *current_plan)
476{
477 if (current_plan == NULL)
478 return NULL;
479
480 int stack_size = m_completed_plan_stack.size();
481 for (int i = stack_size - 1; i > 0; i--)
482 {
483 if (current_plan == m_completed_plan_stack[i].get())
484 return m_completed_plan_stack[i-1].get();
485 }
486
487 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
488 {
489 if (m_immediate_plan_stack.size() > 0)
490 return m_immediate_plan_stack.back().get();
491 else if (m_plan_stack.size() > 0)
492 return m_plan_stack.back().get();
493 else
494 return NULL;
495 }
496
497 stack_size = m_immediate_plan_stack.size();
498 for (int i = stack_size - 1; i > 0; i--)
499 {
500 if (current_plan == m_immediate_plan_stack[i].get())
501 return m_immediate_plan_stack[i-1].get();
502 }
503 if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
504 {
505 if (m_plan_stack.size() > 0)
506 return m_plan_stack.back().get();
507 else
508 return NULL;
509 }
510
511 stack_size = m_plan_stack.size();
512 for (int i = stack_size - 1; i > 0; i--)
513 {
514 if (current_plan == m_plan_stack[i].get())
515 return m_plan_stack[i-1].get();
516 }
517 return NULL;
518}
519
520void
521Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
522{
523 if (abort_other_plans)
524 DiscardThreadPlans(true);
525
526 PushPlan (thread_plan_sp);
527}
528
529void
530Thread::DiscardThreadPlans(bool force)
531{
532 // FIXME: It is not always safe to just discard plans. Some, like the step over
533 // breakpoint trap can't be discarded in general (though you can if you plan to
534 // force a return from a function, for instance.
535 // For now I'm just not clearing immediate plans, but I need a way for plans to
536 // say they really need to be kept on, and then a way to override that. Humm...
537
538 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
539 if (log)
540 {
Greg Claytonf04d6612010-09-03 22:45:01 +0000541 log->Printf("Discarding thread plans for thread (tid = 0x%4.4x, force %d)", GetID(), force);
Chris Lattner24943d22010-06-08 16:52:24 +0000542 }
543
544 if (force)
545 {
546 int stack_size = m_plan_stack.size();
547 for (int i = stack_size - 1; i > 0; i--)
548 {
549 DiscardPlan();
550 }
551 return;
552 }
553
554 while (1)
555 {
556
557 int master_plan_idx;
558 bool discard;
559
560 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
561 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
562 {
563 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
564 {
565 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
566 break;
567 }
568 }
569
570 if (discard)
571 {
572 // First pop all the dependent plans:
573 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
574 {
575
576 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
577 // for the plan leaves it in a state that it is safe to pop the plan
578 // with no more notice?
579 DiscardPlan();
580 }
581
582 // Now discard the master plan itself.
583 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
584 // discard it's dependent plans, but not it...
585 if (master_plan_idx > 0)
586 {
587 DiscardPlan();
588 }
589 }
590 else
591 {
592 // If the master plan doesn't want to get discarded, then we're done.
593 break;
594 }
595
596 }
597 // FIXME: What should we do about the immediate plans?
598}
599
600ThreadPlan *
601Thread::QueueFundamentalPlan (bool abort_other_plans)
602{
603 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
604 QueueThreadPlan (thread_plan_sp, abort_other_plans);
605 return thread_plan_sp.get();
606}
607
608ThreadPlan *
609Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
610{
611 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
612 QueueThreadPlan (thread_plan_sp, abort_other_plans);
613 return thread_plan_sp.get();
614}
615
616ThreadPlan *
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000617Thread::QueueThreadPlanForStepRange
618(
619 bool abort_other_plans,
620 StepType type,
621 const AddressRange &range,
622 const SymbolContext &addr_context,
623 lldb::RunMode stop_other_threads,
624 bool avoid_code_without_debug_info
625)
Chris Lattner24943d22010-06-08 16:52:24 +0000626{
627 ThreadPlanSP thread_plan_sp;
628 if (type == eStepTypeInto)
Greg Clayton8f5fd6b2010-06-12 18:59:55 +0000629 {
630 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
631 if (avoid_code_without_debug_info)
632 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
633 else
634 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
635 thread_plan_sp.reset (plan);
636 }
Chris Lattner24943d22010-06-08 16:52:24 +0000637 else
638 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
639
640 QueueThreadPlan (thread_plan_sp, abort_other_plans);
641 return thread_plan_sp.get();
642}
643
644
645ThreadPlan *
646Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
647{
648 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
649 QueueThreadPlan (thread_plan_sp, abort_other_plans);
650 return thread_plan_sp.get();
651}
652
653ThreadPlan *
654Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
655 bool stop_other_threads, Vote stop_vote, Vote run_vote)
656{
657 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
658 QueueThreadPlan (thread_plan_sp, abort_other_plans);
659 return thread_plan_sp.get();
660}
661
662ThreadPlan *
663Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
664{
665 ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
666 if (thread_plan_sp.get() == NULL)
667 {
668 thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
669 if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
Greg Claytonf8e98a62010-07-23 15:37:46 +0000670 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000671 }
672 QueueThreadPlan (thread_plan_sp, abort_other_plans);
673 return thread_plan_sp.get();
674}
675
676ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +0000677Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
678 Address& function,
679 lldb::addr_t arg,
680 bool stop_other_threads,
681 bool discard_on_error)
682{
683 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
684 QueueThreadPlan (thread_plan_sp, abort_other_plans);
685 return thread_plan_sp.get();
686}
687
688ThreadPlan *
689Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
690 Address& function,
691 ValueList &args,
692 bool stop_other_threads,
693 bool discard_on_error)
694{
695 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
696 QueueThreadPlan (thread_plan_sp, abort_other_plans);
697 return thread_plan_sp.get();
698}
699
700ThreadPlan *
701Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
702 Address &target_addr,
703 bool stop_other_threads)
704{
705 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
706 QueueThreadPlan (thread_plan_sp, abort_other_plans);
707 return thread_plan_sp.get();
708}
709
710ThreadPlan *
711Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
712 lldb::addr_t *address_list,
713 size_t num_addresses,
714 bool stop_other_threads)
715{
716 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
717 QueueThreadPlan (thread_plan_sp, abort_other_plans);
718 return thread_plan_sp.get();
719
720}
721
722uint32_t
723Thread::GetIndexID () const
724{
725 return m_index_id;
726}
727
728void
729Thread::DumpThreadPlans (lldb_private::Stream *s) const
730{
731 uint32_t stack_size = m_plan_stack.size();
Greg Claytonf04d6612010-09-03 22:45:01 +0000732 int i;
733 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x, stack_size = %d\n", GetIndexID(), GetID(), stack_size);
734 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000735 {
736 s->Printf ("Element %d: ", i);
737 s->IndentMore();
738 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
739 s->IndentLess();
740 s->EOL();
741 }
742
743 stack_size = m_immediate_plan_stack.size();
744 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000745 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000746 {
747 s->Printf ("Element %d: ", i);
748 s->IndentMore();
749 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
750 s->IndentLess();
751 s->EOL();
752 }
753
754 stack_size = m_completed_plan_stack.size();
755 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000756 for (i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000757 {
758 s->Printf ("Element %d: ", i);
759 s->IndentMore();
760 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
761 s->IndentLess();
762 s->EOL();
763 }
764
765 stack_size = m_discarded_plan_stack.size();
766 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
Greg Claytonf04d6612010-09-03 22:45:01 +0000767 for (int i = stack_size - 1; i >= 0; i--)
Chris Lattner24943d22010-06-08 16:52:24 +0000768 {
769 s->Printf ("Element %d: ", i);
770 s->IndentMore();
771 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
772 s->IndentLess();
773 s->EOL();
774 }
775
776}
777
778Target *
779Thread::CalculateTarget ()
780{
781 return m_process.CalculateTarget();
782}
783
784Process *
785Thread::CalculateProcess ()
786{
787 return &m_process;
788}
789
790Thread *
791Thread::CalculateThread ()
792{
793 return this;
794}
795
796StackFrame *
797Thread::CalculateStackFrame ()
798{
799 return NULL;
800}
801
802void
803Thread::Calculate (ExecutionContext &exe_ctx)
804{
805 m_process.Calculate (exe_ctx);
806 exe_ctx.thread = this;
807 exe_ctx.frame = NULL;
808}
809
Greg Clayton782b9cc2010-08-25 00:35:26 +0000810
811StackFrameList &
812Thread::GetStackFrameList ()
813{
Greg Claytonf40e3082010-08-26 02:28:22 +0000814 if (m_curr_frames_ap.get() == NULL)
Greg Clayton5205f0b2010-09-03 17:10:42 +0000815 m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_sp, true));
Greg Claytonf40e3082010-08-26 02:28:22 +0000816 return *m_curr_frames_ap;
Greg Clayton782b9cc2010-08-25 00:35:26 +0000817}
818
819
820
Jim Ingham71219082010-08-12 02:14:28 +0000821uint32_t
822Thread::GetStackFrameCount()
823{
Greg Clayton782b9cc2010-08-25 00:35:26 +0000824 return GetStackFrameList().GetNumFrames();
825}
Greg Clayton33ed1702010-08-24 00:45:41 +0000826
Greg Clayton33ed1702010-08-24 00:45:41 +0000827
Greg Clayton782b9cc2010-08-25 00:35:26 +0000828void
829Thread::ClearStackFrames ()
830{
Greg Clayton5205f0b2010-09-03 17:10:42 +0000831 if (m_curr_frames_ap.get() && m_curr_frames_ap->GetNumFrames (false) > 1)
832 m_prev_frames_sp.reset (m_curr_frames_ap.release());
833 else
834 m_curr_frames_ap.release();
835
836// StackFrameList::Merge (m_curr_frames_ap, m_prev_frames_sp);
837// assert (m_curr_frames_ap.get() == NULL);
Jim Ingham71219082010-08-12 02:14:28 +0000838}
839
840lldb::StackFrameSP
841Thread::GetStackFrameAtIndex (uint32_t idx)
842{
Greg Clayton72b71582010-09-02 21:44:10 +0000843 return GetStackFrameList().GetFrameAtIndex(idx);
Jim Ingham71219082010-08-12 02:14:28 +0000844}
845
Chris Lattner24943d22010-06-08 16:52:24 +0000846lldb::StackFrameSP
Jim Inghamc8332952010-08-26 21:32:51 +0000847Thread::GetSelectedFrame ()
Chris Lattner24943d22010-06-08 16:52:24 +0000848{
Jim Inghamc8332952010-08-26 21:32:51 +0000849 return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex());
Chris Lattner24943d22010-06-08 16:52:24 +0000850}
851
852uint32_t
Jim Inghamc8332952010-08-26 21:32:51 +0000853Thread::SetSelectedFrame (lldb_private::StackFrame *frame)
Chris Lattner24943d22010-06-08 16:52:24 +0000854{
Jim Inghamc8332952010-08-26 21:32:51 +0000855 return GetStackFrameList().SetSelectedFrame(frame);
Chris Lattner24943d22010-06-08 16:52:24 +0000856}
857
858void
Jim Inghamc8332952010-08-26 21:32:51 +0000859Thread::SetSelectedFrameByIndex (uint32_t idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000860{
Jim Inghamc8332952010-08-26 21:32:51 +0000861 GetStackFrameList().SetSelectedFrameByIndex(idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000862}
863
864void
865Thread::DumpInfo
866(
867 Stream &strm,
868 bool show_stop_reason,
869 bool show_name,
870 bool show_queue,
Greg Clayton33ed1702010-08-24 00:45:41 +0000871 uint32_t idx
Chris Lattner24943d22010-06-08 16:52:24 +0000872)
873{
874 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
875
Greg Clayton33ed1702010-08-24 00:45:41 +0000876 if (idx != LLDB_INVALID_INDEX32)
Chris Lattner24943d22010-06-08 16:52:24 +0000877 {
Greg Clayton33ed1702010-08-24 00:45:41 +0000878 StackFrameSP frame_sp(GetStackFrameAtIndex (idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000879 if (frame_sp)
880 {
881 strm.PutCString(", ");
Greg Clayton72b71582010-09-02 21:44:10 +0000882 frame_sp->Dump (&strm, false, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000883 }
884 }
885
886 if (show_stop_reason)
887 {
Greg Clayton643ee732010-08-04 01:40:35 +0000888 StopInfo *stop_info = GetStopInfo();
889
890 if (stop_info)
Chris Lattner24943d22010-06-08 16:52:24 +0000891 {
Greg Clayton643ee732010-08-04 01:40:35 +0000892 const char *stop_description = stop_info->GetDescription();
893 if (stop_description)
894 strm.Printf (", stop reason = %s", stop_description);
Chris Lattner24943d22010-06-08 16:52:24 +0000895 }
896 }
897
898 if (show_name)
899 {
900 const char *name = GetName();
901 if (name && name[0])
902 strm.Printf(", name = %s", name);
903 }
904
905 if (show_queue)
906 {
907 const char *queue = GetQueueName();
908 if (queue && queue[0])
909 strm.Printf(", queue = %s", queue);
910 }
911}
912
913lldb::ThreadSP
914Thread::GetSP ()
915{
916 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
917}
Jim Ingham20594b12010-09-08 03:14:33 +0000918
919lldb::UserSettingsControllerSP
920Thread::GetSettingsController (bool finish)
921{
922 static UserSettingsControllerSP g_settings_controller (new ThreadSettingsController);
923 static bool initialized = false;
924
925 if (!initialized)
926 {
927 initialized = UserSettingsController::InitializeSettingsController (g_settings_controller,
928 Thread::ThreadSettingsController::global_settings_table,
929 Thread::ThreadSettingsController::instance_settings_table);
930 }
931
932 if (finish)
933 {
934 UserSettingsController::FinalizeSettingsController (g_settings_controller);
935 g_settings_controller.reset();
936 initialized = false;
937 }
938
939 return g_settings_controller;
940}
941
Caroline Tice1ebef442010-09-27 00:30:10 +0000942void
943Thread::UpdateInstanceName ()
944{
945 StreamString sstr;
946 const char *name = GetName();
947
948 if (name && name[0] != '\0')
949 sstr.Printf ("%s", name);
950 else if ((GetIndexID() != 0) || (GetID() != 0))
951 sstr.Printf ("0x%4.4x", GetIndexID(), GetID());
952
953 if (sstr.GetSize() > 0)
954 Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData());
955}
956
Jim Ingham20594b12010-09-08 03:14:33 +0000957//--------------------------------------------------------------
958// class Thread::ThreadSettingsController
959//--------------------------------------------------------------
960
961Thread::ThreadSettingsController::ThreadSettingsController () :
962 UserSettingsController ("thread", Process::GetSettingsController())
963{
Caroline Tice004afcb2010-09-08 17:48:55 +0000964 m_default_settings.reset (new ThreadInstanceSettings (*this, false,
965 InstanceSettings::GetDefaultName().AsCString()));
Jim Ingham20594b12010-09-08 03:14:33 +0000966}
967
968Thread::ThreadSettingsController::~ThreadSettingsController ()
969{
970}
971
972lldb::InstanceSettingsSP
Greg Claytond0a5a232010-09-19 02:33:57 +0000973Thread::ThreadSettingsController::CreateInstanceSettings (const char *instance_name)
Jim Ingham20594b12010-09-08 03:14:33 +0000974{
Caroline Tice004afcb2010-09-08 17:48:55 +0000975 ThreadInstanceSettings *new_settings = new ThreadInstanceSettings (*(Thread::GetSettingsController().get()),
976 false, instance_name);
Jim Ingham20594b12010-09-08 03:14:33 +0000977 lldb::InstanceSettingsSP new_settings_sp (new_settings);
978 return new_settings_sp;
979}
980
981//--------------------------------------------------------------
982// class ThreadInstanceSettings
983//--------------------------------------------------------------
984
Caroline Tice004afcb2010-09-08 17:48:55 +0000985ThreadInstanceSettings::ThreadInstanceSettings (UserSettingsController &owner, bool live_instance, const char *name) :
Caroline Tice75b11a32010-09-16 19:05:55 +0000986 InstanceSettings (owner, (name == NULL ? InstanceSettings::InvalidName().AsCString() : name), live_instance),
Jim Ingham20594b12010-09-08 03:14:33 +0000987 m_avoid_regexp_ap ()
988{
Caroline Tice396704b2010-09-09 18:26:37 +0000989 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
990 // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers.
991 // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
Caroline Tice75b11a32010-09-16 19:05:55 +0000992 // This is true for CreateInstanceName() too.
993
994 if (GetInstanceName() == InstanceSettings::InvalidName())
995 {
996 ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
997 m_owner.RegisterInstanceSettings (this);
998 }
Caroline Tice396704b2010-09-09 18:26:37 +0000999
1000 if (live_instance)
Jim Ingham20594b12010-09-08 03:14:33 +00001001 {
1002 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1003 CopyInstanceSettings (pending_settings,false);
Caroline Tice396704b2010-09-09 18:26:37 +00001004 //m_owner.RemovePendingSettings (m_instance_name);
Jim Ingham20594b12010-09-08 03:14:33 +00001005 }
1006}
1007
1008ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) :
1009 InstanceSettings (*(Thread::GetSettingsController().get()), CreateInstanceName().AsCString()),
1010 m_avoid_regexp_ap ()
1011{
1012 if (m_instance_name != InstanceSettings::GetDefaultName())
1013 {
1014 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1015 CopyInstanceSettings (pending_settings,false);
1016 m_owner.RemovePendingSettings (m_instance_name);
1017 }
1018 if (rhs.m_avoid_regexp_ap.get() != NULL)
1019 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
1020}
1021
1022ThreadInstanceSettings::~ThreadInstanceSettings ()
1023{
1024}
1025
1026ThreadInstanceSettings&
1027ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs)
1028{
1029 if (this != &rhs)
1030 {
1031 if (rhs.m_avoid_regexp_ap.get() != NULL)
1032 m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
1033 else
1034 m_avoid_regexp_ap.reset(NULL);
1035 }
1036
1037 return *this;
1038}
1039
1040
1041void
1042ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1043 const char *index_value,
1044 const char *value,
1045 const ConstString &instance_name,
1046 const SettingEntry &entry,
1047 lldb::VarSetOperationType op,
1048 Error &err,
1049 bool pending)
1050{
1051 if (var_name == StepAvoidRegexpVarName())
1052 {
1053 std::string regexp_text;
1054 if (m_avoid_regexp_ap.get() != NULL)
1055 regexp_text.append (m_avoid_regexp_ap->GetText());
1056 UserSettingsController::UpdateStringVariable (op, regexp_text, value, err);
1057 if (regexp_text.empty())
1058 m_avoid_regexp_ap.reset();
1059 else
1060 {
1061 m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str()));
1062
1063 }
1064 }
1065}
1066
1067void
1068ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1069 bool pending)
1070{
1071 if (new_settings.get() == NULL)
1072 return;
1073
1074 ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get();
1075 if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL)
1076 m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText()));
1077 else
1078 m_avoid_regexp_ap.reset ();
1079}
1080
Caroline Ticebcb5b452010-09-20 21:37:42 +00001081bool
Jim Ingham20594b12010-09-08 03:14:33 +00001082ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
Caroline Tice5bc8c972010-09-20 20:44:43 +00001083 const ConstString &var_name,
1084 StringList &value,
Caroline Ticebcb5b452010-09-20 21:37:42 +00001085 Error *err)
Jim Ingham20594b12010-09-08 03:14:33 +00001086{
1087 if (var_name == StepAvoidRegexpVarName())
1088 {
1089 if (m_avoid_regexp_ap.get() != NULL)
1090 {
1091 std::string regexp_text("\"");
1092 regexp_text.append(m_avoid_regexp_ap->GetText());
1093 regexp_text.append ("\"");
1094 value.AppendString (regexp_text.c_str());
1095 }
Caroline Tice5bc8c972010-09-20 20:44:43 +00001096
Jim Ingham20594b12010-09-08 03:14:33 +00001097 }
1098 else
Caroline Ticebcb5b452010-09-20 21:37:42 +00001099 {
1100 if (err)
1101 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1102 return false;
1103 }
1104 return true;
Jim Ingham20594b12010-09-08 03:14:33 +00001105}
1106
Jim Ingham20594b12010-09-08 03:14:33 +00001107const ConstString
1108ThreadInstanceSettings::CreateInstanceName ()
1109{
1110 static int instance_count = 1;
1111 StreamString sstr;
1112
1113 sstr.Printf ("thread_%d", instance_count);
1114 ++instance_count;
1115
1116 const ConstString ret_val (sstr.GetData());
1117 return ret_val;
1118}
1119
1120const ConstString &
1121ThreadInstanceSettings::StepAvoidRegexpVarName ()
1122{
1123 static ConstString run_args_var_name ("step-avoid-regexp");
1124
1125 return run_args_var_name;
1126}
1127
1128//--------------------------------------------------
1129// ThreadSettingsController Variable Tables
1130//--------------------------------------------------
1131
1132SettingEntry
1133Thread::ThreadSettingsController::global_settings_table[] =
1134{
1135 //{ "var-name", var-type , "default", enum-table, init'd, hidden, "help-text"},
1136 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1137};
1138
1139
1140SettingEntry
1141Thread::ThreadSettingsController::instance_settings_table[] =
1142{
1143 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
1144 { "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." },
1145 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1146};
1147
Jim Inghamccd584d2010-09-23 17:40:12 +00001148lldb::StackFrameSP
1149Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
1150{
1151 return GetStackFrameList().GetStackFrameSPForStackFramePtr (stack_frame_ptr);
1152}