xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision fd54b368ea4d1bd481ac4d203362c2a5556418d0)
1 //===-- CommandObjectThread.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 "CommandObjectThread.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/Options.h"
17 #include "lldb/Core/State.h"
18 #include "lldb/Core/SourceManager.h"
19 
20 #include "lldb/Host/Host.h"
21 
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandReturnObject.h"
24 
25 #include "lldb/Target/Process.h"
26 #include "lldb/Target/RegisterContext.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadPlan.h"
30 #include "lldb/Target/ThreadPlanStepInstruction.h"
31 #include "lldb/Target/ThreadPlanStepOut.h"
32 #include "lldb/Target/ThreadPlanStepRange.h"
33 #include "lldb/Target/ThreadPlanStepInRange.h"
34 #include "lldb/Symbol/LineTable.h"
35 #include "lldb/Symbol/LineEntry.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 
41 //-------------------------------------------------------------------------
42 // CommandObjectThreadBacktrace
43 //-------------------------------------------------------------------------
44 
45 class CommandObjectThreadBacktrace : public CommandObject
46 {
47 public:
48 
49     class CommandOptions : public Options
50     {
51     public:
52 
53         CommandOptions (CommandInterpreter &interpreter) :
54             Options(interpreter)
55         {
56             // Keep default values of all options in one place: OptionParsingStarting ()
57             OptionParsingStarting ();
58         }
59 
60         virtual
61         ~CommandOptions ()
62         {
63         }
64 
65         virtual Error
66         SetOptionValue (uint32_t option_idx, const char *option_arg)
67         {
68             Error error;
69             char short_option = (char) m_getopt_table[option_idx].val;
70 
71             switch (short_option)
72             {
73                 case 'c':
74                 {
75                     bool success;
76                     int32_t input_count =  Args::StringToSInt32 (option_arg, -1, 0, &success);
77                     if (!success)
78                         error.SetErrorStringWithFormat("Invalid integer value for option '%c'.\n", short_option);
79                     if (input_count < -1)
80                         m_count = UINT32_MAX;
81                     else
82                         m_count = input_count;
83                 }
84                 break;
85                 case 's':
86                 {
87                     bool success;
88                     m_start =  Args::StringToUInt32 (option_arg, 0, 0, &success);
89                     if (!success)
90                         error.SetErrorStringWithFormat("Invalid integer value for option '%c'.\n", short_option);
91                 }
92                 break;
93                 default:
94                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
95                     break;
96 
97             }
98             return error;
99         }
100 
101         void
102         OptionParsingStarting ()
103         {
104             m_count = UINT32_MAX;
105             m_start = 0;
106         }
107 
108         const OptionDefinition*
109         GetDefinitions ()
110         {
111             return g_option_table;
112         }
113 
114         // Options table: Required for subclasses of Options.
115 
116         static OptionDefinition g_option_table[];
117 
118         // Instance variables to hold the values for command options.
119         uint32_t m_count;
120         uint32_t m_start;
121     };
122 
123     CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
124         CommandObject (interpreter,
125                        "thread backtrace",
126                        "Show the stack for one or more threads.  If no threads are specified, show the currently selected thread.  Use the thread-index \"all\" to see all threads.",
127                        NULL,
128                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
129         m_options(interpreter)
130     {
131         CommandArgumentEntry arg;
132         CommandArgumentData thread_idx_arg;
133 
134         // Define the first (and only) variant of this arg.
135         thread_idx_arg.arg_type = eArgTypeThreadIndex;
136         thread_idx_arg.arg_repetition = eArgRepeatStar;
137 
138         // There is only one variant this argument could be; put it into the argument entry.
139         arg.push_back (thread_idx_arg);
140 
141         // Push the data for the first argument into the m_arguments vector.
142         m_arguments.push_back (arg);
143     }
144 
145     ~CommandObjectThreadBacktrace()
146     {
147     }
148 
149     virtual Options *
150     GetOptions ()
151     {
152         return &m_options;
153     }
154 
155     virtual bool
156     Execute (Args& command, CommandReturnObject &result)
157     {
158         result.SetStatus (eReturnStatusSuccessFinishResult);
159         Stream &strm = result.GetOutputStream();
160 
161         // Don't show source context when doing backtraces.
162         const uint32_t num_frames_with_source = 0;
163         if (command.GetArgumentCount() == 0)
164         {
165             ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
166             if (exe_ctx.thread)
167             {
168                 // Thread::GetStatus() returns the number of frames shown.
169                 if (exe_ctx.thread->GetStatus (strm,
170                                                m_options.m_start,
171                                                m_options.m_count,
172                                                num_frames_with_source))
173                 {
174                     result.SetStatus (eReturnStatusSuccessFinishResult);
175                 }
176             }
177             else
178             {
179                 result.AppendError ("invalid thread");
180                 result.SetStatus (eReturnStatusFailed);
181             }
182         }
183         else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
184         {
185             Process *process = m_interpreter.GetExecutionContext().process;
186             uint32_t num_threads = process->GetThreadList().GetSize();
187             for (uint32_t i = 0; i < num_threads; i++)
188             {
189                 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
190                 if (!thread_sp->GetStatus (strm,
191                                            m_options.m_start,
192                                            m_options.m_count,
193                                            num_frames_with_source))
194                 {
195                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
196                     result.SetStatus (eReturnStatusFailed);
197                     return false;
198                 }
199 
200                 if (i < num_threads - 1)
201                     result.AppendMessage("");
202 
203             }
204         }
205         else
206         {
207             uint32_t num_args = command.GetArgumentCount();
208             Process *process = m_interpreter.GetExecutionContext().process;
209             std::vector<ThreadSP> thread_sps;
210 
211             for (uint32_t i = 0; i < num_args; i++)
212             {
213                 bool success;
214 
215                 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
216                 if (!success)
217                 {
218                     result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
219                     result.SetStatus (eReturnStatusFailed);
220                     return false;
221                 }
222 
223                 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
224 
225                 if (!thread_sps[i])
226                 {
227                     result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
228                     result.SetStatus (eReturnStatusFailed);
229                     return false;
230                 }
231 
232             }
233 
234             for (uint32_t i = 0; i < num_args; i++)
235             {
236                 if (!thread_sps[i]->GetStatus (strm,
237                                                m_options.m_start,
238                                                m_options.m_count,
239                                                num_frames_with_source))
240                 {
241                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
242                     result.SetStatus (eReturnStatusFailed);
243                     return false;
244                 }
245 
246                 if (i < num_args - 1)
247                     result.AppendMessage("");
248             }
249         }
250         return result.Succeeded();
251     }
252 protected:
253     CommandOptions m_options;
254 };
255 
256 OptionDefinition
257 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
258 {
259 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
260 { LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
261 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
262 };
263 
264 enum StepScope
265 {
266     eStepScopeSource,
267     eStepScopeInstruction
268 };
269 
270 class CommandObjectThreadStepWithTypeAndScope : public CommandObject
271 {
272 public:
273 
274     class CommandOptions : public Options
275     {
276     public:
277 
278         CommandOptions (CommandInterpreter &interpreter) :
279             Options (interpreter)
280         {
281             // Keep default values of all options in one place: OptionParsingStarting ()
282             OptionParsingStarting ();
283         }
284 
285         virtual
286         ~CommandOptions ()
287         {
288         }
289 
290         virtual Error
291         SetOptionValue (uint32_t option_idx, const char *option_arg)
292         {
293             Error error;
294             char short_option = (char) m_getopt_table[option_idx].val;
295 
296             switch (short_option)
297             {
298             case 'a':
299                 {
300                     bool success;
301                     m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
302                     if (!success)
303                         error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
304                 }
305                 break;
306 
307             case 'm':
308                 {
309                     bool found_one = false;
310                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
311                     m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
312                     if (!found_one)
313                         error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
314                 }
315                 break;
316 
317             case 'r':
318                 {
319                     m_avoid_regexp.clear();
320                     m_avoid_regexp.assign(option_arg);
321                 }
322                 break;
323 
324             default:
325                 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
326                 break;
327 
328             }
329             return error;
330         }
331 
332         void
333         OptionParsingStarting ()
334         {
335             m_avoid_no_debug = true;
336             m_run_mode = eOnlyDuringStepping;
337             m_avoid_regexp.clear();
338         }
339 
340         const OptionDefinition*
341         GetDefinitions ()
342         {
343             return g_option_table;
344         }
345 
346         // Options table: Required for subclasses of Options.
347 
348         static OptionDefinition g_option_table[];
349 
350         // Instance variables to hold the values for command options.
351         bool m_avoid_no_debug;
352         RunMode m_run_mode;
353         std::string m_avoid_regexp;
354     };
355 
356     CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
357                                              const char *name,
358                                              const char *help,
359                                              const char *syntax,
360                                              uint32_t flags,
361                                              StepType step_type,
362                                              StepScope step_scope) :
363         CommandObject (interpreter, name, help, syntax, flags),
364         m_step_type (step_type),
365         m_step_scope (step_scope),
366         m_options (interpreter)
367     {
368         CommandArgumentEntry arg;
369         CommandArgumentData thread_id_arg;
370 
371         // Define the first (and only) variant of this arg.
372         thread_id_arg.arg_type = eArgTypeThreadID;
373         thread_id_arg.arg_repetition = eArgRepeatOptional;
374 
375         // There is only one variant this argument could be; put it into the argument entry.
376         arg.push_back (thread_id_arg);
377 
378         // Push the data for the first argument into the m_arguments vector.
379         m_arguments.push_back (arg);
380     }
381 
382     virtual
383     ~CommandObjectThreadStepWithTypeAndScope ()
384     {
385     }
386 
387     virtual
388     Options *
389     GetOptions ()
390     {
391         return &m_options;
392     }
393 
394     virtual bool
395     Execute
396     (
397         Args& command,
398         CommandReturnObject &result
399     )
400     {
401         Process *process = m_interpreter.GetExecutionContext().process;
402         bool synchronous_execution = m_interpreter.GetSynchronous();
403 
404         if (process == NULL)
405         {
406             result.AppendError ("need a valid process to step");
407             result.SetStatus (eReturnStatusFailed);
408 
409         }
410         else
411         {
412             const uint32_t num_threads = process->GetThreadList().GetSize();
413             Thread *thread = NULL;
414 
415             if (command.GetArgumentCount() == 0)
416             {
417                 thread = process->GetThreadList().GetSelectedThread().get();
418                 if (thread == NULL)
419                 {
420                     result.AppendError ("no selected thread in process");
421                     result.SetStatus (eReturnStatusFailed);
422                     return false;
423                 }
424             }
425             else
426             {
427                 const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
428                 uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
429                 if (step_thread_idx == LLDB_INVALID_INDEX32)
430                 {
431                     result.AppendErrorWithFormat ("Invalid thread index '%s'.\n", thread_idx_cstr);
432                     result.SetStatus (eReturnStatusFailed);
433                     return false;
434                 }
435                 thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
436                 if (thread == NULL)
437                 {
438                     result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
439                                                   step_thread_idx, num_threads);
440                     result.SetStatus (eReturnStatusFailed);
441                     return false;
442                 }
443             }
444 
445             const bool abort_other_plans = false;
446             const lldb::RunMode stop_other_threads = m_options.m_run_mode;
447 
448             // This is a bit unfortunate, but not all the commands in this command object support
449             // only while stepping, so I use the bool for them.
450             bool bool_stop_other_threads;
451             if (m_options.m_run_mode == eAllThreads)
452                 bool_stop_other_threads = false;
453             else
454                 bool_stop_other_threads = true;
455 
456             if (m_step_type == eStepTypeInto)
457             {
458                 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
459                 ThreadPlan *new_plan;
460 
461                 if (frame->HasDebugInformation ())
462                 {
463                     new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
464                                                                     frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
465                                                                     frame->GetSymbolContext(eSymbolContextEverything),
466                                                                     stop_other_threads,
467                                                                     m_options.m_avoid_no_debug);
468                     if (new_plan && !m_options.m_avoid_regexp.empty())
469                     {
470                         ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
471                         step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
472                     }
473                 }
474                 else
475                     new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
476 
477                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
478                 process->Resume ();
479             }
480             else if (m_step_type == eStepTypeOver)
481             {
482                 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
483                 ThreadPlan *new_plan;
484 
485                 if (frame->HasDebugInformation())
486                     new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
487                                                                     m_step_type,
488                                                                     frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
489                                                                     frame->GetSymbolContext(eSymbolContextEverything),
490                                                                     stop_other_threads,
491                                                                     false);
492                 else
493                     new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
494                                                                                 abort_other_plans,
495                                                                                 bool_stop_other_threads);
496 
497                 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
498                 // Maybe there should be a parameter to control this.
499                 new_plan->SetOkayToDiscard(false);
500 
501                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
502                 process->Resume ();
503             }
504             else if (m_step_type == eStepTypeTrace)
505             {
506                 thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
507                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
508                 process->Resume ();
509             }
510             else if (m_step_type == eStepTypeTraceOver)
511             {
512                 thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
513                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
514                 process->Resume ();
515             }
516             else if (m_step_type == eStepTypeOut)
517             {
518                 ThreadPlan *new_plan;
519 
520                 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
521                                                               NULL,
522                                                               false,
523                                                               bool_stop_other_threads,
524                                                               eVoteYes,
525                                                               eVoteNoOpinion,
526                                                               thread->GetSelectedFrameIndex());
527                 // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
528                 // Maybe there should be a parameter to control this.
529                 new_plan->SetOkayToDiscard(false);
530 
531                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
532                 process->Resume ();
533             }
534             else
535             {
536                 result.AppendError ("step type is not supported");
537                 result.SetStatus (eReturnStatusFailed);
538             }
539             if (synchronous_execution)
540             {
541                 StateType state = process->WaitForProcessToStop (NULL);
542 
543                 //EventSP event_sp;
544                 //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
545                 //while (! StateIsStoppedState (state))
546                 //  {
547                 //    state = process->WaitForStateChangedEvents (NULL, event_sp);
548                 //  }
549                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
550                 result.SetDidChangeProcessState (true);
551                 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
552                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
553             }
554         }
555         return result.Succeeded();
556     }
557 
558 protected:
559     StepType m_step_type;
560     StepScope m_step_scope;
561     CommandOptions m_options;
562 };
563 
564 static OptionEnumValueElement
565 g_tri_running_mode[] =
566 {
567 { eOnlyThisThread,     "this-thread",    "Run only this thread"},
568 { eAllThreads,         "all-threads",    "Run all threads"},
569 { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
570 { 0, NULL, NULL }
571 };
572 
573 static OptionEnumValueElement
574 g_duo_running_mode[] =
575 {
576 { eOnlyThisThread,     "this-thread",    "Run only this thread"},
577 { eAllThreads,         "all-threads",    "Run all threads"},
578 { 0, NULL, NULL }
579 };
580 
581 OptionDefinition
582 CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
583 {
584 { LLDB_OPT_SET_1, false, "avoid-no-debug",  'a', required_argument, NULL,               0, eArgTypeBoolean,     "A boolean value that sets whether step-in will step over functions with no debug information."},
585 { LLDB_OPT_SET_1, false, "run-mode",        'm', required_argument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
586 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL,               0, eArgTypeRegularExpression,   "A regular expression that defines function names to step over."},
587 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
588 };
589 
590 
591 //-------------------------------------------------------------------------
592 // CommandObjectThreadContinue
593 //-------------------------------------------------------------------------
594 
595 class CommandObjectThreadContinue : public CommandObject
596 {
597 public:
598 
599     CommandObjectThreadContinue (CommandInterpreter &interpreter) :
600         CommandObject (interpreter,
601                        "thread continue",
602                        "Continue execution of one or more threads in an active process.",
603                        NULL,
604                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
605     {
606         CommandArgumentEntry arg;
607         CommandArgumentData thread_idx_arg;
608 
609         // Define the first (and only) variant of this arg.
610         thread_idx_arg.arg_type = eArgTypeThreadIndex;
611         thread_idx_arg.arg_repetition = eArgRepeatPlus;
612 
613         // There is only one variant this argument could be; put it into the argument entry.
614         arg.push_back (thread_idx_arg);
615 
616         // Push the data for the first argument into the m_arguments vector.
617         m_arguments.push_back (arg);
618     }
619 
620 
621     virtual
622     ~CommandObjectThreadContinue ()
623     {
624     }
625 
626     virtual bool
627     Execute
628     (
629         Args& command,
630         CommandReturnObject &result
631     )
632     {
633         bool synchronous_execution = m_interpreter.GetSynchronous ();
634 
635         if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
636         {
637             result.AppendError ("invalid target, create a debug target using the 'target create' command");
638             result.SetStatus (eReturnStatusFailed);
639             return false;
640         }
641 
642         Process *process = m_interpreter.GetExecutionContext().process;
643         if (process == NULL)
644         {
645             result.AppendError ("no process exists. Cannot continue");
646             result.SetStatus (eReturnStatusFailed);
647             return false;
648         }
649 
650         StateType state = process->GetState();
651         if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
652         {
653             const uint32_t num_threads = process->GetThreadList().GetSize();
654             uint32_t idx;
655             const size_t argc = command.GetArgumentCount();
656             if (argc > 0)
657             {
658                 std::vector<uint32_t> resume_thread_indexes;
659                 for (uint32_t i=0; i<argc; ++i)
660                 {
661                     idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
662                     if (idx < num_threads)
663                         resume_thread_indexes.push_back(idx);
664                     else
665                         result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
666                 }
667 
668                 if (resume_thread_indexes.empty())
669                 {
670                     result.AppendError ("no valid thread indexes were specified");
671                     result.SetStatus (eReturnStatusFailed);
672                     return false;
673                 }
674                 else
675                 {
676                     result.AppendMessage ("Resuming thread ");
677                     for (idx=0; idx<num_threads; ++idx)
678                     {
679                         Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
680                         if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
681                         {
682                             result.AppendMessageWithFormat ("%u ", idx);
683                             thread->SetResumeState (eStateRunning);
684                         }
685                         else
686                         {
687                             thread->SetResumeState (eStateSuspended);
688                         }
689                     }
690                     result.AppendMessageWithFormat ("in process %i\n", process->GetID());
691                 }
692             }
693             else
694             {
695                 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
696                 if (current_thread == NULL)
697                 {
698                     result.AppendError ("the process doesn't have a current thread");
699                     result.SetStatus (eReturnStatusFailed);
700                     return false;
701                 }
702                 // Set the actions that the threads should each take when resuming
703                 for (idx=0; idx<num_threads; ++idx)
704                 {
705                     Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
706                     if (thread == current_thread)
707                     {
708                         result.AppendMessageWithFormat ("Resuming thread 0x%4.4x in process %i\n", thread->GetID(), process->GetID());
709                         thread->SetResumeState (eStateRunning);
710                     }
711                     else
712                     {
713                         thread->SetResumeState (eStateSuspended);
714                     }
715                 }
716             }
717 
718             Error error (process->Resume());
719             if (error.Success())
720             {
721                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
722                 if (synchronous_execution)
723                 {
724                     state = process->WaitForProcessToStop (NULL);
725 
726                     result.SetDidChangeProcessState (true);
727                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
728                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
729                 }
730                 else
731                 {
732                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
733                 }
734             }
735             else
736             {
737                 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
738                 result.SetStatus (eReturnStatusFailed);
739             }
740         }
741         else
742         {
743             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
744                                           StateAsCString(state));
745             result.SetStatus (eReturnStatusFailed);
746         }
747 
748         return result.Succeeded();
749     }
750 
751 };
752 
753 //-------------------------------------------------------------------------
754 // CommandObjectThreadUntil
755 //-------------------------------------------------------------------------
756 
757 class CommandObjectThreadUntil : public CommandObject
758 {
759 public:
760 
761     class CommandOptions : public Options
762     {
763     public:
764         uint32_t m_thread_idx;
765         uint32_t m_frame_idx;
766 
767         CommandOptions (CommandInterpreter &interpreter) :
768             Options (interpreter),
769             m_thread_idx(LLDB_INVALID_THREAD_ID),
770             m_frame_idx(LLDB_INVALID_FRAME_ID)
771         {
772             // Keep default values of all options in one place: OptionParsingStarting ()
773             OptionParsingStarting ();
774         }
775 
776         virtual
777         ~CommandOptions ()
778         {
779         }
780 
781         virtual Error
782         SetOptionValue (uint32_t option_idx, const char *option_arg)
783         {
784             Error error;
785             char short_option = (char) m_getopt_table[option_idx].val;
786 
787             switch (short_option)
788             {
789                 case 't':
790                 {
791                     m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
792                     if (m_thread_idx == LLDB_INVALID_INDEX32)
793                     {
794                         error.SetErrorStringWithFormat ("Invalid thread index '%s'.\n", option_arg);
795                     }
796                 }
797                 break;
798                 case 'f':
799                 {
800                     m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
801                     if (m_frame_idx == LLDB_INVALID_FRAME_ID)
802                     {
803                         error.SetErrorStringWithFormat ("Invalid frame index '%s'.\n", option_arg);
804                     }
805                 }
806                 break;
807                 case 'm':
808                 {
809                     bool found_one = false;
810                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
811                     lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
812 
813                     if (!found_one)
814                         error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
815                     else if (run_mode == eAllThreads)
816                         m_stop_others = false;
817                     else
818                         m_stop_others = true;
819 
820                 }
821                 break;
822                 default:
823                     error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
824                     break;
825 
826             }
827             return error;
828         }
829 
830         void
831         OptionParsingStarting ()
832         {
833             m_thread_idx = LLDB_INVALID_THREAD_ID;
834             m_frame_idx = 0;
835             m_stop_others = false;
836         }
837 
838         const OptionDefinition*
839         GetDefinitions ()
840         {
841             return g_option_table;
842         }
843 
844         uint32_t m_step_thread_idx;
845         bool m_stop_others;
846 
847         // Options table: Required for subclasses of Options.
848 
849         static OptionDefinition g_option_table[];
850 
851         // Instance variables to hold the values for command options.
852     };
853 
854     CommandObjectThreadUntil (CommandInterpreter &interpreter) :
855         CommandObject (interpreter,
856                        "thread until",
857                        "Run the current or specified thread until it reaches a given line number or leaves the current function.",
858                        NULL,
859                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
860         m_options (interpreter)
861     {
862         CommandArgumentEntry arg;
863         CommandArgumentData line_num_arg;
864 
865         // Define the first (and only) variant of this arg.
866         line_num_arg.arg_type = eArgTypeLineNum;
867         line_num_arg.arg_repetition = eArgRepeatPlain;
868 
869         // There is only one variant this argument could be; put it into the argument entry.
870         arg.push_back (line_num_arg);
871 
872         // Push the data for the first argument into the m_arguments vector.
873         m_arguments.push_back (arg);
874     }
875 
876 
877     virtual
878     ~CommandObjectThreadUntil ()
879     {
880     }
881 
882     virtual
883     Options *
884     GetOptions ()
885     {
886         return &m_options;
887     }
888 
889     virtual bool
890     Execute
891     (
892         Args& command,
893         CommandReturnObject &result
894     )
895     {
896         bool synchronous_execution = m_interpreter.GetSynchronous ();
897 
898         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
899         if (target == NULL)
900         {
901             result.AppendError ("invalid target, create a debug target using the 'target create' command");
902             result.SetStatus (eReturnStatusFailed);
903             return false;
904         }
905 
906         Process *process = m_interpreter.GetExecutionContext().process;
907         if (process == NULL)
908         {
909             result.AppendError ("need a valid process to step");
910             result.SetStatus (eReturnStatusFailed);
911 
912         }
913         else
914         {
915             Thread *thread = NULL;
916             uint32_t line_number;
917 
918             if (command.GetArgumentCount() != 1)
919             {
920                 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
921                 result.SetStatus (eReturnStatusFailed);
922                 return false;
923             }
924 
925             line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
926             if (line_number == UINT32_MAX)
927             {
928                 result.AppendErrorWithFormat ("Invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
929                 result.SetStatus (eReturnStatusFailed);
930                 return false;
931             }
932 
933             if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
934             {
935                 thread = process->GetThreadList().GetSelectedThread().get();
936             }
937             else
938             {
939                 thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
940             }
941 
942             if (thread == NULL)
943             {
944                 const uint32_t num_threads = process->GetThreadList().GetSize();
945                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
946                                               m_options.m_thread_idx,
947                                               num_threads);
948                 result.SetStatus (eReturnStatusFailed);
949                 return false;
950             }
951 
952             const bool abort_other_plans = true;
953 
954             StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
955             if (frame == NULL)
956             {
957 
958                 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
959                                               m_options.m_frame_idx,
960                                               m_options.m_thread_idx);
961                 result.SetStatus (eReturnStatusFailed);
962                 return false;
963             }
964 
965             ThreadPlan *new_plan;
966 
967             if (frame->HasDebugInformation ())
968             {
969                 // Finally we got here...  Translate the given line number to a bunch of addresses:
970                 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
971                 LineTable *line_table = NULL;
972                 if (sc.comp_unit)
973                     line_table = sc.comp_unit->GetLineTable();
974 
975                 if (line_table == NULL)
976                 {
977                     result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
978                                                  m_options.m_frame_idx, m_options.m_thread_idx);
979                     result.SetStatus (eReturnStatusFailed);
980                     return false;
981                 }
982 
983                 LineEntry function_start;
984                 uint32_t index_ptr = 0, end_ptr;
985                 std::vector<addr_t> address_list;
986 
987                 // Find the beginning & end index of the
988                 AddressRange fun_addr_range = sc.function->GetAddressRange();
989                 Address fun_start_addr = fun_addr_range.GetBaseAddress();
990                 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
991 
992                 Address fun_end_addr(fun_start_addr.GetSection(),
993                                      fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
994                 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
995 
996                 bool all_in_function = true;
997 
998                 while (index_ptr <= end_ptr)
999                 {
1000                     LineEntry line_entry;
1001                     index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
1002                     if (index_ptr == UINT32_MAX)
1003                         break;
1004 
1005                     addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1006                     if (address != LLDB_INVALID_ADDRESS)
1007                     {
1008                         if (fun_addr_range.ContainsLoadAddress (address, target))
1009                             address_list.push_back (address);
1010                         else
1011                             all_in_function = false;
1012                     }
1013                     index_ptr++;
1014                 }
1015 
1016                 if (address_list.size() == 0)
1017                 {
1018                     if (all_in_function)
1019                         result.AppendErrorWithFormat ("No line entries matching until target.\n");
1020                     else
1021                         result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1022 
1023                     result.SetStatus (eReturnStatusFailed);
1024                     return false;
1025                 }
1026 
1027                 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1028                                                                 &address_list.front(),
1029                                                                 address_list.size(),
1030                                                                 m_options.m_stop_others,
1031                                                                 thread->GetSelectedFrameIndex ());
1032                 new_plan->SetOkayToDiscard(false);
1033             }
1034             else
1035             {
1036                 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1037                                               m_options.m_frame_idx,
1038                                               m_options.m_thread_idx);
1039                 result.SetStatus (eReturnStatusFailed);
1040                 return false;
1041 
1042             }
1043 
1044             process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1045             Error error (process->Resume ());
1046             if (error.Success())
1047             {
1048                 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID());
1049                 if (synchronous_execution)
1050                 {
1051                     StateType state = process->WaitForProcessToStop (NULL);
1052 
1053                     result.SetDidChangeProcessState (true);
1054                     result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state));
1055                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1056                 }
1057                 else
1058                 {
1059                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1060                 }
1061             }
1062             else
1063             {
1064                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1065                 result.SetStatus (eReturnStatusFailed);
1066             }
1067 
1068         }
1069         return result.Succeeded();
1070     }
1071 protected:
1072     CommandOptions m_options;
1073 
1074 };
1075 
1076 OptionDefinition
1077 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1078 {
1079 { LLDB_OPT_SET_1, false, "frame",   'f', required_argument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1080 { LLDB_OPT_SET_1, false, "thread",  't', required_argument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1081 { LLDB_OPT_SET_1, false, "run-mode",'m', required_argument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
1082 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1083 };
1084 
1085 
1086 //-------------------------------------------------------------------------
1087 // CommandObjectThreadSelect
1088 //-------------------------------------------------------------------------
1089 
1090 class CommandObjectThreadSelect : public CommandObject
1091 {
1092 public:
1093 
1094     CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1095         CommandObject (interpreter,
1096                        "thread select",
1097                        "Select a thread as the currently active thread.",
1098                        NULL,
1099                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1100     {
1101         CommandArgumentEntry arg;
1102         CommandArgumentData thread_idx_arg;
1103 
1104         // Define the first (and only) variant of this arg.
1105         thread_idx_arg.arg_type = eArgTypeThreadIndex;
1106         thread_idx_arg.arg_repetition = eArgRepeatPlain;
1107 
1108         // There is only one variant this argument could be; put it into the argument entry.
1109         arg.push_back (thread_idx_arg);
1110 
1111         // Push the data for the first argument into the m_arguments vector.
1112         m_arguments.push_back (arg);
1113     }
1114 
1115 
1116     virtual
1117     ~CommandObjectThreadSelect ()
1118     {
1119     }
1120 
1121     virtual bool
1122     Execute
1123     (
1124         Args& command,
1125         CommandReturnObject &result
1126     )
1127     {
1128         Process *process = m_interpreter.GetExecutionContext().process;
1129         if (process == NULL)
1130         {
1131             result.AppendError ("no process");
1132             result.SetStatus (eReturnStatusFailed);
1133             return false;
1134         }
1135         else if (command.GetArgumentCount() != 1)
1136         {
1137             result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1138             result.SetStatus (eReturnStatusFailed);
1139             return false;
1140         }
1141 
1142         uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1143 
1144         Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1145         if (new_thread == NULL)
1146         {
1147             result.AppendErrorWithFormat ("Invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1148             result.SetStatus (eReturnStatusFailed);
1149             return false;
1150         }
1151 
1152         process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
1153         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1154 
1155         const uint32_t start_frame = 0;
1156         const uint32_t num_frames = 1;
1157         const uint32_t num_frames_with_source = 1;
1158         new_thread->GetStatus (result.GetOutputStream(),
1159                                start_frame,
1160                                num_frames,
1161                                num_frames_with_source);
1162 
1163         return result.Succeeded();
1164     }
1165 
1166 };
1167 
1168 
1169 //-------------------------------------------------------------------------
1170 // CommandObjectThreadList
1171 //-------------------------------------------------------------------------
1172 
1173 class CommandObjectThreadList : public CommandObject
1174 {
1175 public:
1176 
1177 
1178     CommandObjectThreadList (CommandInterpreter &interpreter):
1179         CommandObject (interpreter,
1180                        "thread list",
1181                        "Show a summary of all current threads in a process.",
1182                        "thread list",
1183                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1184     {
1185     }
1186 
1187     ~CommandObjectThreadList()
1188     {
1189     }
1190 
1191     bool
1192     Execute
1193     (
1194         Args& command,
1195         CommandReturnObject &result
1196     )
1197     {
1198         Stream &strm = result.GetOutputStream();
1199         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1200         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1201         if (exe_ctx.process)
1202         {
1203             const bool only_threads_with_stop_reason = false;
1204             const uint32_t start_frame = 0;
1205             const uint32_t num_frames = 0;
1206             const uint32_t num_frames_with_source = 0;
1207             exe_ctx.process->GetStatus(strm);
1208             exe_ctx.process->GetThreadStatus (strm,
1209                                               only_threads_with_stop_reason,
1210                                               start_frame,
1211                                               num_frames,
1212                                               num_frames_with_source);
1213         }
1214         else
1215         {
1216             result.AppendError ("no current location or status available");
1217             result.SetStatus (eReturnStatusFailed);
1218         }
1219         return result.Succeeded();
1220     }
1221 };
1222 
1223 //-------------------------------------------------------------------------
1224 // CommandObjectMultiwordThread
1225 //-------------------------------------------------------------------------
1226 
1227 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1228     CommandObjectMultiword (interpreter,
1229                             "thread",
1230                             "A set of commands for operating on one or more threads within a running process.",
1231                             "thread <subcommand> [<subcommand-options>]")
1232 {
1233     LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1234     LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1235     LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1236     LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1237     LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1238     LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1239                                                     interpreter,
1240                                                     "thread step-in",
1241                                                     "Source level single step in specified thread (current thread, if none specified).",
1242                                                     NULL,
1243                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1244                                                     eStepTypeInto,
1245                                                     eStepScopeSource)));
1246 
1247     LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1248                                                     interpreter,
1249                                                     "thread step-out",
1250                                                     "Finish executing the current function and return to its call site in specified thread (current thread, if none specified).",
1251                                                     NULL,
1252                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1253                                                     eStepTypeOut,
1254                                                     eStepScopeSource)));
1255 
1256     LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1257                                                     interpreter,
1258                                                     "thread step-over",
1259                                                     "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1260                                                     NULL,
1261                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1262                                                     eStepTypeOver,
1263                                                     eStepScopeSource)));
1264 
1265     LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1266                                                     interpreter,
1267                                                     "thread step-inst",
1268                                                     "Single step one instruction in specified thread (current thread, if none specified).",
1269                                                     NULL,
1270                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1271                                                     eStepTypeTrace,
1272                                                     eStepScopeInstruction)));
1273 
1274     LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1275                                                     interpreter,
1276                                                     "thread step-inst-over",
1277                                                     "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1278                                                     NULL,
1279                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1280                                                     eStepTypeTraceOver,
1281                                                     eStepScopeInstruction)));
1282 }
1283 
1284 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1285 {
1286 }
1287 
1288 
1289