1 //===-- Thread.cpp ----------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-private-log.h"
11 #include "lldb/Breakpoint/BreakpointLocation.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Core/Stream.h"
15 #include "lldb/Core/StreamString.h"
16 #include "lldb/Core/RegularExpression.h"
17 #include "lldb/Host/Host.h"
18 #include "lldb/Target/DynamicLoader.h"
19 #include "lldb/Target/ExecutionContext.h"
20 #include "lldb/Target/ObjCLanguageRuntime.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/StopInfo.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Target/ThreadPlan.h"
27 #include "lldb/Target/ThreadPlanCallFunction.h"
28 #include "lldb/Target/ThreadPlanBase.h"
29 #include "lldb/Target/ThreadPlanStepInstruction.h"
30 #include "lldb/Target/ThreadPlanStepOut.h"
31 #include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
32 #include "lldb/Target/ThreadPlanStepThrough.h"
33 #include "lldb/Target/ThreadPlanStepInRange.h"
34 #include "lldb/Target/ThreadPlanStepOverRange.h"
35 #include "lldb/Target/ThreadPlanRunToAddress.h"
36 #include "lldb/Target/ThreadPlanStepUntil.h"
37 #include "lldb/Target/ThreadSpec.h"
38 #include "lldb/Target/Unwind.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 Thread::Thread (Process &process, lldb::tid_t tid) :
44     UserID (tid),
45     ThreadInstanceSettings (*GetSettingsController()),
46     m_process (process),
47     m_actual_stop_info_sp (),
48     m_index_id (process.GetNextThreadIndexID ()),
49     m_reg_context_sp (),
50     m_state (eStateUnloaded),
51     m_state_mutex (Mutex::eMutexTypeRecursive),
52     m_plan_stack (),
53     m_completed_plan_stack(),
54     m_curr_frames_ap (),
55     m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
56     m_resume_state (eStateRunning),
57     m_unwinder_ap (),
58     m_destroy_called (false),
59     m_thread_stop_reason_stop_id (0)
60 
61 {
62     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
63     if (log)
64         log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
65 
66     QueueFundamentalPlan(true);
67     UpdateInstanceName();
68 }
69 
70 
71 Thread::~Thread()
72 {
73     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
74     if (log)
75         log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
76     /// If you hit this assert, it means your derived class forgot to call DoDestroy in its destructor.
77     assert (m_destroy_called);
78 }
79 
80 void
81 Thread::DestroyThread ()
82 {
83     m_plan_stack.clear();
84     m_discarded_plan_stack.clear();
85     m_completed_plan_stack.clear();
86     m_destroy_called = true;
87 }
88 
89 lldb::StopInfoSP
90 Thread::GetStopInfo ()
91 {
92     ThreadPlanSP plan_sp (GetCompletedPlan());
93     if (plan_sp)
94         return StopInfo::CreateStopReasonWithPlan (plan_sp);
95     else
96     {
97         if (m_actual_stop_info_sp
98             && m_actual_stop_info_sp->IsValid()
99             && m_thread_stop_reason_stop_id == m_process.GetStopID())
100             return m_actual_stop_info_sp;
101         else
102             return GetPrivateStopReason ();
103     }
104 }
105 
106 void
107 Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp)
108 {
109     m_actual_stop_info_sp = stop_info_sp;
110     if (m_actual_stop_info_sp)
111         m_actual_stop_info_sp->MakeStopInfoValid();
112     m_thread_stop_reason_stop_id = GetProcess().GetStopID();
113 }
114 
115 void
116 Thread::SetStopInfoToNothing()
117 {
118     // Note, we can't just NULL out the private reason, or the native thread implementation will try to
119     // go calculate it again.  For now, just set it to a Unix Signal with an invalid signal number.
120     SetStopInfo (StopInfo::CreateStopReasonWithSignal (*this,  LLDB_INVALID_SIGNAL_NUMBER));
121 }
122 
123 bool
124 Thread::ThreadStoppedForAReason (void)
125 {
126     return GetPrivateStopReason () != NULL;
127 }
128 
129 bool
130 Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
131 {
132     if (!SaveFrameZeroState(saved_state.register_backup))
133         return false;
134 
135     saved_state.stop_info_sp = GetStopInfo();
136     saved_state.orig_stop_id = GetProcess().GetStopID();
137 
138     return true;
139 }
140 
141 bool
142 Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
143 {
144     RestoreSaveFrameZero(saved_state.register_backup);
145     if (saved_state.stop_info_sp)
146         saved_state.stop_info_sp->MakeStopInfoValid();
147     SetStopInfo(saved_state.stop_info_sp);
148     return true;
149 }
150 
151 StateType
152 Thread::GetState() const
153 {
154     // If any other threads access this we will need a mutex for it
155     Mutex::Locker locker(m_state_mutex);
156     return m_state;
157 }
158 
159 void
160 Thread::SetState(StateType state)
161 {
162     Mutex::Locker locker(m_state_mutex);
163     m_state = state;
164 }
165 
166 void
167 Thread::WillStop()
168 {
169     ThreadPlan *current_plan = GetCurrentPlan();
170 
171     // FIXME: I may decide to disallow threads with no plans.  In which
172     // case this should go to an assert.
173 
174     if (!current_plan)
175         return;
176 
177     current_plan->WillStop();
178 }
179 
180 void
181 Thread::SetupForResume ()
182 {
183     if (GetResumeState() != eStateSuspended)
184     {
185 
186         // If we're at a breakpoint push the step-over breakpoint plan.  Do this before
187         // telling the current plan it will resume, since we might change what the current
188         // plan is.
189 
190         lldb::addr_t pc = GetRegisterContext()->GetPC();
191         BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
192         if (bp_site_sp && bp_site_sp->IsEnabled())
193         {
194             // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
195             // special to step over a breakpoint.
196 
197             ThreadPlan *cur_plan = GetCurrentPlan();
198 
199             if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
200             {
201                 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
202                 if (step_bp_plan)
203                 {
204                     ThreadPlanSP step_bp_plan_sp;
205                     step_bp_plan->SetPrivate (true);
206 
207                     if (GetCurrentPlan()->RunState() != eStateStepping)
208                     {
209                         step_bp_plan->SetAutoContinue(true);
210                     }
211                     step_bp_plan_sp.reset (step_bp_plan);
212                     QueueThreadPlan (step_bp_plan_sp, false);
213                 }
214             }
215         }
216     }
217 }
218 
219 bool
220 Thread::WillResume (StateType resume_state)
221 {
222     // At this point clear the completed plan stack.
223     m_completed_plan_stack.clear();
224     m_discarded_plan_stack.clear();
225 
226     StopInfo *stop_info = GetPrivateStopReason().get();
227     if (stop_info)
228         stop_info->WillResume (resume_state);
229 
230     // Tell all the plans that we are about to resume in case they need to clear any state.
231     // We distinguish between the plan on the top of the stack and the lower
232     // plans in case a plan needs to do any special business before it runs.
233 
234     ThreadPlan *plan_ptr = GetCurrentPlan();
235     plan_ptr->WillResume(resume_state, true);
236 
237     while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
238     {
239         plan_ptr->WillResume (resume_state, false);
240     }
241 
242     m_actual_stop_info_sp.reset();
243     return true;
244 }
245 
246 void
247 Thread::DidResume ()
248 {
249     SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
250 }
251 
252 bool
253 Thread::ShouldStop (Event* event_ptr)
254 {
255     ThreadPlan *current_plan = GetCurrentPlan();
256     bool should_stop = true;
257 
258     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
259     if (log)
260     {
261         StreamString s;
262         DumpThreadPlans(&s);
263         log->PutCString (s.GetData());
264     }
265 
266     // The top most plan always gets to do the trace log...
267     current_plan->DoTraceLog ();
268 
269     if (current_plan->PlanExplainsStop())
270     {
271         bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
272 
273         // We're starting from the base plan, so just let it decide;
274         if (PlanIsBasePlan(current_plan))
275         {
276             should_stop = current_plan->ShouldStop (event_ptr);
277             if (log)
278                 log->Printf("Base plan says should stop: %i.", should_stop);
279         }
280         else
281         {
282             // Otherwise, don't let the base plan override what the other plans say to do, since
283             // presumably if there were other plans they would know what to do...
284             while (1)
285             {
286                 if (PlanIsBasePlan(current_plan))
287                     break;
288 
289                 should_stop = current_plan->ShouldStop(event_ptr);
290                 if (log)
291                     log->Printf("Plan %s should stop: %d.", current_plan->GetName(), should_stop);
292                 if (current_plan->MischiefManaged())
293                 {
294                     if (should_stop)
295                         current_plan->WillStop();
296 
297                     // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
298                     // Otherwise, see if the plan's parent wants to stop.
299 
300                     if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
301                     {
302                         PopPlan();
303                         break;
304                     }
305                     else
306                     {
307 
308                         PopPlan();
309 
310                         current_plan = GetCurrentPlan();
311                         if (current_plan == NULL)
312                         {
313                             break;
314                         }
315                     }
316 
317                 }
318                 else
319                 {
320                     break;
321                 }
322             }
323         }
324         if (over_ride_stop)
325             should_stop = false;
326     }
327     else if (current_plan->TracerExplainsStop())
328     {
329         return false;
330     }
331     else
332     {
333         // If the current plan doesn't explain the stop, then, find one that
334         // does and let it handle the situation.
335         ThreadPlan *plan_ptr = current_plan;
336         while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
337         {
338             if (plan_ptr->PlanExplainsStop())
339             {
340                 should_stop = plan_ptr->ShouldStop (event_ptr);
341                 break;
342             }
343 
344         }
345     }
346 
347     return should_stop;
348 }
349 
350 Vote
351 Thread::ShouldReportStop (Event* event_ptr)
352 {
353     StateType thread_state = GetResumeState ();
354     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
355 
356     if (thread_state == eStateSuspended || thread_state == eStateInvalid)
357     {
358         if (log)
359             log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
360         return eVoteNoOpinion;
361     }
362 
363     if (m_completed_plan_stack.size() > 0)
364     {
365         // Don't use GetCompletedPlan here, since that suppresses private plans.
366         if (log)
367             log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote  for complete stack's back plan\n", GetID());
368         return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
369     }
370     else
371     {
372         if (log)
373             log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4x: returning vote  for current plan\n", GetID());
374         return GetCurrentPlan()->ShouldReportStop (event_ptr);
375     }
376 }
377 
378 Vote
379 Thread::ShouldReportRun (Event* event_ptr)
380 {
381     StateType thread_state = GetResumeState ();
382 
383     if (thread_state == eStateSuspended
384             || thread_state == eStateInvalid)
385     {
386         return eVoteNoOpinion;
387     }
388 
389     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
390     if (m_completed_plan_stack.size() > 0)
391     {
392         // Don't use GetCompletedPlan here, since that suppresses private plans.
393         if (log)
394             log->Printf ("Current Plan for thread %d (0x%4.4x): %s being asked whether we should report run.",
395                          GetIndexID(),
396                          GetID(),
397                          m_completed_plan_stack.back()->GetName());
398 
399         return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
400     }
401     else
402     {
403         if (log)
404             log->Printf ("Current Plan for thread %d (0x%4.4x): %s being asked whether we should report run.",
405                          GetIndexID(),
406                          GetID(),
407                          GetCurrentPlan()->GetName());
408 
409         return GetCurrentPlan()->ShouldReportRun (event_ptr);
410      }
411 }
412 
413 bool
414 Thread::MatchesSpec (const ThreadSpec *spec)
415 {
416     if (spec == NULL)
417         return true;
418 
419     return spec->ThreadPassesBasicTests(this);
420 }
421 
422 void
423 Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
424 {
425     if (thread_plan_sp)
426     {
427         // If the thread plan doesn't already have a tracer, give it its parent's tracer:
428         if (!thread_plan_sp->GetThreadPlanTracer())
429             thread_plan_sp->SetThreadPlanTracer(m_plan_stack.back()->GetThreadPlanTracer());
430         m_plan_stack.push_back (thread_plan_sp);
431 
432         thread_plan_sp->DidPush();
433 
434         LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
435         if (log)
436         {
437             StreamString s;
438             thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
439             log->Printf("Pushing plan: \"%s\", tid = 0x%4.4x.",
440                         s.GetData(),
441                         thread_plan_sp->GetThread().GetID());
442         }
443     }
444 }
445 
446 void
447 Thread::PopPlan ()
448 {
449     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
450 
451     if (m_plan_stack.empty())
452         return;
453     else
454     {
455         ThreadPlanSP &plan = m_plan_stack.back();
456         if (log)
457         {
458             log->Printf("Popping plan: \"%s\", tid = 0x%4.4x.", plan->GetName(), plan->GetThread().GetID());
459         }
460         m_completed_plan_stack.push_back (plan);
461         plan->WillPop();
462         m_plan_stack.pop_back();
463     }
464 }
465 
466 void
467 Thread::DiscardPlan ()
468 {
469     if (m_plan_stack.size() > 1)
470     {
471         ThreadPlanSP &plan = m_plan_stack.back();
472         m_discarded_plan_stack.push_back (plan);
473         plan->WillPop();
474         m_plan_stack.pop_back();
475     }
476 }
477 
478 ThreadPlan *
479 Thread::GetCurrentPlan ()
480 {
481     if (m_plan_stack.empty())
482         return NULL;
483     else
484         return m_plan_stack.back().get();
485 }
486 
487 ThreadPlanSP
488 Thread::GetCompletedPlan ()
489 {
490     ThreadPlanSP empty_plan_sp;
491     if (!m_completed_plan_stack.empty())
492     {
493         for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
494         {
495             ThreadPlanSP completed_plan_sp;
496             completed_plan_sp = m_completed_plan_stack[i];
497             if (!completed_plan_sp->GetPrivate ())
498             return completed_plan_sp;
499         }
500     }
501     return empty_plan_sp;
502 }
503 
504 bool
505 Thread::IsThreadPlanDone (ThreadPlan *plan)
506 {
507     if (!m_completed_plan_stack.empty())
508     {
509         for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
510         {
511             if (m_completed_plan_stack[i].get() == plan)
512                 return true;
513         }
514     }
515     return false;
516 }
517 
518 bool
519 Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
520 {
521     if (!m_discarded_plan_stack.empty())
522     {
523         for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
524         {
525             if (m_discarded_plan_stack[i].get() == plan)
526                 return true;
527         }
528     }
529     return false;
530 }
531 
532 ThreadPlan *
533 Thread::GetPreviousPlan (ThreadPlan *current_plan)
534 {
535     if (current_plan == NULL)
536         return NULL;
537 
538     int stack_size = m_completed_plan_stack.size();
539     for (int i = stack_size - 1; i > 0; i--)
540     {
541         if (current_plan == m_completed_plan_stack[i].get())
542             return m_completed_plan_stack[i-1].get();
543     }
544 
545     if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
546     {
547         if (m_plan_stack.size() > 0)
548             return m_plan_stack.back().get();
549         else
550             return NULL;
551     }
552 
553     stack_size = m_plan_stack.size();
554     for (int i = stack_size - 1; i > 0; i--)
555     {
556         if (current_plan == m_plan_stack[i].get())
557             return m_plan_stack[i-1].get();
558     }
559     return NULL;
560 }
561 
562 void
563 Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
564 {
565     if (abort_other_plans)
566        DiscardThreadPlans(true);
567 
568     PushPlan (thread_plan_sp);
569 }
570 
571 
572 void
573 Thread::EnableTracer (bool value, bool single_stepping)
574 {
575     int stack_size = m_plan_stack.size();
576     for (int i = 0; i < stack_size; i++)
577     {
578         if (m_plan_stack[i]->GetThreadPlanTracer())
579         {
580             m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value);
581             m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping);
582         }
583     }
584 }
585 
586 void
587 Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp)
588 {
589     int stack_size = m_plan_stack.size();
590     for (int i = 0; i < stack_size; i++)
591         m_plan_stack[i]->SetThreadPlanTracer(tracer_sp);
592 }
593 
594 void
595 Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp)
596 {
597     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
598     if (log)
599     {
600         log->Printf("Discarding thread plans for thread tid = 0x%4.4x, up to %p", GetID(), up_to_plan_sp.get());
601     }
602 
603     int stack_size = m_plan_stack.size();
604 
605     // If the input plan is NULL, discard all plans.  Otherwise make sure this plan is in the
606     // stack, and if so discard up to and including it.
607 
608     if (up_to_plan_sp.get() == NULL)
609     {
610         for (int i = stack_size - 1; i > 0; i--)
611             DiscardPlan();
612     }
613     else
614     {
615         bool found_it = false;
616         for (int i = stack_size - 1; i > 0; i--)
617         {
618             if (m_plan_stack[i] == up_to_plan_sp)
619                 found_it = true;
620         }
621         if (found_it)
622         {
623             bool last_one = false;
624             for (int i = stack_size - 1; i > 0 && !last_one ; i--)
625             {
626                 if (GetCurrentPlan() == up_to_plan_sp.get())
627                     last_one = true;
628                 DiscardPlan();
629             }
630         }
631     }
632     return;
633 }
634 
635 void
636 Thread::DiscardThreadPlans(bool force)
637 {
638     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
639     if (log)
640     {
641         log->Printf("Discarding thread plans for thread (tid = 0x%4.4x, force %d)", GetID(), force);
642     }
643 
644     if (force)
645     {
646         int stack_size = m_plan_stack.size();
647         for (int i = stack_size - 1; i > 0; i--)
648         {
649             DiscardPlan();
650         }
651         return;
652     }
653 
654     while (1)
655     {
656 
657         int master_plan_idx;
658         bool discard;
659 
660         // Find the first master plan, see if it wants discarding, and if yes discard up to it.
661         for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
662         {
663             if (m_plan_stack[master_plan_idx]->IsMasterPlan())
664             {
665                 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
666                 break;
667             }
668         }
669 
670         if (discard)
671         {
672             // First pop all the dependent plans:
673             for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
674             {
675 
676                 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
677                 // for the plan leaves it in a state that it is safe to pop the plan
678                 // with no more notice?
679                 DiscardPlan();
680             }
681 
682             // Now discard the master plan itself.
683             // The bottom-most plan never gets discarded.  "OkayToDiscard" for it means
684             // discard it's dependent plans, but not it...
685             if (master_plan_idx > 0)
686             {
687                 DiscardPlan();
688             }
689         }
690         else
691         {
692             // If the master plan doesn't want to get discarded, then we're done.
693             break;
694         }
695 
696     }
697 }
698 
699 ThreadPlan *
700 Thread::QueueFundamentalPlan (bool abort_other_plans)
701 {
702     ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
703     QueueThreadPlan (thread_plan_sp, abort_other_plans);
704     return thread_plan_sp.get();
705 }
706 
707 ThreadPlan *
708 Thread::QueueThreadPlanForStepSingleInstruction
709 (
710     bool step_over,
711     bool abort_other_plans,
712     bool stop_other_threads
713 )
714 {
715     ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
716     QueueThreadPlan (thread_plan_sp, abort_other_plans);
717     return thread_plan_sp.get();
718 }
719 
720 ThreadPlan *
721 Thread::QueueThreadPlanForStepRange
722 (
723     bool abort_other_plans,
724     StepType type,
725     const AddressRange &range,
726     const SymbolContext &addr_context,
727     lldb::RunMode stop_other_threads,
728     bool avoid_code_without_debug_info
729 )
730 {
731     ThreadPlanSP thread_plan_sp;
732     if (type == eStepTypeInto)
733     {
734         ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
735         if (avoid_code_without_debug_info)
736             plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
737         else
738             plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
739         thread_plan_sp.reset (plan);
740     }
741     else
742         thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
743 
744     QueueThreadPlan (thread_plan_sp, abort_other_plans);
745     return thread_plan_sp.get();
746 }
747 
748 
749 ThreadPlan *
750 Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
751 {
752     ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
753     QueueThreadPlan (thread_plan_sp, abort_other_plans);
754     return thread_plan_sp.get();
755 }
756 
757 ThreadPlan *
758 Thread::QueueThreadPlanForStepOut
759 (
760     bool abort_other_plans,
761     SymbolContext *addr_context,
762     bool first_insn,
763     bool stop_other_threads,
764     Vote stop_vote,
765     Vote run_vote,
766     uint32_t frame_idx
767 )
768 {
769     ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this,
770                                                         addr_context,
771                                                         first_insn,
772                                                         stop_other_threads,
773                                                         stop_vote,
774                                                         run_vote,
775                                                         frame_idx));
776     QueueThreadPlan (thread_plan_sp, abort_other_plans);
777     return thread_plan_sp.get();
778 }
779 
780 ThreadPlan *
781 Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
782 {
783     // Try the dynamic loader first:
784     ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
785     // If that didn't come up with anything, try the ObjC runtime plugin:
786     if (thread_plan_sp.get() == NULL)
787     {
788         ObjCLanguageRuntime *objc_runtime = GetProcess().GetObjCLanguageRuntime();
789         if (objc_runtime)
790             thread_plan_sp = objc_runtime->GetStepThroughTrampolinePlan (*this, stop_other_threads);
791     }
792 
793     if (thread_plan_sp.get() == NULL)
794     {
795         thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
796         if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
797             return NULL;
798     }
799     QueueThreadPlan (thread_plan_sp, abort_other_plans);
800     return thread_plan_sp.get();
801 }
802 
803 ThreadPlan *
804 Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
805                                         Address& function,
806                                         lldb::addr_t arg,
807                                         bool stop_other_threads,
808                                         bool discard_on_error)
809 {
810     ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
811     QueueThreadPlan (thread_plan_sp, abort_other_plans);
812     return thread_plan_sp.get();
813 }
814 
815 ThreadPlan *
816 Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
817                                         Address &target_addr,
818                                         bool stop_other_threads)
819 {
820     ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
821     QueueThreadPlan (thread_plan_sp, abort_other_plans);
822     return thread_plan_sp.get();
823 }
824 
825 ThreadPlan *
826 Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
827                                      lldb::addr_t *address_list,
828                                      size_t num_addresses,
829                                      bool stop_other_threads,
830                                      uint32_t frame_idx)
831 {
832     ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx));
833     QueueThreadPlan (thread_plan_sp, abort_other_plans);
834     return thread_plan_sp.get();
835 
836 }
837 
838 uint32_t
839 Thread::GetIndexID () const
840 {
841     return m_index_id;
842 }
843 
844 void
845 Thread::DumpThreadPlans (lldb_private::Stream *s) const
846 {
847     uint32_t stack_size = m_plan_stack.size();
848     int i;
849     s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x, stack_size = %d\n", GetIndexID(), GetID(), stack_size);
850     for (i = stack_size - 1; i >= 0; i--)
851     {
852         s->Printf ("Element %d: ", i);
853         s->IndentMore();
854         m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
855         s->IndentLess();
856         s->EOL();
857     }
858 
859     stack_size = m_completed_plan_stack.size();
860     s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
861     for (i = stack_size - 1; i >= 0; i--)
862     {
863         s->Printf ("Element %d: ", i);
864         s->IndentMore();
865         m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
866         s->IndentLess();
867         s->EOL();
868     }
869 
870     stack_size = m_discarded_plan_stack.size();
871     s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
872     for (i = stack_size - 1; i >= 0; i--)
873     {
874         s->Printf ("Element %d: ", i);
875         s->IndentMore();
876         m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
877         s->IndentLess();
878         s->EOL();
879     }
880 
881 }
882 
883 Target *
884 Thread::CalculateTarget ()
885 {
886     return m_process.CalculateTarget();
887 }
888 
889 Process *
890 Thread::CalculateProcess ()
891 {
892     return &m_process;
893 }
894 
895 Thread *
896 Thread::CalculateThread ()
897 {
898     return this;
899 }
900 
901 StackFrame *
902 Thread::CalculateStackFrame ()
903 {
904     return NULL;
905 }
906 
907 void
908 Thread::CalculateExecutionContext (ExecutionContext &exe_ctx)
909 {
910     m_process.CalculateExecutionContext (exe_ctx);
911     exe_ctx.thread = this;
912     exe_ctx.frame = NULL;
913 }
914 
915 
916 StackFrameList &
917 Thread::GetStackFrameList ()
918 {
919     if (m_curr_frames_ap.get() == NULL)
920         m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_sp, true));
921     return *m_curr_frames_ap;
922 }
923 
924 
925 
926 uint32_t
927 Thread::GetStackFrameCount()
928 {
929     return GetStackFrameList().GetNumFrames();
930 }
931 
932 
933 void
934 Thread::ClearStackFrames ()
935 {
936     if (m_curr_frames_ap.get() && m_curr_frames_ap->GetNumFrames (false) > 1)
937         m_prev_frames_sp.reset (m_curr_frames_ap.release());
938     else
939         m_curr_frames_ap.release();
940 
941 //    StackFrameList::Merge (m_curr_frames_ap, m_prev_frames_sp);
942 //    assert (m_curr_frames_ap.get() == NULL);
943 }
944 
945 lldb::StackFrameSP
946 Thread::GetStackFrameAtIndex (uint32_t idx)
947 {
948     return GetStackFrameList().GetFrameAtIndex(idx);
949 }
950 
951 uint32_t
952 Thread::GetSelectedFrameIndex ()
953 {
954     return GetStackFrameList().GetSelectedFrameIndex();
955 }
956 
957 lldb::StackFrameSP
958 Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
959 {
960     return GetStackFrameList().GetFrameWithConcreteFrameIndex (unwind_idx);
961 }
962 
963 lldb::StackFrameSP
964 Thread::GetFrameWithStackID(StackID &stack_id)
965 {
966     return GetStackFrameList().GetFrameWithStackID (stack_id);
967 }
968 
969 
970 lldb::StackFrameSP
971 Thread::GetSelectedFrame ()
972 {
973     return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex());
974 }
975 
976 uint32_t
977 Thread::SetSelectedFrame (lldb_private::StackFrame *frame)
978 {
979     return GetStackFrameList().SetSelectedFrame(frame);
980 }
981 
982 void
983 Thread::SetSelectedFrameByIndex (uint32_t idx)
984 {
985     GetStackFrameList().SetSelectedFrameByIndex(idx);
986 }
987 
988 void
989 Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
990 {
991     ExecutionContext exe_ctx;
992     SymbolContext frame_sc;
993     CalculateExecutionContext (exe_ctx);
994 
995     if (frame_idx != LLDB_INVALID_INDEX32)
996     {
997         StackFrameSP frame_sp(GetStackFrameAtIndex (frame_idx));
998         if (frame_sp)
999         {
1000             exe_ctx.frame = frame_sp.get();
1001             frame_sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything);
1002         }
1003     }
1004 
1005     const char *thread_format = GetProcess().GetTarget().GetDebugger().GetThreadFormat();
1006     assert (thread_format);
1007     const char *end = NULL;
1008     Debugger::FormatPrompt (thread_format,
1009                             exe_ctx.frame ? &frame_sc : NULL,
1010                             &exe_ctx,
1011                             NULL,
1012                             strm,
1013                             &end);
1014 }
1015 
1016 lldb::ThreadSP
1017 Thread::GetSP ()
1018 {
1019     return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
1020 }
1021 
1022 
1023 void
1024 Thread::SettingsInitialize ()
1025 {
1026     UserSettingsControllerSP &usc = GetSettingsController();
1027     usc.reset (new SettingsController);
1028     UserSettingsController::InitializeSettingsController (usc,
1029                                                           SettingsController::global_settings_table,
1030                                                           SettingsController::instance_settings_table);
1031 
1032     // Now call SettingsInitialize() on each 'child' setting of Thread.
1033     // Currently there are none.
1034 }
1035 
1036 void
1037 Thread::SettingsTerminate ()
1038 {
1039     // Must call SettingsTerminate() on each 'child' setting of Thread before terminating Thread settings.
1040     // Currently there are none.
1041 
1042     // Now terminate Thread Settings.
1043 
1044     UserSettingsControllerSP &usc = GetSettingsController();
1045     UserSettingsController::FinalizeSettingsController (usc);
1046     usc.reset();
1047 }
1048 
1049 UserSettingsControllerSP &
1050 Thread::GetSettingsController ()
1051 {
1052     static UserSettingsControllerSP g_settings_controller;
1053     return g_settings_controller;
1054 }
1055 
1056 void
1057 Thread::UpdateInstanceName ()
1058 {
1059     StreamString sstr;
1060     const char *name = GetName();
1061 
1062     if (name && name[0] != '\0')
1063         sstr.Printf ("%s", name);
1064     else if ((GetIndexID() != 0) || (GetID() != 0))
1065         sstr.Printf ("0x%4.4x", GetIndexID(), GetID());
1066 
1067     if (sstr.GetSize() > 0)
1068 	Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData());
1069 }
1070 
1071 lldb::StackFrameSP
1072 Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
1073 {
1074     return GetStackFrameList().GetStackFrameSPForStackFramePtr (stack_frame_ptr);
1075 }
1076 
1077 const char *
1078 Thread::StopReasonAsCString (lldb::StopReason reason)
1079 {
1080     switch (reason)
1081     {
1082     case eStopReasonInvalid:      return "invalid";
1083     case eStopReasonNone:         return "none";
1084     case eStopReasonTrace:        return "trace";
1085     case eStopReasonBreakpoint:   return "breakpoint";
1086     case eStopReasonWatchpoint:   return "watchpoint";
1087     case eStopReasonSignal:       return "signal";
1088     case eStopReasonException:    return "exception";
1089     case eStopReasonPlanComplete: return "plan complete";
1090     }
1091 
1092 
1093     static char unknown_state_string[64];
1094     snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason);
1095     return unknown_state_string;
1096 }
1097 
1098 const char *
1099 Thread::RunModeAsCString (lldb::RunMode mode)
1100 {
1101     switch (mode)
1102     {
1103     case eOnlyThisThread:     return "only this thread";
1104     case eAllThreads:         return "all threads";
1105     case eOnlyDuringStepping: return "only during stepping";
1106     }
1107 
1108     static char unknown_state_string[64];
1109     snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode);
1110     return unknown_state_string;
1111 }
1112 
1113 size_t
1114 Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source)
1115 {
1116     size_t num_frames_shown = 0;
1117     strm.Indent();
1118     strm.Printf("%c ", GetProcess().GetThreadList().GetSelectedThread().get() == this ? '*' : ' ');
1119 
1120     StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame);
1121     SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry));
1122     if (frame_sc.line_entry.line != 0 &&
1123         frame_sc.line_entry.file &&
1124         GetProcess().GetTarget().GetDebugger().GetUseExternalEditor())
1125     {
1126         Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
1127     }
1128 
1129     DumpUsingSettingsFormat (strm, start_frame);
1130 
1131     if (num_frames > 0)
1132     {
1133         strm.IndentMore();
1134 
1135         const bool show_frame_info = true;
1136         const uint32_t source_lines_before = 3;
1137         const uint32_t source_lines_after = 3;
1138         strm.IndentMore ();
1139         num_frames_shown = GetStackFrameList ().GetStatus (strm,
1140                                                            start_frame,
1141                                                            num_frames,
1142                                                            show_frame_info,
1143                                                            num_frames_with_source,
1144                                                            source_lines_before,
1145                                                            source_lines_after);
1146         strm.IndentLess();
1147         strm.IndentLess();
1148     }
1149     return num_frames_shown;
1150 }
1151 
1152 size_t
1153 Thread::GetStackFrameStatus (Stream& strm,
1154                              uint32_t first_frame,
1155                              uint32_t num_frames,
1156                              bool show_frame_info,
1157                              uint32_t num_frames_with_source,
1158                              uint32_t source_lines_before,
1159                              uint32_t source_lines_after)
1160 {
1161     return GetStackFrameList().GetStatus (strm,
1162                                           first_frame,
1163                                           num_frames,
1164                                           show_frame_info,
1165                                           num_frames_with_source,
1166                                           source_lines_before,
1167                                           source_lines_after);
1168 }
1169 
1170 bool
1171 Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
1172 {
1173     lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
1174     if (frame_sp)
1175     {
1176         checkpoint.SetStackID(frame_sp->GetStackID());
1177         return frame_sp->GetRegisterContext()->ReadAllRegisterValues (checkpoint.GetData());
1178     }
1179     return false;
1180 }
1181 
1182 bool
1183 Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
1184 {
1185     lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
1186     if (frame_sp)
1187     {
1188         bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
1189 
1190         // Clear out all stack frames as our world just changed.
1191         ClearStackFrames();
1192         frame_sp->GetRegisterContext()->InvalidateIfNeeded(true);
1193 
1194         return ret;
1195     }
1196     return false;
1197 }
1198 
1199 #pragma mark "Thread::SettingsController"
1200 //--------------------------------------------------------------
1201 // class Thread::SettingsController
1202 //--------------------------------------------------------------
1203 
1204 Thread::SettingsController::SettingsController () :
1205     UserSettingsController ("thread", Process::GetSettingsController())
1206 {
1207     m_default_settings.reset (new ThreadInstanceSettings (*this, false,
1208                                                           InstanceSettings::GetDefaultName().AsCString()));
1209 }
1210 
1211 Thread::SettingsController::~SettingsController ()
1212 {
1213 }
1214 
1215 lldb::InstanceSettingsSP
1216 Thread::SettingsController::CreateInstanceSettings (const char *instance_name)
1217 {
1218     ThreadInstanceSettings *new_settings = new ThreadInstanceSettings (*GetSettingsController(),
1219                                                                        false,
1220                                                                        instance_name);
1221     lldb::InstanceSettingsSP new_settings_sp (new_settings);
1222     return new_settings_sp;
1223 }
1224 
1225 #pragma mark "ThreadInstanceSettings"
1226 //--------------------------------------------------------------
1227 // class ThreadInstanceSettings
1228 //--------------------------------------------------------------
1229 
1230 ThreadInstanceSettings::ThreadInstanceSettings (UserSettingsController &owner, bool live_instance, const char *name) :
1231     InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
1232     m_avoid_regexp_ap (),
1233     m_trace_enabled (false)
1234 {
1235     // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1236     // until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers.
1237     // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
1238     // This is true for CreateInstanceName() too.
1239 
1240     if (GetInstanceName() == InstanceSettings::InvalidName())
1241     {
1242         ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
1243         m_owner.RegisterInstanceSettings (this);
1244     }
1245 
1246     if (live_instance)
1247     {
1248         const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1249         CopyInstanceSettings (pending_settings,false);
1250         //m_owner.RemovePendingSettings (m_instance_name);
1251     }
1252 }
1253 
1254 ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) :
1255     InstanceSettings (*Thread::GetSettingsController(), CreateInstanceName().AsCString()),
1256     m_avoid_regexp_ap (),
1257     m_trace_enabled (rhs.m_trace_enabled)
1258 {
1259     if (m_instance_name != InstanceSettings::GetDefaultName())
1260     {
1261         const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1262         CopyInstanceSettings (pending_settings,false);
1263         m_owner.RemovePendingSettings (m_instance_name);
1264     }
1265     if (rhs.m_avoid_regexp_ap.get() != NULL)
1266         m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
1267 }
1268 
1269 ThreadInstanceSettings::~ThreadInstanceSettings ()
1270 {
1271 }
1272 
1273 ThreadInstanceSettings&
1274 ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs)
1275 {
1276     if (this != &rhs)
1277     {
1278         if (rhs.m_avoid_regexp_ap.get() != NULL)
1279             m_avoid_regexp_ap.reset(new RegularExpression(rhs.m_avoid_regexp_ap->GetText()));
1280         else
1281             m_avoid_regexp_ap.reset(NULL);
1282     }
1283     m_trace_enabled = rhs.m_trace_enabled;
1284     return *this;
1285 }
1286 
1287 
1288 void
1289 ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1290                                                          const char *index_value,
1291                                                          const char *value,
1292                                                          const ConstString &instance_name,
1293                                                          const SettingEntry &entry,
1294                                                          VarSetOperationType op,
1295                                                          Error &err,
1296                                                          bool pending)
1297 {
1298     if (var_name == StepAvoidRegexpVarName())
1299     {
1300         std::string regexp_text;
1301         if (m_avoid_regexp_ap.get() != NULL)
1302             regexp_text.append (m_avoid_regexp_ap->GetText());
1303         UserSettingsController::UpdateStringVariable (op, regexp_text, value, err);
1304         if (regexp_text.empty())
1305             m_avoid_regexp_ap.reset();
1306         else
1307         {
1308             m_avoid_regexp_ap.reset(new RegularExpression(regexp_text.c_str()));
1309 
1310         }
1311     }
1312     else if (var_name == GetTraceThreadVarName())
1313     {
1314         bool success;
1315         bool result = Args::StringToBoolean(value, false, &success);
1316 
1317         if (success)
1318         {
1319             m_trace_enabled = result;
1320             if (!pending)
1321             {
1322                 Thread *myself = static_cast<Thread *> (this);
1323                 myself->EnableTracer(m_trace_enabled, true);
1324             }
1325         }
1326         else
1327         {
1328             err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value);
1329         }
1330 
1331     }
1332 }
1333 
1334 void
1335 ThreadInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1336                                                bool pending)
1337 {
1338     if (new_settings.get() == NULL)
1339         return;
1340 
1341     ThreadInstanceSettings *new_process_settings = (ThreadInstanceSettings *) new_settings.get();
1342     if (new_process_settings->GetSymbolsToAvoidRegexp() != NULL)
1343         m_avoid_regexp_ap.reset (new RegularExpression (new_process_settings->GetSymbolsToAvoidRegexp()->GetText()));
1344     else
1345         m_avoid_regexp_ap.reset ();
1346 }
1347 
1348 bool
1349 ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
1350                                                   const ConstString &var_name,
1351                                                   StringList &value,
1352                                                   Error *err)
1353 {
1354     if (var_name == StepAvoidRegexpVarName())
1355     {
1356         if (m_avoid_regexp_ap.get() != NULL)
1357         {
1358             std::string regexp_text("\"");
1359             regexp_text.append(m_avoid_regexp_ap->GetText());
1360             regexp_text.append ("\"");
1361             value.AppendString (regexp_text.c_str());
1362         }
1363 
1364     }
1365     else if (var_name == GetTraceThreadVarName())
1366     {
1367         value.AppendString(m_trace_enabled ? "true" : "false");
1368     }
1369     else
1370     {
1371         if (err)
1372             err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1373         return false;
1374     }
1375     return true;
1376 }
1377 
1378 const ConstString
1379 ThreadInstanceSettings::CreateInstanceName ()
1380 {
1381     static int instance_count = 1;
1382     StreamString sstr;
1383 
1384     sstr.Printf ("thread_%d", instance_count);
1385     ++instance_count;
1386 
1387     const ConstString ret_val (sstr.GetData());
1388     return ret_val;
1389 }
1390 
1391 const ConstString &
1392 ThreadInstanceSettings::StepAvoidRegexpVarName ()
1393 {
1394     static ConstString step_avoid_var_name ("step-avoid-regexp");
1395 
1396     return step_avoid_var_name;
1397 }
1398 
1399 const ConstString &
1400 ThreadInstanceSettings::GetTraceThreadVarName ()
1401 {
1402     static ConstString trace_thread_var_name ("trace-thread");
1403 
1404     return trace_thread_var_name;
1405 }
1406 
1407 //--------------------------------------------------
1408 // SettingsController Variable Tables
1409 //--------------------------------------------------
1410 
1411 SettingEntry
1412 Thread::SettingsController::global_settings_table[] =
1413 {
1414   //{ "var-name",    var-type  ,        "default", enum-table, init'd, hidden, "help-text"},
1415     {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1416 };
1417 
1418 
1419 SettingEntry
1420 Thread::SettingsController::instance_settings_table[] =
1421 {
1422   //{ "var-name",    var-type,              "default",      enum-table, init'd, hidden, "help-text"},
1423     { "step-avoid-regexp",  eSetVarTypeString,      "",  NULL,       false,  false,  "A regular expression defining functions step-in won't stop in." },
1424     { "trace-thread",  eSetVarTypeBoolean,      "false",  NULL,       false,  false,  "If true, this thread will single-step and log execution." },
1425     {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1426 };
1427