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