xref: /llvm-project/lldb/source/Commands/CommandObjectThread.cpp (revision 41f2b940c974b0ef7082a638cd23f128e167e8d1)
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/Core/State.h"
17 #include "lldb/Core/SourceManager.h"
18 #include "lldb/Host/Host.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 #include "lldb/Interpreter/Options.h"
22 #include "lldb/Symbol/CompileUnit.h"
23 #include "lldb/Symbol/Function.h"
24 #include "lldb/Symbol/LineTable.h"
25 #include "lldb/Symbol/LineEntry.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/RegisterContext.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/Thread.h"
30 #include "lldb/Target/ThreadPlan.h"
31 #include "lldb/Target/ThreadPlanStepInstruction.h"
32 #include "lldb/Target/ThreadPlanStepOut.h"
33 #include "lldb/Target/ThreadPlanStepRange.h"
34 #include "lldb/Target/ThreadPlanStepInRange.h"
35 
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 
41 //-------------------------------------------------------------------------
42 // CommandObjectThreadBacktrace
43 //-------------------------------------------------------------------------
44 
45 class CommandObjectThreadBacktrace : public CommandObjectParsed
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         CommandObjectParsed (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 protected:
156     virtual bool
157     DoExecute (Args& command, CommandReturnObject &result)
158     {
159         result.SetStatus (eReturnStatusSuccessFinishResult);
160         Stream &strm = result.GetOutputStream();
161 
162         // Don't show source context when doing backtraces.
163         const uint32_t num_frames_with_source = 0;
164         if (command.GetArgumentCount() == 0)
165         {
166             ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
167             Thread *thread = exe_ctx.GetThreadPtr();
168             if (thread)
169             {
170                 // Thread::GetStatus() returns the number of frames shown.
171                 if (thread->GetStatus (strm,
172                                        m_options.m_start,
173                                        m_options.m_count,
174                                        num_frames_with_source))
175                 {
176                     result.SetStatus (eReturnStatusSuccessFinishResult);
177                 }
178             }
179             else
180             {
181                 result.AppendError ("invalid thread");
182                 result.SetStatus (eReturnStatusFailed);
183             }
184         }
185         else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
186         {
187             Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
188             Mutex::Locker locker (process->GetThreadList().GetMutex());
189             uint32_t num_threads = process->GetThreadList().GetSize();
190             for (uint32_t i = 0; i < num_threads; i++)
191             {
192                 ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
193                 if (!thread_sp->GetStatus (strm,
194                                            m_options.m_start,
195                                            m_options.m_count,
196                                            num_frames_with_source))
197                 {
198                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
199                     result.SetStatus (eReturnStatusFailed);
200                     return false;
201                 }
202 
203                 if (i < num_threads - 1)
204                     result.AppendMessage("");
205 
206             }
207         }
208         else
209         {
210             uint32_t num_args = command.GetArgumentCount();
211             Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
212             Mutex::Locker locker (process->GetThreadList().GetMutex());
213             std::vector<ThreadSP> thread_sps;
214 
215             for (uint32_t i = 0; i < num_args; i++)
216             {
217                 bool success;
218 
219                 uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
220                 if (!success)
221                 {
222                     result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
223                     result.SetStatus (eReturnStatusFailed);
224                     return false;
225                 }
226 
227                 thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx));
228 
229                 if (!thread_sps[i])
230                 {
231                     result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
232                     result.SetStatus (eReturnStatusFailed);
233                     return false;
234                 }
235 
236             }
237 
238             for (uint32_t i = 0; i < num_args; i++)
239             {
240                 if (!thread_sps[i]->GetStatus (strm,
241                                                m_options.m_start,
242                                                m_options.m_count,
243                                                num_frames_with_source))
244                 {
245                     result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i));
246                     result.SetStatus (eReturnStatusFailed);
247                     return false;
248                 }
249 
250                 if (i < num_args - 1)
251                     result.AppendMessage("");
252             }
253         }
254         return result.Succeeded();
255     }
256 
257     CommandOptions m_options;
258 };
259 
260 OptionDefinition
261 CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
262 {
263 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
264 { LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
265 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
266 };
267 
268 enum StepScope
269 {
270     eStepScopeSource,
271     eStepScopeInstruction
272 };
273 
274 class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
275 {
276 public:
277 
278     class CommandOptions : public Options
279     {
280     public:
281 
282         CommandOptions (CommandInterpreter &interpreter) :
283             Options (interpreter)
284         {
285             // Keep default values of all options in one place: OptionParsingStarting ()
286             OptionParsingStarting ();
287         }
288 
289         virtual
290         ~CommandOptions ()
291         {
292         }
293 
294         virtual Error
295         SetOptionValue (uint32_t option_idx, const char *option_arg)
296         {
297             Error error;
298             char short_option = (char) m_getopt_table[option_idx].val;
299 
300             switch (short_option)
301             {
302             case 'a':
303                 {
304                     bool success;
305                     m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
306                     if (!success)
307                         error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
308                 }
309                 break;
310 
311             case 'm':
312                 {
313                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
314                     m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
315                 }
316                 break;
317 
318             case 'r':
319                 {
320                     m_avoid_regexp.clear();
321                     m_avoid_regexp.assign(option_arg);
322                 }
323                 break;
324 
325             default:
326                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
327                 break;
328 
329             }
330             return error;
331         }
332 
333         void
334         OptionParsingStarting ()
335         {
336             m_avoid_no_debug = true;
337             m_run_mode = eOnlyDuringStepping;
338             m_avoid_regexp.clear();
339         }
340 
341         const OptionDefinition*
342         GetDefinitions ()
343         {
344             return g_option_table;
345         }
346 
347         // Options table: Required for subclasses of Options.
348 
349         static OptionDefinition g_option_table[];
350 
351         // Instance variables to hold the values for command options.
352         bool m_avoid_no_debug;
353         RunMode m_run_mode;
354         std::string m_avoid_regexp;
355     };
356 
357     CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
358                                              const char *name,
359                                              const char *help,
360                                              const char *syntax,
361                                              uint32_t flags,
362                                              StepType step_type,
363                                              StepScope step_scope) :
364         CommandObjectParsed (interpreter, name, help, syntax, flags),
365         m_step_type (step_type),
366         m_step_scope (step_scope),
367         m_options (interpreter)
368     {
369         CommandArgumentEntry arg;
370         CommandArgumentData thread_id_arg;
371 
372         // Define the first (and only) variant of this arg.
373         thread_id_arg.arg_type = eArgTypeThreadID;
374         thread_id_arg.arg_repetition = eArgRepeatOptional;
375 
376         // There is only one variant this argument could be; put it into the argument entry.
377         arg.push_back (thread_id_arg);
378 
379         // Push the data for the first argument into the m_arguments vector.
380         m_arguments.push_back (arg);
381     }
382 
383     virtual
384     ~CommandObjectThreadStepWithTypeAndScope ()
385     {
386     }
387 
388     virtual
389     Options *
390     GetOptions ()
391     {
392         return &m_options;
393     }
394 
395 protected:
396     virtual bool
397     DoExecute (Args& command, CommandReturnObject &result)
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 CommandObjectParsed
598 {
599 public:
600 
601     CommandObjectThreadContinue (CommandInterpreter &interpreter) :
602         CommandObjectParsed (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     DoExecute (Args& command, CommandReturnObject &result)
630     {
631         bool synchronous_execution = m_interpreter.GetSynchronous ();
632 
633         if (!m_interpreter.GetDebugger().GetSelectedTarget().get())
634         {
635             result.AppendError ("invalid target, create a debug target using the 'target create' command");
636             result.SetStatus (eReturnStatusFailed);
637             return false;
638         }
639 
640         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
641         if (process == NULL)
642         {
643             result.AppendError ("no process exists. Cannot continue");
644             result.SetStatus (eReturnStatusFailed);
645             return false;
646         }
647 
648         StateType state = process->GetState();
649         if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
650         {
651             Mutex::Locker locker (process->GetThreadList().GetMutex());
652             const uint32_t num_threads = process->GetThreadList().GetSize();
653             const size_t argc = command.GetArgumentCount();
654             if (argc > 0)
655             {
656                 std::vector<Thread *> resume_threads;
657                 for (uint32_t i=0; i<argc; ++i)
658                 {
659                     bool success;
660                     const int base = 0;
661                     uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
662                     if (success)
663                     {
664                         Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
665 
666                         if (thread)
667                         {
668                             resume_threads.push_back(thread);
669                         }
670                         else
671                         {
672                             result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
673                             result.SetStatus (eReturnStatusFailed);
674                             return false;
675                         }
676                     }
677                     else
678                     {
679                         result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
680                         result.SetStatus (eReturnStatusFailed);
681                         return false;
682                     }
683                 }
684 
685                 if (resume_threads.empty())
686                 {
687                     result.AppendError ("no valid thread indexes were specified");
688                     result.SetStatus (eReturnStatusFailed);
689                     return false;
690                 }
691                 else
692                 {
693                     if (resume_threads.size() == 1)
694                         result.AppendMessageWithFormat ("Resuming thread: ");
695                     else
696                         result.AppendMessageWithFormat ("Resuming threads: ");
697 
698                     for (uint32_t idx=0; idx<num_threads; ++idx)
699                     {
700                         Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
701                         std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
702 
703                         if (this_thread_pos != resume_threads.end())
704                         {
705                             resume_threads.erase(this_thread_pos);
706                             if (resume_threads.size() > 0)
707                                 result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
708                             else
709                                 result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
710 
711                             thread->SetResumeState (eStateRunning);
712                         }
713                         else
714                         {
715                             thread->SetResumeState (eStateSuspended);
716                         }
717                     }
718                     result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
719                 }
720             }
721             else
722             {
723                 Thread *current_thread = process->GetThreadList().GetSelectedThread().get();
724                 if (current_thread == NULL)
725                 {
726                     result.AppendError ("the process doesn't have a current thread");
727                     result.SetStatus (eReturnStatusFailed);
728                     return false;
729                 }
730                 // Set the actions that the threads should each take when resuming
731                 for (uint32_t idx=0; idx<num_threads; ++idx)
732                 {
733                     Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
734                     if (thread == current_thread)
735                     {
736                         result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
737                         thread->SetResumeState (eStateRunning);
738                     }
739                     else
740                     {
741                         thread->SetResumeState (eStateSuspended);
742                     }
743                 }
744             }
745 
746             Error error (process->Resume());
747             if (error.Success())
748             {
749                 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
750                 if (synchronous_execution)
751                 {
752                     state = process->WaitForProcessToStop (NULL);
753 
754                     result.SetDidChangeProcessState (true);
755                     result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
756                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
757                 }
758                 else
759                 {
760                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
761                 }
762             }
763             else
764             {
765                 result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
766                 result.SetStatus (eReturnStatusFailed);
767             }
768         }
769         else
770         {
771             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
772                                           StateAsCString(state));
773             result.SetStatus (eReturnStatusFailed);
774         }
775 
776         return result.Succeeded();
777     }
778 
779 };
780 
781 //-------------------------------------------------------------------------
782 // CommandObjectThreadUntil
783 //-------------------------------------------------------------------------
784 
785 class CommandObjectThreadUntil : public CommandObjectParsed
786 {
787 public:
788 
789     class CommandOptions : public Options
790     {
791     public:
792         uint32_t m_thread_idx;
793         uint32_t m_frame_idx;
794 
795         CommandOptions (CommandInterpreter &interpreter) :
796             Options (interpreter),
797             m_thread_idx(LLDB_INVALID_THREAD_ID),
798             m_frame_idx(LLDB_INVALID_FRAME_ID)
799         {
800             // Keep default values of all options in one place: OptionParsingStarting ()
801             OptionParsingStarting ();
802         }
803 
804         virtual
805         ~CommandOptions ()
806         {
807         }
808 
809         virtual Error
810         SetOptionValue (uint32_t option_idx, const char *option_arg)
811         {
812             Error error;
813             char short_option = (char) m_getopt_table[option_idx].val;
814 
815             switch (short_option)
816             {
817                 case 't':
818                 {
819                     m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
820                     if (m_thread_idx == LLDB_INVALID_INDEX32)
821                     {
822                         error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
823                     }
824                 }
825                 break;
826                 case 'f':
827                 {
828                     m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
829                     if (m_frame_idx == LLDB_INVALID_FRAME_ID)
830                     {
831                         error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
832                     }
833                 }
834                 break;
835                 case 'm':
836                 {
837                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
838                     lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
839 
840                     if (error.Success())
841                     {
842                         if (run_mode == eAllThreads)
843                             m_stop_others = false;
844                         else
845                             m_stop_others = true;
846                     }
847                 }
848                 break;
849                 default:
850                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
851                     break;
852 
853             }
854             return error;
855         }
856 
857         void
858         OptionParsingStarting ()
859         {
860             m_thread_idx = LLDB_INVALID_THREAD_ID;
861             m_frame_idx = 0;
862             m_stop_others = false;
863         }
864 
865         const OptionDefinition*
866         GetDefinitions ()
867         {
868             return g_option_table;
869         }
870 
871         uint32_t m_step_thread_idx;
872         bool m_stop_others;
873 
874         // Options table: Required for subclasses of Options.
875 
876         static OptionDefinition g_option_table[];
877 
878         // Instance variables to hold the values for command options.
879     };
880 
881     CommandObjectThreadUntil (CommandInterpreter &interpreter) :
882         CommandObjectParsed (interpreter,
883                              "thread until",
884                              "Run the current or specified thread until it reaches a given line number or leaves the current function.",
885                              NULL,
886                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
887         m_options (interpreter)
888     {
889         CommandArgumentEntry arg;
890         CommandArgumentData line_num_arg;
891 
892         // Define the first (and only) variant of this arg.
893         line_num_arg.arg_type = eArgTypeLineNum;
894         line_num_arg.arg_repetition = eArgRepeatPlain;
895 
896         // There is only one variant this argument could be; put it into the argument entry.
897         arg.push_back (line_num_arg);
898 
899         // Push the data for the first argument into the m_arguments vector.
900         m_arguments.push_back (arg);
901     }
902 
903 
904     virtual
905     ~CommandObjectThreadUntil ()
906     {
907     }
908 
909     virtual
910     Options *
911     GetOptions ()
912     {
913         return &m_options;
914     }
915 
916 protected:
917     virtual bool
918     DoExecute (Args& command, CommandReturnObject &result)
919     {
920         bool synchronous_execution = m_interpreter.GetSynchronous ();
921 
922         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
923         if (target == NULL)
924         {
925             result.AppendError ("invalid target, create a debug target using the 'target create' command");
926             result.SetStatus (eReturnStatusFailed);
927             return false;
928         }
929 
930         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
931         if (process == NULL)
932         {
933             result.AppendError ("need a valid process to step");
934             result.SetStatus (eReturnStatusFailed);
935 
936         }
937         else
938         {
939             Thread *thread = NULL;
940             uint32_t line_number;
941 
942             if (command.GetArgumentCount() != 1)
943             {
944                 result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
945                 result.SetStatus (eReturnStatusFailed);
946                 return false;
947             }
948 
949             line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
950             if (line_number == UINT32_MAX)
951             {
952                 result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
953                 result.SetStatus (eReturnStatusFailed);
954                 return false;
955             }
956 
957             if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
958             {
959                 thread = process->GetThreadList().GetSelectedThread().get();
960             }
961             else
962             {
963                 thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
964             }
965 
966             if (thread == NULL)
967             {
968                 const uint32_t num_threads = process->GetThreadList().GetSize();
969                 result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
970                                               m_options.m_thread_idx,
971                                               num_threads);
972                 result.SetStatus (eReturnStatusFailed);
973                 return false;
974             }
975 
976             const bool abort_other_plans = false;
977 
978             StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
979             if (frame == NULL)
980             {
981 
982                 result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
983                                               m_options.m_frame_idx,
984                                               m_options.m_thread_idx);
985                 result.SetStatus (eReturnStatusFailed);
986                 return false;
987             }
988 
989             ThreadPlan *new_plan = NULL;
990 
991             if (frame->HasDebugInformation ())
992             {
993                 // Finally we got here...  Translate the given line number to a bunch of addresses:
994                 SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
995                 LineTable *line_table = NULL;
996                 if (sc.comp_unit)
997                     line_table = sc.comp_unit->GetLineTable();
998 
999                 if (line_table == NULL)
1000                 {
1001                     result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
1002                                                  m_options.m_frame_idx, m_options.m_thread_idx);
1003                     result.SetStatus (eReturnStatusFailed);
1004                     return false;
1005                 }
1006 
1007                 LineEntry function_start;
1008                 uint32_t index_ptr = 0, end_ptr;
1009                 std::vector<addr_t> address_list;
1010 
1011                 // Find the beginning & end index of the
1012                 AddressRange fun_addr_range = sc.function->GetAddressRange();
1013                 Address fun_start_addr = fun_addr_range.GetBaseAddress();
1014                 line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
1015 
1016                 Address fun_end_addr(fun_start_addr.GetSection(),
1017                                      fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
1018                 line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
1019 
1020                 bool all_in_function = true;
1021 
1022                 while (index_ptr <= end_ptr)
1023                 {
1024                     LineEntry line_entry;
1025                     const bool exact = false;
1026                     index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
1027                     if (index_ptr == UINT32_MAX)
1028                         break;
1029 
1030                     addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
1031                     if (address != LLDB_INVALID_ADDRESS)
1032                     {
1033                         if (fun_addr_range.ContainsLoadAddress (address, target))
1034                             address_list.push_back (address);
1035                         else
1036                             all_in_function = false;
1037                     }
1038                     index_ptr++;
1039                 }
1040 
1041                 if (address_list.size() == 0)
1042                 {
1043                     if (all_in_function)
1044                         result.AppendErrorWithFormat ("No line entries matching until target.\n");
1045                     else
1046                         result.AppendErrorWithFormat ("Until target outside of the current function.\n");
1047 
1048                     result.SetStatus (eReturnStatusFailed);
1049                     return false;
1050                 }
1051 
1052                 new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
1053                                                                 &address_list.front(),
1054                                                                 address_list.size(),
1055                                                                 m_options.m_stop_others,
1056                                                                 thread->GetSelectedFrameIndex ());
1057                 // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
1058                 // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
1059                 // will resume the original plan.
1060                 new_plan->SetIsMasterPlan (true);
1061                 new_plan->SetOkayToDiscard(false);
1062             }
1063             else
1064             {
1065                 result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
1066                                               m_options.m_frame_idx,
1067                                               m_options.m_thread_idx);
1068                 result.SetStatus (eReturnStatusFailed);
1069                 return false;
1070 
1071             }
1072 
1073             process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
1074             Error error (process->Resume ());
1075             if (error.Success())
1076             {
1077                 result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
1078                 if (synchronous_execution)
1079                 {
1080                     StateType state = process->WaitForProcessToStop (NULL);
1081 
1082                     result.SetDidChangeProcessState (true);
1083                     result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
1084                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1085                 }
1086                 else
1087                 {
1088                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
1089                 }
1090             }
1091             else
1092             {
1093                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
1094                 result.SetStatus (eReturnStatusFailed);
1095             }
1096 
1097         }
1098         return result.Succeeded();
1099     }
1100 
1101     CommandOptions m_options;
1102 
1103 };
1104 
1105 OptionDefinition
1106 CommandObjectThreadUntil::CommandOptions::g_option_table[] =
1107 {
1108 { LLDB_OPT_SET_1, false, "frame",   'f', required_argument, NULL,               0, eArgTypeFrameIndex,   "Frame index for until operation - defaults to 0"},
1109 { LLDB_OPT_SET_1, false, "thread",  't', required_argument, NULL,               0, eArgTypeThreadIndex,  "Thread index for the thread for until operation"},
1110 { 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"},
1111 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1112 };
1113 
1114 
1115 //-------------------------------------------------------------------------
1116 // CommandObjectThreadSelect
1117 //-------------------------------------------------------------------------
1118 
1119 class CommandObjectThreadSelect : public CommandObjectParsed
1120 {
1121 public:
1122 
1123     CommandObjectThreadSelect (CommandInterpreter &interpreter) :
1124         CommandObjectParsed (interpreter,
1125                              "thread select",
1126                              "Select a thread as the currently active thread.",
1127                              NULL,
1128                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1129     {
1130         CommandArgumentEntry arg;
1131         CommandArgumentData thread_idx_arg;
1132 
1133         // Define the first (and only) variant of this arg.
1134         thread_idx_arg.arg_type = eArgTypeThreadIndex;
1135         thread_idx_arg.arg_repetition = eArgRepeatPlain;
1136 
1137         // There is only one variant this argument could be; put it into the argument entry.
1138         arg.push_back (thread_idx_arg);
1139 
1140         // Push the data for the first argument into the m_arguments vector.
1141         m_arguments.push_back (arg);
1142     }
1143 
1144 
1145     virtual
1146     ~CommandObjectThreadSelect ()
1147     {
1148     }
1149 
1150 protected:
1151     virtual bool
1152     DoExecute (Args& command, CommandReturnObject &result)
1153     {
1154         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
1155         if (process == NULL)
1156         {
1157             result.AppendError ("no process");
1158             result.SetStatus (eReturnStatusFailed);
1159             return false;
1160         }
1161         else if (command.GetArgumentCount() != 1)
1162         {
1163             result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
1164             result.SetStatus (eReturnStatusFailed);
1165             return false;
1166         }
1167 
1168         uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
1169 
1170         Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
1171         if (new_thread == NULL)
1172         {
1173             result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
1174             result.SetStatus (eReturnStatusFailed);
1175             return false;
1176         }
1177 
1178         process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
1179         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1180 
1181         const uint32_t start_frame = 0;
1182         const uint32_t num_frames = 1;
1183         const uint32_t num_frames_with_source = 1;
1184         new_thread->GetStatus (result.GetOutputStream(),
1185                                start_frame,
1186                                num_frames,
1187                                num_frames_with_source);
1188 
1189         return result.Succeeded();
1190     }
1191 
1192 };
1193 
1194 
1195 //-------------------------------------------------------------------------
1196 // CommandObjectThreadList
1197 //-------------------------------------------------------------------------
1198 
1199 class CommandObjectThreadList : public CommandObjectParsed
1200 {
1201 public:
1202 
1203 
1204     CommandObjectThreadList (CommandInterpreter &interpreter):
1205         CommandObjectParsed (interpreter,
1206                              "thread list",
1207                              "Show a summary of all current threads in a process.",
1208                              "thread list",
1209                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
1210     {
1211     }
1212 
1213     ~CommandObjectThreadList()
1214     {
1215     }
1216 
1217 protected:
1218     bool
1219     DoExecute (Args& command, CommandReturnObject &result)
1220     {
1221         Stream &strm = result.GetOutputStream();
1222         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1223         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1224         Process *process = exe_ctx.GetProcessPtr();
1225         if (process)
1226         {
1227             const bool only_threads_with_stop_reason = false;
1228             const uint32_t start_frame = 0;
1229             const uint32_t num_frames = 0;
1230             const uint32_t num_frames_with_source = 0;
1231             process->GetStatus(strm);
1232             process->GetThreadStatus (strm,
1233                                       only_threads_with_stop_reason,
1234                                       start_frame,
1235                                       num_frames,
1236                                       num_frames_with_source);
1237         }
1238         else
1239         {
1240             result.AppendError ("no current location or status available");
1241             result.SetStatus (eReturnStatusFailed);
1242         }
1243         return result.Succeeded();
1244     }
1245 };
1246 
1247 //-------------------------------------------------------------------------
1248 // CommandObjectMultiwordThread
1249 //-------------------------------------------------------------------------
1250 
1251 CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) :
1252     CommandObjectMultiword (interpreter,
1253                             "thread",
1254                             "A set of commands for operating on one or more threads within a running process.",
1255                             "thread <subcommand> [<subcommand-options>]")
1256 {
1257     LoadSubCommand ("backtrace",  CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
1258     LoadSubCommand ("continue",   CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
1259     LoadSubCommand ("list",       CommandObjectSP (new CommandObjectThreadList (interpreter)));
1260     LoadSubCommand ("select",     CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
1261     LoadSubCommand ("until",      CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
1262     LoadSubCommand ("step-in",    CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1263                                                     interpreter,
1264                                                     "thread step-in",
1265                                                     "Source level single step in specified thread (current thread, if none specified).",
1266                                                     NULL,
1267                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1268                                                     eStepTypeInto,
1269                                                     eStepScopeSource)));
1270 
1271     LoadSubCommand ("step-out",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1272                                                     interpreter,
1273                                                     "thread step-out",
1274                                                     "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
1275                                                     NULL,
1276                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1277                                                     eStepTypeOut,
1278                                                     eStepScopeSource)));
1279 
1280     LoadSubCommand ("step-over",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1281                                                     interpreter,
1282                                                     "thread step-over",
1283                                                     "Source level single step in specified thread (current thread, if none specified), stepping over calls.",
1284                                                     NULL,
1285                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1286                                                     eStepTypeOver,
1287                                                     eStepScopeSource)));
1288 
1289     LoadSubCommand ("step-inst",   CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1290                                                     interpreter,
1291                                                     "thread step-inst",
1292                                                     "Single step one instruction in specified thread (current thread, if none specified).",
1293                                                     NULL,
1294                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1295                                                     eStepTypeTrace,
1296                                                     eStepScopeInstruction)));
1297 
1298     LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
1299                                                     interpreter,
1300                                                     "thread step-inst-over",
1301                                                     "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
1302                                                     NULL,
1303                                                     eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
1304                                                     eStepTypeTraceOver,
1305                                                     eStepScopeInstruction)));
1306 }
1307 
1308 CommandObjectMultiwordThread::~CommandObjectMultiwordThread ()
1309 {
1310 }
1311 
1312 
1313