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