Home | History | Annotate | Download | only in Commands
      1 //===-- CommandObjectProcess.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 "CommandObjectProcess.h"
     13 
     14 // C Includes
     15 // C++ Includes
     16 // Other libraries and framework includes
     17 // Project includes
     18 #include "lldb/Breakpoint/Breakpoint.h"
     19 #include "lldb/Breakpoint/BreakpointLocation.h"
     20 #include "lldb/Breakpoint/BreakpointSite.h"
     21 #include "lldb/Core/State.h"
     22 #include "lldb/Core/Module.h"
     23 #include "lldb/Host/Host.h"
     24 #include "lldb/Interpreter/Args.h"
     25 #include "lldb/Interpreter/Options.h"
     26 #include "lldb/Interpreter/CommandInterpreter.h"
     27 #include "lldb/Interpreter/CommandReturnObject.h"
     28 #include "lldb/Target/Platform.h"
     29 #include "lldb/Target/Process.h"
     30 #include "lldb/Target/StopInfo.h"
     31 #include "lldb/Target/Target.h"
     32 #include "lldb/Target/Thread.h"
     33 
     34 using namespace lldb;
     35 using namespace lldb_private;
     36 
     37 class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
     38 {
     39 public:
     40     CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
     41                                        const char *name,
     42                                        const char *help,
     43                                        const char *syntax,
     44                                        uint32_t flags,
     45                                        const char *new_process_action) :
     46         CommandObjectParsed (interpreter, name, help, syntax, flags),
     47         m_new_process_action (new_process_action) {}
     48 
     49     virtual ~CommandObjectProcessLaunchOrAttach () {}
     50 protected:
     51     bool
     52     StopProcessIfNecessary (Process *&process, StateType &state, CommandReturnObject &result)
     53     {
     54         state = eStateInvalid;
     55         if (process)
     56         {
     57             state = process->GetState();
     58 
     59             if (process->IsAlive() && state != eStateConnected)
     60             {
     61                 char message[1024];
     62                 if (process->GetState() == eStateAttaching)
     63                     ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
     64                 else if (process->GetShouldDetach())
     65                     ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
     66                 else
     67                     ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
     68 
     69                 if (!m_interpreter.Confirm (message, true))
     70                 {
     71                     result.SetStatus (eReturnStatusFailed);
     72                     return false;
     73                 }
     74                 else
     75                 {
     76                     if (process->GetShouldDetach())
     77                     {
     78                         bool keep_stopped = false;
     79                         Error detach_error (process->Detach(keep_stopped));
     80                         if (detach_error.Success())
     81                         {
     82                             result.SetStatus (eReturnStatusSuccessFinishResult);
     83                             process = NULL;
     84                         }
     85                         else
     86                         {
     87                             result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
     88                             result.SetStatus (eReturnStatusFailed);
     89                         }
     90                     }
     91                     else
     92                     {
     93                         Error destroy_error (process->Destroy());
     94                         if (destroy_error.Success())
     95                         {
     96                             result.SetStatus (eReturnStatusSuccessFinishResult);
     97                             process = NULL;
     98                         }
     99                         else
    100                         {
    101                             result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
    102                             result.SetStatus (eReturnStatusFailed);
    103                         }
    104                     }
    105                 }
    106             }
    107         }
    108         return result.Succeeded();
    109     }
    110     std::string m_new_process_action;
    111 };
    112 //-------------------------------------------------------------------------
    113 // CommandObjectProcessLaunch
    114 //-------------------------------------------------------------------------
    115 #pragma mark CommandObjectProcessLaunch
    116 class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
    117 {
    118 public:
    119 
    120     CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
    121         CommandObjectProcessLaunchOrAttach (interpreter,
    122                                             "process launch",
    123                                             "Launch the executable in the debugger.",
    124                                             NULL,
    125                                             eFlagRequiresTarget,
    126                                             "restart"),
    127         m_options (interpreter)
    128     {
    129         CommandArgumentEntry arg;
    130         CommandArgumentData run_args_arg;
    131 
    132         // Define the first (and only) variant of this arg.
    133         run_args_arg.arg_type = eArgTypeRunArgs;
    134         run_args_arg.arg_repetition = eArgRepeatOptional;
    135 
    136         // There is only one variant this argument could be; put it into the argument entry.
    137         arg.push_back (run_args_arg);
    138 
    139         // Push the data for the first argument into the m_arguments vector.
    140         m_arguments.push_back (arg);
    141     }
    142 
    143 
    144     ~CommandObjectProcessLaunch ()
    145     {
    146     }
    147 
    148     virtual int
    149     HandleArgumentCompletion (Args &input,
    150                               int &cursor_index,
    151                               int &cursor_char_position,
    152                               OptionElementVector &opt_element_vector,
    153                               int match_start_point,
    154                               int max_return_elements,
    155                               bool &word_complete,
    156                               StringList &matches)
    157     {
    158         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
    159         completion_str.erase (cursor_char_position);
    160 
    161         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    162                                                              CommandCompletions::eDiskFileCompletion,
    163                                                              completion_str.c_str(),
    164                                                              match_start_point,
    165                                                              max_return_elements,
    166                                                              NULL,
    167                                                              word_complete,
    168                                                              matches);
    169         return matches.GetSize();
    170     }
    171 
    172     Options *
    173     GetOptions ()
    174     {
    175         return &m_options;
    176     }
    177 
    178     virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
    179     {
    180         // No repeat for "process launch"...
    181         return "";
    182     }
    183 
    184 protected:
    185     bool
    186     DoExecute (Args& launch_args, CommandReturnObject &result)
    187     {
    188         Debugger &debugger = m_interpreter.GetDebugger();
    189         Target *target = debugger.GetSelectedTarget().get();
    190         Error error;
    191         // If our listener is NULL, users aren't allows to launch
    192         char filename[PATH_MAX];
    193         const Module *exe_module = target->GetExecutableModulePointer();
    194 
    195         if (exe_module == NULL)
    196         {
    197             result.AppendError ("no file in target, create a debug target using the 'target create' command");
    198             result.SetStatus (eReturnStatusFailed);
    199             return false;
    200         }
    201 
    202         StateType state = eStateInvalid;
    203         Process *process = m_exe_ctx.GetProcessPtr();
    204 
    205         if (!StopProcessIfNecessary(process, state, result))
    206             return false;
    207 
    208         const char *target_settings_argv0 = target->GetArg0();
    209 
    210         exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
    211 
    212         if (target_settings_argv0)
    213         {
    214             m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
    215             m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false);
    216         }
    217         else
    218         {
    219             m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
    220         }
    221 
    222         if (launch_args.GetArgumentCount() == 0)
    223         {
    224             Args target_setting_args;
    225             if (target->GetRunArguments(target_setting_args))
    226                 m_options.launch_info.GetArguments().AppendArguments (target_setting_args);
    227         }
    228         else
    229         {
    230             m_options.launch_info.GetArguments().AppendArguments (launch_args);
    231 
    232             // Save the arguments for subsequent runs in the current target.
    233             target->SetRunArguments (launch_args);
    234         }
    235 
    236         if (target->GetDisableASLR())
    237             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
    238 
    239         if (target->GetDisableSTDIO())
    240             m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
    241 
    242         m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
    243 
    244         Args environment;
    245         target->GetEnvironmentAsArgs (environment);
    246         if (environment.GetArgumentCount() > 0)
    247             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
    248 
    249         // Get the value of synchronous execution here.  If you wait till after you have started to
    250         // run, then you could have hit a breakpoint, whose command might switch the value, and
    251         // then you'll pick up that incorrect value.
    252         bool synchronous_execution = m_interpreter.GetSynchronous ();
    253 
    254         // Finalize the file actions, and if none were given, default to opening
    255         // up a pseudo terminal
    256         const bool default_to_use_pty = true;
    257         m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
    258 
    259         if (state == eStateConnected)
    260         {
    261             if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
    262             {
    263                 result.AppendWarning("can't launch in tty when launching through a remote connection");
    264                 m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
    265             }
    266         }
    267 
    268         if (!m_options.launch_info.GetArchitecture().IsValid())
    269             m_options.launch_info.GetArchitecture() = target->GetArchitecture();
    270 
    271         PlatformSP platform_sp (target->GetPlatform());
    272 
    273         if (platform_sp && platform_sp->CanDebugProcess ())
    274         {
    275             process = target->GetPlatform()->DebugProcess (m_options.launch_info,
    276                                                            debugger,
    277                                                            target,
    278                                                            debugger.GetListener(),
    279                                                            error).get();
    280         }
    281         else
    282         {
    283             const char *plugin_name = m_options.launch_info.GetProcessPluginName();
    284             process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
    285             if (process)
    286                 error = process->Launch (m_options.launch_info);
    287         }
    288 
    289         if (process == NULL)
    290         {
    291             result.SetError (error, "failed to launch or debug process");
    292             return false;
    293         }
    294 
    295 
    296         if (error.Success())
    297         {
    298             const char *archname = exe_module->GetArchitecture().GetArchitectureName();
    299 
    300             result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
    301             result.SetDidChangeProcessState (true);
    302             if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
    303             {
    304                 result.SetStatus (eReturnStatusSuccessContinuingNoResult);
    305                 StateType state = process->WaitForProcessToStop (NULL);
    306 
    307                 if (state == eStateStopped)
    308                 {
    309                     error = process->Resume();
    310                     if (error.Success())
    311                     {
    312                         if (synchronous_execution)
    313                         {
    314                             state = process->WaitForProcessToStop (NULL);
    315                             const bool must_be_alive = true;
    316                             if (!StateIsStoppedState(state, must_be_alive))
    317                             {
    318                                 result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
    319                             }
    320                             result.SetDidChangeProcessState (true);
    321                             result.SetStatus (eReturnStatusSuccessFinishResult);
    322                         }
    323                         else
    324                         {
    325                             result.SetStatus (eReturnStatusSuccessContinuingNoResult);
    326                         }
    327                     }
    328                     else
    329                     {
    330                         result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
    331                         result.SetStatus (eReturnStatusFailed);
    332                     }
    333                 }
    334                 else
    335                 {
    336                     result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
    337                     result.SetStatus (eReturnStatusFailed);
    338                 }
    339             }
    340         }
    341         else
    342         {
    343             result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
    344             result.SetStatus (eReturnStatusFailed);
    345         }
    346 
    347         return result.Succeeded();
    348     }
    349 
    350 protected:
    351     ProcessLaunchCommandOptions m_options;
    352 };
    353 
    354 
    355 //#define SET1 LLDB_OPT_SET_1
    356 //#define SET2 LLDB_OPT_SET_2
    357 //#define SET3 LLDB_OPT_SET_3
    358 //
    359 //OptionDefinition
    360 //CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
    361 //{
    362 //{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,    "Stop at the entry point of the program when launching a process."},
    363 //{ SET1              , false, "stdin",         'i', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdin for the process to <path>."},
    364 //{ SET1              , false, "stdout",        'o', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stdout for the process to <path>."},
    365 //{ SET1              , false, "stderr",        'e', required_argument, NULL, 0, eArgTypeDirectoryName,    "Redirect stderr for the process to <path>."},
    366 //{ SET1 | SET2 | SET3, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,  "Name of the process plugin you want to use."},
    367 //{        SET2       , false, "tty",           't', optional_argument, NULL, 0, eArgTypeDirectoryName,    "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
    368 //{               SET3, false, "no-stdio",      'n', no_argument,       NULL, 0, eArgTypeNone,    "Do not set up for terminal I/O to go to running process."},
    369 //{ SET1 | SET2 | SET3, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypeDirectoryName,    "Set the current working directory to <path> when running the inferior."},
    370 //{ 0,                  false, NULL,             0,  0,                 NULL, 0, eArgTypeNone,    NULL }
    371 //};
    372 //
    373 //#undef SET1
    374 //#undef SET2
    375 //#undef SET3
    376 
    377 //-------------------------------------------------------------------------
    378 // CommandObjectProcessAttach
    379 //-------------------------------------------------------------------------
    380 #pragma mark CommandObjectProcessAttach
    381 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
    382 {
    383 public:
    384 
    385     class CommandOptions : public Options
    386     {
    387     public:
    388 
    389         CommandOptions (CommandInterpreter &interpreter) :
    390             Options(interpreter)
    391         {
    392             // Keep default values of all options in one place: OptionParsingStarting ()
    393             OptionParsingStarting ();
    394         }
    395 
    396         ~CommandOptions ()
    397         {
    398         }
    399 
    400         Error
    401         SetOptionValue (uint32_t option_idx, const char *option_arg)
    402         {
    403             Error error;
    404             const int short_option = m_getopt_table[option_idx].val;
    405             bool success = false;
    406             switch (short_option)
    407             {
    408                 case 'c':
    409                     attach_info.SetContinueOnceAttached(true);
    410                     break;
    411 
    412                 case 'p':
    413                     {
    414                         lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
    415                         if (!success || pid == LLDB_INVALID_PROCESS_ID)
    416                         {
    417                             error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
    418                         }
    419                         else
    420                         {
    421                             attach_info.SetProcessID (pid);
    422                         }
    423                     }
    424                     break;
    425 
    426                 case 'P':
    427                     attach_info.SetProcessPluginName (option_arg);
    428                     break;
    429 
    430                 case 'n':
    431                     attach_info.GetExecutableFile().SetFile(option_arg, false);
    432                     break;
    433 
    434                 case 'w':
    435                     attach_info.SetWaitForLaunch(true);
    436                     break;
    437 
    438                 case 'i':
    439                     attach_info.SetIgnoreExisting(false);
    440                     break;
    441 
    442                 default:
    443                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
    444                     break;
    445             }
    446             return error;
    447         }
    448 
    449         void
    450         OptionParsingStarting ()
    451         {
    452             attach_info.Clear();
    453         }
    454 
    455         const OptionDefinition*
    456         GetDefinitions ()
    457         {
    458             return g_option_table;
    459         }
    460 
    461         virtual bool
    462         HandleOptionArgumentCompletion (Args &input,
    463                                         int cursor_index,
    464                                         int char_pos,
    465                                         OptionElementVector &opt_element_vector,
    466                                         int opt_element_index,
    467                                         int match_start_point,
    468                                         int max_return_elements,
    469                                         bool &word_complete,
    470                                         StringList &matches)
    471         {
    472             int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
    473             int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
    474 
    475             // We are only completing the name option for now...
    476 
    477             const OptionDefinition *opt_defs = GetDefinitions();
    478             if (opt_defs[opt_defs_index].short_option == 'n')
    479             {
    480                 // Are we in the name?
    481 
    482                 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
    483                 // use the default plugin.
    484 
    485                 const char *partial_name = NULL;
    486                 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
    487 
    488                 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
    489                 if (platform_sp)
    490                 {
    491                     ProcessInstanceInfoList process_infos;
    492                     ProcessInstanceInfoMatch match_info;
    493                     if (partial_name)
    494                     {
    495                         match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
    496                         match_info.SetNameMatchType(eNameMatchStartsWith);
    497                     }
    498                     platform_sp->FindProcesses (match_info, process_infos);
    499                     const size_t num_matches = process_infos.GetSize();
    500                     if (num_matches > 0)
    501                     {
    502                         for (size_t i=0; i<num_matches; ++i)
    503                         {
    504                             matches.AppendString (process_infos.GetProcessNameAtIndex(i),
    505                                                   process_infos.GetProcessNameLengthAtIndex(i));
    506                         }
    507                     }
    508                 }
    509             }
    510 
    511             return false;
    512         }
    513 
    514         // Options table: Required for subclasses of Options.
    515 
    516         static OptionDefinition g_option_table[];
    517 
    518         // Instance variables to hold the values for command options.
    519 
    520         ProcessAttachInfo attach_info;
    521     };
    522 
    523     CommandObjectProcessAttach (CommandInterpreter &interpreter) :
    524         CommandObjectProcessLaunchOrAttach (interpreter,
    525                                             "process attach",
    526                                             "Attach to a process.",
    527                                             "process attach <cmd-options>",
    528                                             0,
    529                                             "attach"),
    530         m_options (interpreter)
    531     {
    532     }
    533 
    534     ~CommandObjectProcessAttach ()
    535     {
    536     }
    537 
    538     Options *
    539     GetOptions ()
    540     {
    541         return &m_options;
    542     }
    543 
    544 protected:
    545     bool
    546     DoExecute (Args& command,
    547              CommandReturnObject &result)
    548     {
    549         Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    550         // N.B. The attach should be synchronous.  It doesn't help much to get the prompt back between initiating the attach
    551         // and the target actually stopping.  So even if the interpreter is set to be asynchronous, we wait for the stop
    552         // ourselves here.
    553 
    554         StateType state = eStateInvalid;
    555         Process *process = m_exe_ctx.GetProcessPtr();
    556 
    557         if (!StopProcessIfNecessary (process, state, result))
    558             return false;
    559 
    560         if (target == NULL)
    561         {
    562             // If there isn't a current target create one.
    563             TargetSP new_target_sp;
    564             Error error;
    565 
    566             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
    567                                                                               NULL,
    568                                                                               NULL,
    569                                                                               false,
    570                                                                               NULL, // No platform options
    571                                                                               new_target_sp);
    572             target = new_target_sp.get();
    573             if (target == NULL || error.Fail())
    574             {
    575                 result.AppendError(error.AsCString("Error creating target"));
    576                 return false;
    577             }
    578             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
    579         }
    580 
    581         // Record the old executable module, we want to issue a warning if the process of attaching changed the
    582         // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
    583 
    584         ModuleSP old_exec_module_sp = target->GetExecutableModule();
    585         ArchSpec old_arch_spec = target->GetArchitecture();
    586 
    587         if (command.GetArgumentCount())
    588         {
    589             result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
    590             result.SetStatus (eReturnStatusFailed);
    591         }
    592         else
    593         {
    594             if (state != eStateConnected)
    595             {
    596                 const char *plugin_name = m_options.attach_info.GetProcessPluginName();
    597                 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
    598             }
    599 
    600             if (process)
    601             {
    602                 Error error;
    603                 // If no process info was specified, then use the target executable
    604                 // name as the process to attach to by default
    605                 if (!m_options.attach_info.ProcessInfoSpecified ())
    606                 {
    607                     if (old_exec_module_sp)
    608                         m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
    609 
    610                     if (!m_options.attach_info.ProcessInfoSpecified ())
    611                     {
    612                         error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
    613                     }
    614                 }
    615 
    616                 if (error.Success())
    617                 {
    618                     error = process->Attach (m_options.attach_info);
    619 
    620                     if (error.Success())
    621                     {
    622                         result.SetStatus (eReturnStatusSuccessContinuingNoResult);
    623                     }
    624                     else
    625                     {
    626                         result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
    627                         result.SetStatus (eReturnStatusFailed);
    628                         return false;
    629                     }
    630                     // If we're synchronous, wait for the stopped event and report that.
    631                     // Otherwise just return.
    632                     // FIXME: in the async case it will now be possible to get to the command
    633                     // interpreter with a state eStateAttaching.  Make sure we handle that correctly.
    634                     StateType state = process->WaitForProcessToStop (NULL);
    635 
    636                     result.SetDidChangeProcessState (true);
    637 
    638                     if (state == eStateStopped)
    639                     {
    640                         result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
    641                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
    642                     }
    643                     else
    644                     {
    645                         result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
    646                         process->Destroy();
    647                         result.SetStatus (eReturnStatusFailed);
    648                         return false;
    649                     }
    650                 }
    651             }
    652         }
    653 
    654         if (result.Succeeded())
    655         {
    656             // Okay, we're done.  Last step is to warn if the executable module has changed:
    657             char new_path[PATH_MAX];
    658             ModuleSP new_exec_module_sp (target->GetExecutableModule());
    659             if (!old_exec_module_sp)
    660             {
    661                 // We might not have a module if we attached to a raw pid...
    662                 if (new_exec_module_sp)
    663                 {
    664                     new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
    665                     result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
    666                 }
    667             }
    668             else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
    669             {
    670                 char old_path[PATH_MAX];
    671 
    672                 old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
    673                 new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
    674 
    675                 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
    676                                                     old_path, new_path);
    677             }
    678 
    679             if (!old_arch_spec.IsValid())
    680             {
    681                 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
    682             }
    683             else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
    684             {
    685                 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
    686                                                old_arch_spec.GetTriple().getTriple().c_str(),
    687                                                target->GetArchitecture().GetTriple().getTriple().c_str());
    688             }
    689 
    690             // This supports the use-case scenario of immediately continuing the process once attached.
    691             if (m_options.attach_info.GetContinueOnceAttached())
    692                 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
    693         }
    694         return result.Succeeded();
    695     }
    696 
    697     CommandOptions m_options;
    698 };
    699 
    700 
    701 OptionDefinition
    702 CommandObjectProcessAttach::CommandOptions::g_option_table[] =
    703 {
    704 { LLDB_OPT_SET_ALL, false, "continue",'c', no_argument,         NULL, 0, eArgTypeNone,         "Immediately continue the process once attached."},
    705 { LLDB_OPT_SET_ALL, false, "plugin",  'P', required_argument,   NULL, 0, eArgTypePlugin,       "Name of the process plugin you want to use."},
    706 { LLDB_OPT_SET_1,   false, "pid",     'p', required_argument,   NULL, 0, eArgTypePid,          "The process ID of an existing process to attach to."},
    707 { LLDB_OPT_SET_2,   false, "name",    'n', required_argument,   NULL, 0, eArgTypeProcessName,  "The name of the process to attach to."},
    708 { LLDB_OPT_SET_2,   false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone,         "Include existing processes when doing attach -w."},
    709 { LLDB_OPT_SET_2,   false, "waitfor", 'w', no_argument,         NULL, 0, eArgTypeNone,         "Wait for the process with <process-name> to launch."},
    710 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
    711 };
    712 
    713 //-------------------------------------------------------------------------
    714 // CommandObjectProcessContinue
    715 //-------------------------------------------------------------------------
    716 #pragma mark CommandObjectProcessContinue
    717 
    718 class CommandObjectProcessContinue : public CommandObjectParsed
    719 {
    720 public:
    721 
    722     CommandObjectProcessContinue (CommandInterpreter &interpreter) :
    723         CommandObjectParsed (interpreter,
    724                              "process continue",
    725                              "Continue execution of all threads in the current process.",
    726                              "process continue",
    727                              eFlagRequiresProcess       |
    728                              eFlagTryTargetAPILock      |
    729                              eFlagProcessMustBeLaunched |
    730                              eFlagProcessMustBePaused   ),
    731         m_options(interpreter)
    732     {
    733     }
    734 
    735 
    736     ~CommandObjectProcessContinue ()
    737     {
    738     }
    739 
    740 protected:
    741 
    742     class CommandOptions : public Options
    743     {
    744     public:
    745 
    746         CommandOptions (CommandInterpreter &interpreter) :
    747             Options(interpreter)
    748         {
    749             // Keep default values of all options in one place: OptionParsingStarting ()
    750             OptionParsingStarting ();
    751         }
    752 
    753         ~CommandOptions ()
    754         {
    755         }
    756 
    757         Error
    758         SetOptionValue (uint32_t option_idx, const char *option_arg)
    759         {
    760             Error error;
    761             const int short_option = m_getopt_table[option_idx].val;
    762             bool success = false;
    763             switch (short_option)
    764             {
    765                 case 'i':
    766                     m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
    767                     if (!success)
    768                         error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
    769                     break;
    770 
    771                 default:
    772                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
    773                     break;
    774             }
    775             return error;
    776         }
    777 
    778         void
    779         OptionParsingStarting ()
    780         {
    781             m_ignore = 0;
    782         }
    783 
    784         const OptionDefinition*
    785         GetDefinitions ()
    786         {
    787             return g_option_table;
    788         }
    789 
    790         // Options table: Required for subclasses of Options.
    791 
    792         static OptionDefinition g_option_table[];
    793 
    794         uint32_t m_ignore;
    795     };
    796 
    797     bool
    798     DoExecute (Args& command, CommandReturnObject &result)
    799     {
    800         Process *process = m_exe_ctx.GetProcessPtr();
    801         bool synchronous_execution = m_interpreter.GetSynchronous ();
    802         StateType state = process->GetState();
    803         if (state == eStateStopped)
    804         {
    805             if (command.GetArgumentCount() != 0)
    806             {
    807                 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
    808                 result.SetStatus (eReturnStatusFailed);
    809                 return false;
    810             }
    811 
    812             if (m_options.m_ignore > 0)
    813             {
    814                 ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread());
    815                 if (sel_thread_sp)
    816                 {
    817                     StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
    818                     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
    819                     {
    820                         lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
    821                         BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
    822                         if (bp_site_sp)
    823                         {
    824                             const size_t num_owners = bp_site_sp->GetNumberOfOwners();
    825                             for (size_t i = 0; i < num_owners; i++)
    826                             {
    827                                 Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
    828                                 if (!bp_ref.IsInternal())
    829                                 {
    830                                     bp_ref.SetIgnoreCount(m_options.m_ignore);
    831                                 }
    832                             }
    833                         }
    834                     }
    835                 }
    836             }
    837 
    838             {  // Scope for thread list mutex:
    839                 Mutex::Locker locker (process->GetThreadList().GetMutex());
    840                 const uint32_t num_threads = process->GetThreadList().GetSize();
    841 
    842                 // Set the actions that the threads should each take when resuming
    843                 for (uint32_t idx=0; idx<num_threads; ++idx)
    844                 {
    845                     process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning);
    846                 }
    847             }
    848 
    849             Error error(process->Resume());
    850             if (error.Success())
    851             {
    852                 result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
    853                 if (synchronous_execution)
    854                 {
    855                     state = process->WaitForProcessToStop (NULL);
    856 
    857                     result.SetDidChangeProcessState (true);
    858                     result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
    859                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
    860                 }
    861                 else
    862                 {
    863                     result.SetStatus (eReturnStatusSuccessContinuingNoResult);
    864                 }
    865             }
    866             else
    867             {
    868                 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
    869                 result.SetStatus (eReturnStatusFailed);
    870             }
    871         }
    872         else
    873         {
    874             result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
    875                                          StateAsCString(state));
    876             result.SetStatus (eReturnStatusFailed);
    877         }
    878         return result.Succeeded();
    879     }
    880 
    881     Options *
    882     GetOptions ()
    883     {
    884         return &m_options;
    885     }
    886 
    887     CommandOptions m_options;
    888 
    889 };
    890 
    891 OptionDefinition
    892 CommandObjectProcessContinue::CommandOptions::g_option_table[] =
    893 {
    894 { LLDB_OPT_SET_ALL, false, "ignore-count",'i', required_argument,         NULL, 0, eArgTypeUnsignedInteger,
    895                            "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
    896 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
    897 };
    898 
    899 //-------------------------------------------------------------------------
    900 // CommandObjectProcessDetach
    901 //-------------------------------------------------------------------------
    902 #pragma mark CommandObjectProcessDetach
    903 
    904 class CommandObjectProcessDetach : public CommandObjectParsed
    905 {
    906 public:
    907     class CommandOptions : public Options
    908     {
    909     public:
    910 
    911         CommandOptions (CommandInterpreter &interpreter) :
    912             Options (interpreter)
    913         {
    914             OptionParsingStarting ();
    915         }
    916 
    917         ~CommandOptions ()
    918         {
    919         }
    920 
    921         Error
    922         SetOptionValue (uint32_t option_idx, const char *option_arg)
    923         {
    924             Error error;
    925             const int short_option = m_getopt_table[option_idx].val;
    926 
    927             switch (short_option)
    928             {
    929                 case 's':
    930                     bool tmp_result;
    931                     bool success;
    932                     tmp_result = Args::StringToBoolean(option_arg, false, &success);
    933                     if (!success)
    934                         error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
    935                     else
    936                     {
    937                         if (tmp_result)
    938                             m_keep_stopped = eLazyBoolYes;
    939                         else
    940                             m_keep_stopped = eLazyBoolNo;
    941                     }
    942                     break;
    943                 default:
    944                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
    945                     break;
    946             }
    947             return error;
    948         }
    949 
    950         void
    951         OptionParsingStarting ()
    952         {
    953             m_keep_stopped = eLazyBoolCalculate;
    954         }
    955 
    956         const OptionDefinition*
    957         GetDefinitions ()
    958         {
    959             return g_option_table;
    960         }
    961 
    962         // Options table: Required for subclasses of Options.
    963 
    964         static OptionDefinition g_option_table[];
    965 
    966         // Instance variables to hold the values for command options.
    967         LazyBool m_keep_stopped;
    968     };
    969 
    970     CommandObjectProcessDetach (CommandInterpreter &interpreter) :
    971         CommandObjectParsed (interpreter,
    972                              "process detach",
    973                              "Detach from the current process being debugged.",
    974                              "process detach",
    975                              eFlagRequiresProcess      |
    976                              eFlagTryTargetAPILock     |
    977                              eFlagProcessMustBeLaunched),
    978         m_options(interpreter)
    979     {
    980     }
    981 
    982     ~CommandObjectProcessDetach ()
    983     {
    984     }
    985 
    986     Options *
    987     GetOptions ()
    988     {
    989         return &m_options;
    990     }
    991 
    992 
    993 protected:
    994     bool
    995     DoExecute (Args& command, CommandReturnObject &result)
    996     {
    997         Process *process = m_exe_ctx.GetProcessPtr();
    998         result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
    999         // FIXME: This will be a Command Option:
   1000         bool keep_stopped;
   1001         if (m_options.m_keep_stopped == eLazyBoolCalculate)
   1002         {
   1003             // Check the process default:
   1004             if (process->GetDetachKeepsStopped())
   1005                 keep_stopped = true;
   1006             else
   1007                 keep_stopped = false;
   1008         }
   1009         else if (m_options.m_keep_stopped == eLazyBoolYes)
   1010             keep_stopped = true;
   1011         else
   1012             keep_stopped = false;
   1013 
   1014         Error error (process->Detach(keep_stopped));
   1015         if (error.Success())
   1016         {
   1017             result.SetStatus (eReturnStatusSuccessFinishResult);
   1018         }
   1019         else
   1020         {
   1021             result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
   1022             result.SetStatus (eReturnStatusFailed);
   1023             return false;
   1024         }
   1025         return result.Succeeded();
   1026     }
   1027 
   1028     CommandOptions m_options;
   1029 };
   1030 
   1031 OptionDefinition
   1032 CommandObjectProcessDetach::CommandOptions::g_option_table[] =
   1033 {
   1034 { LLDB_OPT_SET_1, false, "keep-stopped",   's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
   1035 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   1036 };
   1037 
   1038 //-------------------------------------------------------------------------
   1039 // CommandObjectProcessConnect
   1040 //-------------------------------------------------------------------------
   1041 #pragma mark CommandObjectProcessConnect
   1042 
   1043 class CommandObjectProcessConnect : public CommandObjectParsed
   1044 {
   1045 public:
   1046 
   1047     class CommandOptions : public Options
   1048     {
   1049     public:
   1050 
   1051         CommandOptions (CommandInterpreter &interpreter) :
   1052             Options(interpreter)
   1053         {
   1054             // Keep default values of all options in one place: OptionParsingStarting ()
   1055             OptionParsingStarting ();
   1056         }
   1057 
   1058         ~CommandOptions ()
   1059         {
   1060         }
   1061 
   1062         Error
   1063         SetOptionValue (uint32_t option_idx, const char *option_arg)
   1064         {
   1065             Error error;
   1066             const int short_option = m_getopt_table[option_idx].val;
   1067 
   1068             switch (short_option)
   1069             {
   1070             case 'p':
   1071                 plugin_name.assign (option_arg);
   1072                 break;
   1073 
   1074             default:
   1075                 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
   1076                 break;
   1077             }
   1078             return error;
   1079         }
   1080 
   1081         void
   1082         OptionParsingStarting ()
   1083         {
   1084             plugin_name.clear();
   1085         }
   1086 
   1087         const OptionDefinition*
   1088         GetDefinitions ()
   1089         {
   1090             return g_option_table;
   1091         }
   1092 
   1093         // Options table: Required for subclasses of Options.
   1094 
   1095         static OptionDefinition g_option_table[];
   1096 
   1097         // Instance variables to hold the values for command options.
   1098 
   1099         std::string plugin_name;
   1100     };
   1101 
   1102     CommandObjectProcessConnect (CommandInterpreter &interpreter) :
   1103         CommandObjectParsed (interpreter,
   1104                              "process connect",
   1105                              "Connect to a remote debug service.",
   1106                              "process connect <remote-url>",
   1107                              0),
   1108         m_options (interpreter)
   1109     {
   1110     }
   1111 
   1112     ~CommandObjectProcessConnect ()
   1113     {
   1114     }
   1115 
   1116 
   1117     Options *
   1118     GetOptions ()
   1119     {
   1120         return &m_options;
   1121     }
   1122 
   1123 protected:
   1124     bool
   1125     DoExecute (Args& command,
   1126              CommandReturnObject &result)
   1127     {
   1128 
   1129         TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
   1130         Error error;
   1131         Process *process = m_exe_ctx.GetProcessPtr();
   1132         if (process)
   1133         {
   1134             if (process->IsAlive())
   1135             {
   1136                 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
   1137                                               process->GetID());
   1138                 result.SetStatus (eReturnStatusFailed);
   1139                 return false;
   1140             }
   1141         }
   1142 
   1143         if (!target_sp)
   1144         {
   1145             // If there isn't a current target create one.
   1146 
   1147             error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
   1148                                                                               NULL,
   1149                                                                               NULL,
   1150                                                                               false,
   1151                                                                               NULL, // No platform options
   1152                                                                               target_sp);
   1153             if (!target_sp || error.Fail())
   1154             {
   1155                 result.AppendError(error.AsCString("Error creating target"));
   1156                 result.SetStatus (eReturnStatusFailed);
   1157                 return false;
   1158             }
   1159             m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get());
   1160         }
   1161 
   1162         if (command.GetArgumentCount() == 1)
   1163         {
   1164             const char *plugin_name = NULL;
   1165             if (!m_options.plugin_name.empty())
   1166                 plugin_name = m_options.plugin_name.c_str();
   1167 
   1168             const char *remote_url = command.GetArgumentAtIndex(0);
   1169             process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
   1170 
   1171             if (process)
   1172             {
   1173                 error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
   1174 
   1175                 if (error.Fail())
   1176                 {
   1177                     result.AppendError(error.AsCString("Remote connect failed"));
   1178                     result.SetStatus (eReturnStatusFailed);
   1179                     target_sp->DeleteCurrentProcess();
   1180                     return false;
   1181                 }
   1182             }
   1183             else
   1184             {
   1185                 result.AppendErrorWithFormat ("Unable to find process plug-in for remote URL '%s'.\nPlease specify a process plug-in name with the --plugin option, or specify an object file using the \"file\" command.\n",
   1186                                               remote_url);
   1187                 result.SetStatus (eReturnStatusFailed);
   1188             }
   1189         }
   1190         else
   1191         {
   1192             result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
   1193                                           m_cmd_name.c_str(),
   1194                                           m_cmd_syntax.c_str());
   1195             result.SetStatus (eReturnStatusFailed);
   1196         }
   1197         return result.Succeeded();
   1198     }
   1199 
   1200     CommandOptions m_options;
   1201 };
   1202 
   1203 OptionDefinition
   1204 CommandObjectProcessConnect::CommandOptions::g_option_table[] =
   1205 {
   1206     { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
   1207     { 0,                false, NULL,      0 , 0,                 NULL, 0, eArgTypeNone,   NULL }
   1208 };
   1209 
   1210 //-------------------------------------------------------------------------
   1211 // CommandObjectProcessPlugin
   1212 //-------------------------------------------------------------------------
   1213 #pragma mark CommandObjectProcessPlugin
   1214 
   1215 class CommandObjectProcessPlugin : public CommandObjectProxy
   1216 {
   1217 public:
   1218 
   1219     CommandObjectProcessPlugin (CommandInterpreter &interpreter) :
   1220         CommandObjectProxy (interpreter,
   1221                             "process plugin",
   1222                             "Send a custom command to the current process plug-in.",
   1223                             "process plugin <args>",
   1224                             0)
   1225     {
   1226     }
   1227 
   1228     ~CommandObjectProcessPlugin ()
   1229     {
   1230     }
   1231 
   1232     virtual CommandObject *
   1233     GetProxyCommandObject()
   1234     {
   1235         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
   1236         if (process)
   1237             return process->GetPluginCommandObject();
   1238         return NULL;
   1239     }
   1240 };
   1241 
   1242 
   1243 //-------------------------------------------------------------------------
   1244 // CommandObjectProcessLoad
   1245 //-------------------------------------------------------------------------
   1246 #pragma mark CommandObjectProcessLoad
   1247 
   1248 class CommandObjectProcessLoad : public CommandObjectParsed
   1249 {
   1250 public:
   1251 
   1252     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
   1253         CommandObjectParsed (interpreter,
   1254                              "process load",
   1255                              "Load a shared library into the current process.",
   1256                              "process load <filename> [<filename> ...]",
   1257                              eFlagRequiresProcess       |
   1258                              eFlagTryTargetAPILock      |
   1259                              eFlagProcessMustBeLaunched |
   1260                              eFlagProcessMustBePaused   )
   1261     {
   1262     }
   1263 
   1264     ~CommandObjectProcessLoad ()
   1265     {
   1266     }
   1267 
   1268 protected:
   1269     bool
   1270     DoExecute (Args& command,
   1271              CommandReturnObject &result)
   1272     {
   1273         Process *process = m_exe_ctx.GetProcessPtr();
   1274 
   1275         const size_t argc = command.GetArgumentCount();
   1276 
   1277         for (uint32_t i=0; i<argc; ++i)
   1278         {
   1279             Error error;
   1280             const char *image_path = command.GetArgumentAtIndex(i);
   1281             FileSpec image_spec (image_path, false);
   1282             process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
   1283             uint32_t image_token = process->LoadImage(image_spec, error);
   1284             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
   1285             {
   1286                 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
   1287                 result.SetStatus (eReturnStatusSuccessFinishResult);
   1288             }
   1289             else
   1290             {
   1291                 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
   1292                 result.SetStatus (eReturnStatusFailed);
   1293             }
   1294         }
   1295         return result.Succeeded();
   1296     }
   1297 };
   1298 
   1299 
   1300 //-------------------------------------------------------------------------
   1301 // CommandObjectProcessUnload
   1302 //-------------------------------------------------------------------------
   1303 #pragma mark CommandObjectProcessUnload
   1304 
   1305 class CommandObjectProcessUnload : public CommandObjectParsed
   1306 {
   1307 public:
   1308 
   1309     CommandObjectProcessUnload (CommandInterpreter &interpreter) :
   1310         CommandObjectParsed (interpreter,
   1311                              "process unload",
   1312                              "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
   1313                              "process unload <index>",
   1314                              eFlagRequiresProcess       |
   1315                              eFlagTryTargetAPILock      |
   1316                              eFlagProcessMustBeLaunched |
   1317                              eFlagProcessMustBePaused   )
   1318     {
   1319     }
   1320 
   1321     ~CommandObjectProcessUnload ()
   1322     {
   1323     }
   1324 
   1325 protected:
   1326     bool
   1327     DoExecute (Args& command,
   1328              CommandReturnObject &result)
   1329     {
   1330         Process *process = m_exe_ctx.GetProcessPtr();
   1331 
   1332         const size_t argc = command.GetArgumentCount();
   1333 
   1334         for (uint32_t i=0; i<argc; ++i)
   1335         {
   1336             const char *image_token_cstr = command.GetArgumentAtIndex(i);
   1337             uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
   1338             if (image_token == LLDB_INVALID_IMAGE_TOKEN)
   1339             {
   1340                 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
   1341                 result.SetStatus (eReturnStatusFailed);
   1342                 break;
   1343             }
   1344             else
   1345             {
   1346                 Error error (process->UnloadImage(image_token));
   1347                 if (error.Success())
   1348                 {
   1349                     result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
   1350                     result.SetStatus (eReturnStatusSuccessFinishResult);
   1351                 }
   1352                 else
   1353                 {
   1354                     result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
   1355                     result.SetStatus (eReturnStatusFailed);
   1356                     break;
   1357                 }
   1358             }
   1359         }
   1360         return result.Succeeded();
   1361     }
   1362 };
   1363 
   1364 //-------------------------------------------------------------------------
   1365 // CommandObjectProcessSignal
   1366 //-------------------------------------------------------------------------
   1367 #pragma mark CommandObjectProcessSignal
   1368 
   1369 class CommandObjectProcessSignal : public CommandObjectParsed
   1370 {
   1371 public:
   1372 
   1373     CommandObjectProcessSignal (CommandInterpreter &interpreter) :
   1374         CommandObjectParsed (interpreter,
   1375                              "process signal",
   1376                              "Send a UNIX signal to the current process being debugged.",
   1377                              NULL,
   1378                              eFlagRequiresProcess | eFlagTryTargetAPILock)
   1379     {
   1380         CommandArgumentEntry arg;
   1381         CommandArgumentData signal_arg;
   1382 
   1383         // Define the first (and only) variant of this arg.
   1384         signal_arg.arg_type = eArgTypeUnixSignal;
   1385         signal_arg.arg_repetition = eArgRepeatPlain;
   1386 
   1387         // There is only one variant this argument could be; put it into the argument entry.
   1388         arg.push_back (signal_arg);
   1389 
   1390         // Push the data for the first argument into the m_arguments vector.
   1391         m_arguments.push_back (arg);
   1392     }
   1393 
   1394     ~CommandObjectProcessSignal ()
   1395     {
   1396     }
   1397 
   1398 protected:
   1399     bool
   1400     DoExecute (Args& command,
   1401              CommandReturnObject &result)
   1402     {
   1403         Process *process = m_exe_ctx.GetProcessPtr();
   1404 
   1405         if (command.GetArgumentCount() == 1)
   1406         {
   1407             int signo = LLDB_INVALID_SIGNAL_NUMBER;
   1408 
   1409             const char *signal_name = command.GetArgumentAtIndex(0);
   1410             if (::isxdigit (signal_name[0]))
   1411                 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
   1412             else
   1413                 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
   1414 
   1415             if (signo == LLDB_INVALID_SIGNAL_NUMBER)
   1416             {
   1417                 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
   1418                 result.SetStatus (eReturnStatusFailed);
   1419             }
   1420             else
   1421             {
   1422                 Error error (process->Signal (signo));
   1423                 if (error.Success())
   1424                 {
   1425                     result.SetStatus (eReturnStatusSuccessFinishResult);
   1426                 }
   1427                 else
   1428                 {
   1429                     result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
   1430                     result.SetStatus (eReturnStatusFailed);
   1431                 }
   1432             }
   1433         }
   1434         else
   1435         {
   1436             result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
   1437                                         m_cmd_syntax.c_str());
   1438             result.SetStatus (eReturnStatusFailed);
   1439         }
   1440         return result.Succeeded();
   1441     }
   1442 };
   1443 
   1444 
   1445 //-------------------------------------------------------------------------
   1446 // CommandObjectProcessInterrupt
   1447 //-------------------------------------------------------------------------
   1448 #pragma mark CommandObjectProcessInterrupt
   1449 
   1450 class CommandObjectProcessInterrupt : public CommandObjectParsed
   1451 {
   1452 public:
   1453 
   1454 
   1455     CommandObjectProcessInterrupt (CommandInterpreter &interpreter) :
   1456         CommandObjectParsed (interpreter,
   1457                              "process interrupt",
   1458                              "Interrupt the current process being debugged.",
   1459                              "process interrupt",
   1460                              eFlagRequiresProcess      |
   1461                              eFlagTryTargetAPILock     |
   1462                              eFlagProcessMustBeLaunched)
   1463     {
   1464     }
   1465 
   1466     ~CommandObjectProcessInterrupt ()
   1467     {
   1468     }
   1469 
   1470 protected:
   1471     bool
   1472     DoExecute (Args& command,
   1473                CommandReturnObject &result)
   1474     {
   1475         Process *process = m_exe_ctx.GetProcessPtr();
   1476         if (process == NULL)
   1477         {
   1478             result.AppendError ("no process to halt");
   1479             result.SetStatus (eReturnStatusFailed);
   1480             return false;
   1481         }
   1482 
   1483         if (command.GetArgumentCount() == 0)
   1484         {
   1485             bool clear_thread_plans = true;
   1486             Error error(process->Halt (clear_thread_plans));
   1487             if (error.Success())
   1488             {
   1489                 result.SetStatus (eReturnStatusSuccessFinishResult);
   1490             }
   1491             else
   1492             {
   1493                 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
   1494                 result.SetStatus (eReturnStatusFailed);
   1495             }
   1496         }
   1497         else
   1498         {
   1499             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
   1500                                         m_cmd_name.c_str(),
   1501                                         m_cmd_syntax.c_str());
   1502             result.SetStatus (eReturnStatusFailed);
   1503         }
   1504         return result.Succeeded();
   1505     }
   1506 };
   1507 
   1508 //-------------------------------------------------------------------------
   1509 // CommandObjectProcessKill
   1510 //-------------------------------------------------------------------------
   1511 #pragma mark CommandObjectProcessKill
   1512 
   1513 class CommandObjectProcessKill : public CommandObjectParsed
   1514 {
   1515 public:
   1516 
   1517     CommandObjectProcessKill (CommandInterpreter &interpreter) :
   1518         CommandObjectParsed (interpreter,
   1519                              "process kill",
   1520                              "Terminate the current process being debugged.",
   1521                              "process kill",
   1522                              eFlagRequiresProcess      |
   1523                              eFlagTryTargetAPILock     |
   1524                              eFlagProcessMustBeLaunched)
   1525     {
   1526     }
   1527 
   1528     ~CommandObjectProcessKill ()
   1529     {
   1530     }
   1531 
   1532 protected:
   1533     bool
   1534     DoExecute (Args& command,
   1535              CommandReturnObject &result)
   1536     {
   1537         Process *process = m_exe_ctx.GetProcessPtr();
   1538         if (process == NULL)
   1539         {
   1540             result.AppendError ("no process to kill");
   1541             result.SetStatus (eReturnStatusFailed);
   1542             return false;
   1543         }
   1544 
   1545         if (command.GetArgumentCount() == 0)
   1546         {
   1547             Error error (process->Destroy());
   1548             if (error.Success())
   1549             {
   1550                 result.SetStatus (eReturnStatusSuccessFinishResult);
   1551             }
   1552             else
   1553             {
   1554                 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
   1555                 result.SetStatus (eReturnStatusFailed);
   1556             }
   1557         }
   1558         else
   1559         {
   1560             result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
   1561                                         m_cmd_name.c_str(),
   1562                                         m_cmd_syntax.c_str());
   1563             result.SetStatus (eReturnStatusFailed);
   1564         }
   1565         return result.Succeeded();
   1566     }
   1567 };
   1568 
   1569 //-------------------------------------------------------------------------
   1570 // CommandObjectProcessStatus
   1571 //-------------------------------------------------------------------------
   1572 #pragma mark CommandObjectProcessStatus
   1573 
   1574 class CommandObjectProcessStatus : public CommandObjectParsed
   1575 {
   1576 public:
   1577     CommandObjectProcessStatus (CommandInterpreter &interpreter) :
   1578         CommandObjectParsed (interpreter,
   1579                              "process status",
   1580                              "Show the current status and location of executing process.",
   1581                              "process status",
   1582                              eFlagRequiresProcess | eFlagTryTargetAPILock)
   1583     {
   1584     }
   1585 
   1586     ~CommandObjectProcessStatus()
   1587     {
   1588     }
   1589 
   1590 
   1591     bool
   1592     DoExecute (Args& command, CommandReturnObject &result)
   1593     {
   1594         Stream &strm = result.GetOutputStream();
   1595         result.SetStatus (eReturnStatusSuccessFinishNoResult);
   1596         // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
   1597         Process *process = m_exe_ctx.GetProcessPtr();
   1598         const bool only_threads_with_stop_reason = true;
   1599         const uint32_t start_frame = 0;
   1600         const uint32_t num_frames = 1;
   1601         const uint32_t num_frames_with_source = 1;
   1602         process->GetStatus(strm);
   1603         process->GetThreadStatus (strm,
   1604                                   only_threads_with_stop_reason,
   1605                                   start_frame,
   1606                                   num_frames,
   1607                                   num_frames_with_source);
   1608         return result.Succeeded();
   1609     }
   1610 };
   1611 
   1612 //-------------------------------------------------------------------------
   1613 // CommandObjectProcessHandle
   1614 //-------------------------------------------------------------------------
   1615 #pragma mark CommandObjectProcessHandle
   1616 
   1617 class CommandObjectProcessHandle : public CommandObjectParsed
   1618 {
   1619 public:
   1620 
   1621     class CommandOptions : public Options
   1622     {
   1623     public:
   1624 
   1625         CommandOptions (CommandInterpreter &interpreter) :
   1626             Options (interpreter)
   1627         {
   1628             OptionParsingStarting ();
   1629         }
   1630 
   1631         ~CommandOptions ()
   1632         {
   1633         }
   1634 
   1635         Error
   1636         SetOptionValue (uint32_t option_idx, const char *option_arg)
   1637         {
   1638             Error error;
   1639             const int short_option = m_getopt_table[option_idx].val;
   1640 
   1641             switch (short_option)
   1642             {
   1643                 case 's':
   1644                     stop = option_arg;
   1645                     break;
   1646                 case 'n':
   1647                     notify = option_arg;
   1648                     break;
   1649                 case 'p':
   1650                     pass = option_arg;
   1651                     break;
   1652                 default:
   1653                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
   1654                     break;
   1655             }
   1656             return error;
   1657         }
   1658 
   1659         void
   1660         OptionParsingStarting ()
   1661         {
   1662             stop.clear();
   1663             notify.clear();
   1664             pass.clear();
   1665         }
   1666 
   1667         const OptionDefinition*
   1668         GetDefinitions ()
   1669         {
   1670             return g_option_table;
   1671         }
   1672 
   1673         // Options table: Required for subclasses of Options.
   1674 
   1675         static OptionDefinition g_option_table[];
   1676 
   1677         // Instance variables to hold the values for command options.
   1678 
   1679         std::string stop;
   1680         std::string notify;
   1681         std::string pass;
   1682     };
   1683 
   1684 
   1685     CommandObjectProcessHandle (CommandInterpreter &interpreter) :
   1686         CommandObjectParsed (interpreter,
   1687                              "process handle",
   1688                              "Show or update what the process and debugger should do with various signals received from the OS.",
   1689                              NULL),
   1690         m_options (interpreter)
   1691     {
   1692         SetHelpLong ("If no signals are specified, update them all.  If no update option is specified, list the current values.\n");
   1693         CommandArgumentEntry arg;
   1694         CommandArgumentData signal_arg;
   1695 
   1696         signal_arg.arg_type = eArgTypeUnixSignal;
   1697         signal_arg.arg_repetition = eArgRepeatStar;
   1698 
   1699         arg.push_back (signal_arg);
   1700 
   1701         m_arguments.push_back (arg);
   1702     }
   1703 
   1704     ~CommandObjectProcessHandle ()
   1705     {
   1706     }
   1707 
   1708     Options *
   1709     GetOptions ()
   1710     {
   1711         return &m_options;
   1712     }
   1713 
   1714     bool
   1715     VerifyCommandOptionValue (const std::string &option, int &real_value)
   1716     {
   1717         bool okay = true;
   1718 
   1719         bool success = false;
   1720         bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
   1721 
   1722         if (success && tmp_value)
   1723             real_value = 1;
   1724         else if (success && !tmp_value)
   1725             real_value = 0;
   1726         else
   1727         {
   1728             // If the value isn't 'true' or 'false', it had better be 0 or 1.
   1729             real_value = Args::StringToUInt32 (option.c_str(), 3);
   1730             if (real_value != 0 && real_value != 1)
   1731                 okay = false;
   1732         }
   1733 
   1734         return okay;
   1735     }
   1736 
   1737     void
   1738     PrintSignalHeader (Stream &str)
   1739     {
   1740         str.Printf ("NAME        PASS   STOP   NOTIFY\n");
   1741         str.Printf ("==========  =====  =====  ======\n");
   1742     }
   1743 
   1744     void
   1745     PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals)
   1746     {
   1747         bool stop;
   1748         bool suppress;
   1749         bool notify;
   1750 
   1751         str.Printf ("%-10s  ", sig_name);
   1752         if (signals.GetSignalInfo (signo, suppress, stop, notify))
   1753         {
   1754             bool pass = !suppress;
   1755             str.Printf ("%s  %s  %s",
   1756                         (pass ? "true " : "false"),
   1757                         (stop ? "true " : "false"),
   1758                         (notify ? "true " : "false"));
   1759         }
   1760         str.Printf ("\n");
   1761     }
   1762 
   1763     void
   1764     PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals)
   1765     {
   1766         PrintSignalHeader (str);
   1767 
   1768         if (num_valid_signals > 0)
   1769         {
   1770             size_t num_args = signal_args.GetArgumentCount();
   1771             for (size_t i = 0; i < num_args; ++i)
   1772             {
   1773                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
   1774                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
   1775                     PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals);
   1776             }
   1777         }
   1778         else // Print info for ALL signals
   1779         {
   1780             int32_t signo = signals.GetFirstSignalNumber();
   1781             while (signo != LLDB_INVALID_SIGNAL_NUMBER)
   1782             {
   1783                 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals);
   1784                 signo = signals.GetNextSignalNumber (signo);
   1785             }
   1786         }
   1787     }
   1788 
   1789 protected:
   1790     bool
   1791     DoExecute (Args &signal_args, CommandReturnObject &result)
   1792     {
   1793         TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
   1794 
   1795         if (!target_sp)
   1796         {
   1797             result.AppendError ("No current target;"
   1798                                 " cannot handle signals until you have a valid target and process.\n");
   1799             result.SetStatus (eReturnStatusFailed);
   1800             return false;
   1801         }
   1802 
   1803         ProcessSP process_sp = target_sp->GetProcessSP();
   1804 
   1805         if (!process_sp)
   1806         {
   1807             result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
   1808             result.SetStatus (eReturnStatusFailed);
   1809             return false;
   1810         }
   1811 
   1812         int stop_action = -1;   // -1 means leave the current setting alone
   1813         int pass_action = -1;   // -1 means leave the current setting alone
   1814         int notify_action = -1; // -1 means leave the current setting alone
   1815 
   1816         if (! m_options.stop.empty()
   1817             && ! VerifyCommandOptionValue (m_options.stop, stop_action))
   1818         {
   1819             result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
   1820             result.SetStatus (eReturnStatusFailed);
   1821             return false;
   1822         }
   1823 
   1824         if (! m_options.notify.empty()
   1825             && ! VerifyCommandOptionValue (m_options.notify, notify_action))
   1826         {
   1827             result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
   1828             result.SetStatus (eReturnStatusFailed);
   1829             return false;
   1830         }
   1831 
   1832         if (! m_options.pass.empty()
   1833             && ! VerifyCommandOptionValue (m_options.pass, pass_action))
   1834         {
   1835             result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
   1836             result.SetStatus (eReturnStatusFailed);
   1837             return false;
   1838         }
   1839 
   1840         size_t num_args = signal_args.GetArgumentCount();
   1841         UnixSignals &signals = process_sp->GetUnixSignals();
   1842         int num_signals_set = 0;
   1843 
   1844         if (num_args > 0)
   1845         {
   1846             for (size_t i = 0; i < num_args; ++i)
   1847             {
   1848                 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
   1849                 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
   1850                 {
   1851                     // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
   1852                     // the value is either 0 or 1.
   1853                     if (stop_action != -1)
   1854                         signals.SetShouldStop (signo, (bool) stop_action);
   1855                     if (pass_action != -1)
   1856                     {
   1857                         bool suppress = ! ((bool) pass_action);
   1858                         signals.SetShouldSuppress (signo, suppress);
   1859                     }
   1860                     if (notify_action != -1)
   1861                         signals.SetShouldNotify (signo, (bool) notify_action);
   1862                     ++num_signals_set;
   1863                 }
   1864                 else
   1865                 {
   1866                     result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
   1867                 }
   1868             }
   1869         }
   1870         else
   1871         {
   1872             // No signal specified, if any command options were specified, update ALL signals.
   1873             if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
   1874             {
   1875                 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
   1876                 {
   1877                     int32_t signo = signals.GetFirstSignalNumber();
   1878                     while (signo != LLDB_INVALID_SIGNAL_NUMBER)
   1879                     {
   1880                         if (notify_action != -1)
   1881                             signals.SetShouldNotify (signo, (bool) notify_action);
   1882                         if (stop_action != -1)
   1883                             signals.SetShouldStop (signo, (bool) stop_action);
   1884                         if (pass_action != -1)
   1885                         {
   1886                             bool suppress = ! ((bool) pass_action);
   1887                             signals.SetShouldSuppress (signo, suppress);
   1888                         }
   1889                         signo = signals.GetNextSignalNumber (signo);
   1890                     }
   1891                 }
   1892             }
   1893         }
   1894 
   1895         PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals);
   1896 
   1897         if (num_signals_set > 0)
   1898             result.SetStatus (eReturnStatusSuccessFinishNoResult);
   1899         else
   1900             result.SetStatus (eReturnStatusFailed);
   1901 
   1902         return result.Succeeded();
   1903     }
   1904 
   1905     CommandOptions m_options;
   1906 };
   1907 
   1908 OptionDefinition
   1909 CommandObjectProcessHandle::CommandOptions::g_option_table[] =
   1910 {
   1911 { LLDB_OPT_SET_1, false, "stop",   's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
   1912 { LLDB_OPT_SET_1, false, "notify", 'n', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
   1913 { LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
   1914 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
   1915 };
   1916 
   1917 //-------------------------------------------------------------------------
   1918 // CommandObjectMultiwordProcess
   1919 //-------------------------------------------------------------------------
   1920 
   1921 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) :
   1922     CommandObjectMultiword (interpreter,
   1923                             "process",
   1924                             "A set of commands for operating on a process.",
   1925                             "process <subcommand> [<subcommand-options>]")
   1926 {
   1927     LoadSubCommand ("attach",      CommandObjectSP (new CommandObjectProcessAttach    (interpreter)));
   1928     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch    (interpreter)));
   1929     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
   1930     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
   1931     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
   1932     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
   1933     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
   1934     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
   1935     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle    (interpreter)));
   1936     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus    (interpreter)));
   1937     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
   1938     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill      (interpreter)));
   1939     LoadSubCommand ("plugin",      CommandObjectSP (new CommandObjectProcessPlugin    (interpreter)));
   1940 }
   1941 
   1942 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess ()
   1943 {
   1944 }
   1945 
   1946