130fdc8d8SChris Lattner //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "CommandObjectProcess.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1640af72e1SJim Ingham #include "lldb/Interpreter/Args.h" 1740af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 1830fdc8d8SChris Lattner #include "lldb/Core/State.h" 1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 214b9bea87SJim Ingham #include "./CommandObjectThread.h" 2230fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2330fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2430fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2530fdc8d8SChris Lattner 2630fdc8d8SChris Lattner using namespace lldb; 2730fdc8d8SChris Lattner using namespace lldb_private; 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner //------------------------------------------------------------------------- 3030fdc8d8SChris Lattner // CommandObjectProcessLaunch 3130fdc8d8SChris Lattner //------------------------------------------------------------------------- 32bb9caf73SJim Ingham #pragma mark CommandObjectProjectLaunch 3330fdc8d8SChris Lattner class CommandObjectProcessLaunch : public CommandObject 3430fdc8d8SChris Lattner { 3530fdc8d8SChris Lattner public: 3630fdc8d8SChris Lattner 3730fdc8d8SChris Lattner class CommandOptions : public Options 3830fdc8d8SChris Lattner { 3930fdc8d8SChris Lattner public: 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner CommandOptions () : 4230fdc8d8SChris Lattner Options() 4330fdc8d8SChris Lattner { 4430fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 4530fdc8d8SChris Lattner ResetOptionValues (); 4630fdc8d8SChris Lattner } 4730fdc8d8SChris Lattner 4830fdc8d8SChris Lattner ~CommandOptions () 4930fdc8d8SChris Lattner { 5030fdc8d8SChris Lattner } 5130fdc8d8SChris Lattner 5230fdc8d8SChris Lattner Error 5330fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 5430fdc8d8SChris Lattner { 5530fdc8d8SChris Lattner Error error; 5630fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 5730fdc8d8SChris Lattner 5830fdc8d8SChris Lattner switch (short_option) 5930fdc8d8SChris Lattner { 6030fdc8d8SChris Lattner case 's': stop_at_entry = true; break; 61*bd82a5d2SGreg Clayton case 'e': stderr_path.assign (option_arg); break; 62*bd82a5d2SGreg Clayton case 'i': stdin_path.assign (option_arg); break; 63*bd82a5d2SGreg Clayton case 'o': stdout_path.assign (option_arg); break; 64*bd82a5d2SGreg Clayton case 'p': plugin_name.assign (option_arg); break; 65f8da8631SCaroline Tice case 'n': no_stdio = true; break; 66*bd82a5d2SGreg Clayton case 'w': working_dir.assign (option_arg); break; 67913c4fa1SGreg Clayton case 't': 68913c4fa1SGreg Clayton if (option_arg && option_arg[0]) 69913c4fa1SGreg Clayton tty_name.assign (option_arg); 70913c4fa1SGreg Clayton in_new_tty = true; 71913c4fa1SGreg Clayton break; 7230fdc8d8SChris Lattner default: 7330fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 7430fdc8d8SChris Lattner break; 7530fdc8d8SChris Lattner 7630fdc8d8SChris Lattner } 7730fdc8d8SChris Lattner return error; 7830fdc8d8SChris Lattner } 7930fdc8d8SChris Lattner 8030fdc8d8SChris Lattner void 8130fdc8d8SChris Lattner ResetOptionValues () 8230fdc8d8SChris Lattner { 8330fdc8d8SChris Lattner Options::ResetOptionValues(); 8430fdc8d8SChris Lattner stop_at_entry = false; 8519388cfcSGreg Clayton in_new_tty = false; 86913c4fa1SGreg Clayton tty_name.clear(); 8730fdc8d8SChris Lattner stdin_path.clear(); 8830fdc8d8SChris Lattner stdout_path.clear(); 8930fdc8d8SChris Lattner stderr_path.clear(); 9030fdc8d8SChris Lattner plugin_name.clear(); 91*bd82a5d2SGreg Clayton working_dir.clear(); 92f8da8631SCaroline Tice no_stdio = false; 9330fdc8d8SChris Lattner } 9430fdc8d8SChris Lattner 9530fdc8d8SChris Lattner const lldb::OptionDefinition* 9630fdc8d8SChris Lattner GetDefinitions () 9730fdc8d8SChris Lattner { 9830fdc8d8SChris Lattner return g_option_table; 9930fdc8d8SChris Lattner } 10030fdc8d8SChris Lattner 10130fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 10230fdc8d8SChris Lattner 10330fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 10430fdc8d8SChris Lattner 10530fdc8d8SChris Lattner // Instance variables to hold the values for command options. 10630fdc8d8SChris Lattner 10730fdc8d8SChris Lattner bool stop_at_entry; 10819388cfcSGreg Clayton bool in_new_tty; 109f8da8631SCaroline Tice bool no_stdio; 110913c4fa1SGreg Clayton std::string tty_name; 11130fdc8d8SChris Lattner std::string stderr_path; 11230fdc8d8SChris Lattner std::string stdin_path; 11330fdc8d8SChris Lattner std::string stdout_path; 11430fdc8d8SChris Lattner std::string plugin_name; 115*bd82a5d2SGreg Clayton std::string working_dir; 11630fdc8d8SChris Lattner 11730fdc8d8SChris Lattner }; 11830fdc8d8SChris Lattner 119a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 120a7015092SGreg Clayton CommandObject (interpreter, 121a7015092SGreg Clayton "process launch", 122e3d26315SCaroline Tice "Launch the executable in the debugger.", 123405fe67fSCaroline Tice NULL) 12430fdc8d8SChris Lattner { 125405fe67fSCaroline Tice CommandArgumentEntry arg; 126405fe67fSCaroline Tice CommandArgumentData run_args_arg; 127405fe67fSCaroline Tice 128405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 129405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 130405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 131405fe67fSCaroline Tice 132405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 133405fe67fSCaroline Tice arg.push_back (run_args_arg); 134405fe67fSCaroline Tice 135405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 136405fe67fSCaroline Tice m_arguments.push_back (arg); 13730fdc8d8SChris Lattner } 13830fdc8d8SChris Lattner 13930fdc8d8SChris Lattner 14030fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 14130fdc8d8SChris Lattner { 14230fdc8d8SChris Lattner } 14330fdc8d8SChris Lattner 14430fdc8d8SChris Lattner Options * 14530fdc8d8SChris Lattner GetOptions () 14630fdc8d8SChris Lattner { 14730fdc8d8SChris Lattner return &m_options; 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner 15030fdc8d8SChris Lattner bool 15105faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 15230fdc8d8SChris Lattner { 153a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 15430fdc8d8SChris Lattner 15530fdc8d8SChris Lattner if (target == NULL) 15630fdc8d8SChris Lattner { 15730fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 15830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 15930fdc8d8SChris Lattner return false; 16030fdc8d8SChris Lattner } 16130fdc8d8SChris Lattner 16230fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 16330fdc8d8SChris Lattner char filename[PATH_MAX]; 16419388cfcSGreg Clayton const Module *exe_module = target->GetExecutableModule().get(); 16530fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 16630fdc8d8SChris Lattner 167a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 168a7015092SGreg Clayton if (process && process->IsAlive()) 16930fdc8d8SChris Lattner { 170bb9caf73SJim Ingham if (!m_interpreter.Confirm ("There is a running process, kill it and restart?", true)) 171bb9caf73SJim Ingham { 172bb9caf73SJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, restart cancelled.\n", 17330fdc8d8SChris Lattner process->GetID()); 17430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 17530fdc8d8SChris Lattner return false; 17630fdc8d8SChris Lattner } 177bb9caf73SJim Ingham else 178bb9caf73SJim Ingham { 179bb9caf73SJim Ingham Error error (process->Destroy()); 180bb9caf73SJim Ingham if (error.Success()) 181bb9caf73SJim Ingham { 182bb9caf73SJim Ingham result.SetStatus (eReturnStatusSuccessFinishResult); 183bb9caf73SJim Ingham } 184bb9caf73SJim Ingham else 185bb9caf73SJim Ingham { 186bb9caf73SJim Ingham result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 187bb9caf73SJim Ingham result.SetStatus (eReturnStatusFailed); 188bb9caf73SJim Ingham } 189bb9caf73SJim Ingham } 190bb9caf73SJim Ingham } 19130fdc8d8SChris Lattner 19230fdc8d8SChris Lattner const char *plugin_name; 19330fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 19430fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 19530fdc8d8SChris Lattner else 19630fdc8d8SChris Lattner plugin_name = NULL; 19730fdc8d8SChris Lattner 198a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 19930fdc8d8SChris Lattner 200a7015092SGreg Clayton if (process == NULL) 2013df9a8dfSCaroline Tice { 20243a8c39bSCaroline Tice result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 203a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 204a7015092SGreg Clayton return false; 2053df9a8dfSCaroline Tice } 2063df9a8dfSCaroline Tice 207a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 208a7015092SGreg Clayton // might have been set using the "run-args" set variable. 20930fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 21030fdc8d8SChris Lattner { 211a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 212a7015092SGreg Clayton launch_args = process->GetRunArguments(); 21330fdc8d8SChris Lattner } 21430fdc8d8SChris Lattner 21519388cfcSGreg Clayton if (m_options.in_new_tty) 21619388cfcSGreg Clayton { 21719388cfcSGreg Clayton char exec_file_path[PATH_MAX]; 21819388cfcSGreg Clayton if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 21919388cfcSGreg Clayton { 22019388cfcSGreg Clayton launch_args.InsertArgumentAtIndex(0, exec_file_path); 22119388cfcSGreg Clayton } 22219388cfcSGreg Clayton else 22319388cfcSGreg Clayton { 22419388cfcSGreg Clayton result.AppendError("invalid executable"); 22519388cfcSGreg Clayton result.SetStatus (eReturnStatusFailed); 22619388cfcSGreg Clayton return false; 22719388cfcSGreg Clayton } 22819388cfcSGreg Clayton } 22919388cfcSGreg Clayton 230a7015092SGreg Clayton Args environment; 23130fdc8d8SChris Lattner 232a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 233a7015092SGreg Clayton 234a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 235a7015092SGreg Clayton 236a7015092SGreg Clayton if (process->GetDisableASLR()) 237a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 238a7015092SGreg Clayton 239f8da8631SCaroline Tice if (m_options.no_stdio) 240f8da8631SCaroline Tice launch_flags |= eLaunchFlagDisableSTDIO; 241f8da8631SCaroline Tice else if (!m_options.in_new_tty 242f8da8631SCaroline Tice && m_options.stdin_path.empty() 243f8da8631SCaroline Tice && m_options.stdout_path.empty() 244f8da8631SCaroline Tice && m_options.stderr_path.empty()) 245f8da8631SCaroline Tice { 246f8da8631SCaroline Tice // Only use the settings value if the user hasn't specified any options that would override it. 247f8da8631SCaroline Tice if (process->GetDisableSTDIO()) 248f8da8631SCaroline Tice launch_flags |= eLaunchFlagDisableSTDIO; 249f8da8631SCaroline Tice } 250f8da8631SCaroline Tice 25119388cfcSGreg Clayton const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 25219388cfcSGreg Clayton const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 25330fdc8d8SChris Lattner 25419388cfcSGreg Clayton Error error; 255*bd82a5d2SGreg Clayton const char *working_dir = NULL; 256*bd82a5d2SGreg Clayton if (!m_options.working_dir.empty()) 257*bd82a5d2SGreg Clayton working_dir = m_options.working_dir.c_str(); 25819388cfcSGreg Clayton 25919388cfcSGreg Clayton if (m_options.in_new_tty) 26019388cfcSGreg Clayton { 26119388cfcSGreg Clayton 262913c4fa1SGreg Clayton lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(), 263913c4fa1SGreg Clayton inferior_argv, 26419388cfcSGreg Clayton inferior_envp, 265*bd82a5d2SGreg Clayton working_dir, 26619388cfcSGreg Clayton &exe_module->GetArchitecture(), 26719388cfcSGreg Clayton true, 26819388cfcSGreg Clayton process->GetDisableASLR()); 26919388cfcSGreg Clayton 2703fcbed6bSGreg Clayton if (pid != LLDB_INVALID_PROCESS_ID) 2713fcbed6bSGreg Clayton error = process->Attach (pid); 27219388cfcSGreg Clayton } 27319388cfcSGreg Clayton else 27419388cfcSGreg Clayton { 27530fdc8d8SChris Lattner const char * stdin_path = NULL; 27630fdc8d8SChris Lattner const char * stdout_path = NULL; 27730fdc8d8SChris Lattner const char * stderr_path = NULL; 27830fdc8d8SChris Lattner 279a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 280a7015092SGreg Clayton if (m_options.stdin_path.empty() && 28130fdc8d8SChris Lattner m_options.stdout_path.empty() && 282a7015092SGreg Clayton m_options.stderr_path.empty()) 28330fdc8d8SChris Lattner { 284a7015092SGreg Clayton // No standard file handles were given on the command line, check 285a7015092SGreg Clayton // with the process object in case they were give using "set settings" 286a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 287a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 288a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 289a7015092SGreg Clayton } 290a7015092SGreg Clayton else 291a7015092SGreg Clayton { 292a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 293a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 294a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner 29719388cfcSGreg Clayton error = process->Launch (inferior_argv, 29819388cfcSGreg Clayton inferior_envp, 299f681b94fSGreg Clayton launch_flags, 30030fdc8d8SChris Lattner stdin_path, 30130fdc8d8SChris Lattner stdout_path, 302*bd82a5d2SGreg Clayton stderr_path, 303*bd82a5d2SGreg Clayton working_dir); 30419388cfcSGreg Clayton } 30530fdc8d8SChris Lattner 30630fdc8d8SChris Lattner if (error.Success()) 30730fdc8d8SChris Lattner { 30819388cfcSGreg Clayton const char *archname = exe_module->GetArchitecture().AsCString(); 30919388cfcSGreg Clayton 31019388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 31105faeb71SGreg Clayton result.SetDidChangeProcessState (true); 31230fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 31330fdc8d8SChris Lattner { 31405faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 31530fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 31630fdc8d8SChris Lattner 31730fdc8d8SChris Lattner if (state == eStateStopped) 31830fdc8d8SChris Lattner { 31905faeb71SGreg Clayton error = process->Resume(); 32005faeb71SGreg Clayton if (error.Success()) 32105faeb71SGreg Clayton { 32205faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 32330fdc8d8SChris Lattner if (synchronous_execution) 32430fdc8d8SChris Lattner { 32505faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 32630fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 32705faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 32805faeb71SGreg Clayton } 32905faeb71SGreg Clayton else 33005faeb71SGreg Clayton { 33105faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 33205faeb71SGreg Clayton } 33305faeb71SGreg Clayton } 33430fdc8d8SChris Lattner } 33530fdc8d8SChris Lattner } 33630fdc8d8SChris Lattner } 33730fdc8d8SChris Lattner 33830fdc8d8SChris Lattner return result.Succeeded(); 33930fdc8d8SChris Lattner } 34030fdc8d8SChris Lattner 341ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 342ebc09c36SJim Ingham { 343ebc09c36SJim Ingham // No repeat for "process launch"... 344ebc09c36SJim Ingham return ""; 345ebc09c36SJim Ingham } 346ebc09c36SJim Ingham 34730fdc8d8SChris Lattner protected: 34830fdc8d8SChris Lattner 34930fdc8d8SChris Lattner CommandOptions m_options; 35030fdc8d8SChris Lattner }; 35130fdc8d8SChris Lattner 35230fdc8d8SChris Lattner 35319388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1 35419388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2 355f8da8631SCaroline Tice #define SET3 LLDB_OPT_SET_3 35619388cfcSGreg Clayton 35730fdc8d8SChris Lattner lldb::OptionDefinition 35830fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 35930fdc8d8SChris Lattner { 360f8da8631SCaroline Tice { 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."}, 36119388cfcSGreg Clayton { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 36219388cfcSGreg Clayton { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 36319388cfcSGreg Clayton { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 364f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 365913c4fa1SGreg Clayton { SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypePath, "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."}, 366f8da8631SCaroline Tice { SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, 367*bd82a5d2SGreg Clayton { SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."}, 368deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 36930fdc8d8SChris Lattner }; 37030fdc8d8SChris Lattner 37119388cfcSGreg Clayton #undef SET1 37219388cfcSGreg Clayton #undef SET2 373f8da8631SCaroline Tice #undef SET3 37430fdc8d8SChris Lattner 37530fdc8d8SChris Lattner //------------------------------------------------------------------------- 37630fdc8d8SChris Lattner // CommandObjectProcessAttach 37730fdc8d8SChris Lattner //------------------------------------------------------------------------- 378bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach 37930fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 38030fdc8d8SChris Lattner { 38130fdc8d8SChris Lattner public: 38230fdc8d8SChris Lattner 38330fdc8d8SChris Lattner class CommandOptions : public Options 38430fdc8d8SChris Lattner { 38530fdc8d8SChris Lattner public: 38630fdc8d8SChris Lattner 38730fdc8d8SChris Lattner CommandOptions () : 38830fdc8d8SChris Lattner Options() 38930fdc8d8SChris Lattner { 39030fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 39130fdc8d8SChris Lattner ResetOptionValues (); 39230fdc8d8SChris Lattner } 39330fdc8d8SChris Lattner 39430fdc8d8SChris Lattner ~CommandOptions () 39530fdc8d8SChris Lattner { 39630fdc8d8SChris Lattner } 39730fdc8d8SChris Lattner 39830fdc8d8SChris Lattner Error 39930fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 40030fdc8d8SChris Lattner { 40130fdc8d8SChris Lattner Error error; 40230fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 40330fdc8d8SChris Lattner bool success = false; 40430fdc8d8SChris Lattner switch (short_option) 40530fdc8d8SChris Lattner { 40630fdc8d8SChris Lattner case 'p': 40730fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 40830fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 40930fdc8d8SChris Lattner { 41030fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner break; 41330fdc8d8SChris Lattner 41430fdc8d8SChris Lattner case 'P': 41530fdc8d8SChris Lattner plugin_name = option_arg; 41630fdc8d8SChris Lattner break; 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner case 'n': 41930fdc8d8SChris Lattner name.assign(option_arg); 42030fdc8d8SChris Lattner break; 42130fdc8d8SChris Lattner 42230fdc8d8SChris Lattner case 'w': 42330fdc8d8SChris Lattner waitfor = true; 42430fdc8d8SChris Lattner break; 42530fdc8d8SChris Lattner 42630fdc8d8SChris Lattner default: 42730fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 42830fdc8d8SChris Lattner break; 42930fdc8d8SChris Lattner } 43030fdc8d8SChris Lattner return error; 43130fdc8d8SChris Lattner } 43230fdc8d8SChris Lattner 43330fdc8d8SChris Lattner void 43430fdc8d8SChris Lattner ResetOptionValues () 43530fdc8d8SChris Lattner { 43630fdc8d8SChris Lattner Options::ResetOptionValues(); 43730fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 43830fdc8d8SChris Lattner name.clear(); 43930fdc8d8SChris Lattner waitfor = false; 44030fdc8d8SChris Lattner } 44130fdc8d8SChris Lattner 44230fdc8d8SChris Lattner const lldb::OptionDefinition* 44330fdc8d8SChris Lattner GetDefinitions () 44430fdc8d8SChris Lattner { 44530fdc8d8SChris Lattner return g_option_table; 44630fdc8d8SChris Lattner } 44730fdc8d8SChris Lattner 4485aee162fSJim Ingham virtual bool 449a7015092SGreg Clayton HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 4505aee162fSJim Ingham Args &input, 4515aee162fSJim Ingham int cursor_index, 4525aee162fSJim Ingham int char_pos, 4535aee162fSJim Ingham OptionElementVector &opt_element_vector, 4545aee162fSJim Ingham int opt_element_index, 4555aee162fSJim Ingham int match_start_point, 4565aee162fSJim Ingham int max_return_elements, 4575aee162fSJim Ingham bool &word_complete, 4585aee162fSJim Ingham StringList &matches) 4595aee162fSJim Ingham { 4605aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4615aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4625aee162fSJim Ingham 4635aee162fSJim Ingham // We are only completing the name option for now... 4645aee162fSJim Ingham 4655aee162fSJim Ingham const lldb::OptionDefinition *opt_defs = GetDefinitions(); 4665aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4675aee162fSJim Ingham { 4685aee162fSJim Ingham // Are we in the name? 4695aee162fSJim Ingham 4705aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4715aee162fSJim Ingham // use the default plugin. 472a7015092SGreg Clayton Process *process = interpeter.GetDebugger().GetExecutionContext().process; 4735aee162fSJim Ingham bool need_to_delete_process = false; 4745aee162fSJim Ingham 4755aee162fSJim Ingham const char *partial_name = NULL; 4765aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4775aee162fSJim Ingham 4785aee162fSJim Ingham if (process && process->IsAlive()) 4795aee162fSJim Ingham return true; 4805aee162fSJim Ingham 481a7015092SGreg Clayton Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 4825aee162fSJim Ingham if (target == NULL) 4835aee162fSJim Ingham { 4845aee162fSJim Ingham // No target has been set yet, for now do host completion. Otherwise I don't know how we would 4855aee162fSJim Ingham // figure out what the right target to use is... 4865aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4875aee162fSJim Ingham Host::ListProcessesMatchingName (partial_name, matches, pids); 4885aee162fSJim Ingham return true; 4895aee162fSJim Ingham } 4905aee162fSJim Ingham if (!process) 4915aee162fSJim Ingham { 492a7015092SGreg Clayton process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 4935aee162fSJim Ingham need_to_delete_process = true; 4945aee162fSJim Ingham } 4955aee162fSJim Ingham 4965aee162fSJim Ingham if (process) 4975aee162fSJim Ingham { 4985aee162fSJim Ingham matches.Clear(); 4995aee162fSJim Ingham std::vector<lldb::pid_t> pids; 5005aee162fSJim Ingham process->ListProcessesMatchingName (NULL, matches, pids); 5015aee162fSJim Ingham if (need_to_delete_process) 5025aee162fSJim Ingham target->DeleteCurrentProcess(); 5035aee162fSJim Ingham return true; 5045aee162fSJim Ingham } 5055aee162fSJim Ingham } 5065aee162fSJim Ingham 5075aee162fSJim Ingham return false; 5085aee162fSJim Ingham } 5095aee162fSJim Ingham 51030fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 51130fdc8d8SChris Lattner 51230fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 51330fdc8d8SChris Lattner 51430fdc8d8SChris Lattner // Instance variables to hold the values for command options. 51530fdc8d8SChris Lattner 51630fdc8d8SChris Lattner lldb::pid_t pid; 51730fdc8d8SChris Lattner std::string plugin_name; 51830fdc8d8SChris Lattner std::string name; 51930fdc8d8SChris Lattner bool waitfor; 52030fdc8d8SChris Lattner }; 52130fdc8d8SChris Lattner 522a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 523a7015092SGreg Clayton CommandObject (interpreter, 524a7015092SGreg Clayton "process attach", 525e3d26315SCaroline Tice "Attach to a process.", 5265aee162fSJim Ingham "process attach <cmd-options>") 5275aee162fSJim Ingham { 5285aee162fSJim Ingham } 5295aee162fSJim Ingham 5305aee162fSJim Ingham ~CommandObjectProcessAttach () 5315aee162fSJim Ingham { 5325aee162fSJim Ingham } 5335aee162fSJim Ingham 5345aee162fSJim Ingham bool 535a7015092SGreg Clayton Execute (Args& command, 5365aee162fSJim Ingham CommandReturnObject &result) 5375aee162fSJim Ingham { 538a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5395aee162fSJim Ingham 540a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 5415aee162fSJim Ingham if (process) 5425aee162fSJim Ingham { 5435aee162fSJim Ingham if (process->IsAlive()) 5445aee162fSJim Ingham { 5455aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 5465aee162fSJim Ingham process->GetID()); 5475aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5485aee162fSJim Ingham return false; 5495aee162fSJim Ingham } 5505aee162fSJim Ingham } 5515aee162fSJim Ingham 5525aee162fSJim Ingham if (target == NULL) 5535aee162fSJim Ingham { 5545aee162fSJim Ingham // If there isn't a current target create one. 5555aee162fSJim Ingham TargetSP new_target_sp; 5565aee162fSJim Ingham FileSpec emptyFileSpec; 5575aee162fSJim Ingham ArchSpec emptyArchSpec; 5585aee162fSJim Ingham Error error; 5595aee162fSJim Ingham 560a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 5615aee162fSJim Ingham emptyFileSpec, 5625aee162fSJim Ingham emptyArchSpec, 5635aee162fSJim Ingham NULL, 5645aee162fSJim Ingham false, 5655aee162fSJim Ingham new_target_sp); 5665aee162fSJim Ingham target = new_target_sp.get(); 5675aee162fSJim Ingham if (target == NULL || error.Fail()) 5685aee162fSJim Ingham { 5695aee162fSJim Ingham result.AppendError(error.AsCString("Error creating empty target")); 5705aee162fSJim Ingham return false; 5715aee162fSJim Ingham } 572a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5735aee162fSJim Ingham } 5745aee162fSJim Ingham 5755aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5765aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5775aee162fSJim Ingham 5785aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5795aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5805aee162fSJim Ingham 5815aee162fSJim Ingham if (command.GetArgumentCount()) 5825aee162fSJim Ingham { 5835aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5845aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5855aee162fSJim Ingham } 5865aee162fSJim Ingham else 5875aee162fSJim Ingham { 5885aee162fSJim Ingham const char *plugin_name = NULL; 5895aee162fSJim Ingham 5905aee162fSJim Ingham if (!m_options.plugin_name.empty()) 5915aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 5925aee162fSJim Ingham 593a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 5945aee162fSJim Ingham 5955aee162fSJim Ingham if (process) 5965aee162fSJim Ingham { 5975aee162fSJim Ingham Error error; 5985aee162fSJim Ingham int attach_pid = m_options.pid; 5995aee162fSJim Ingham 6003a0b9cdfSJim Ingham const char *wait_name = NULL; 6013a0b9cdfSJim Ingham 6025aee162fSJim Ingham if (m_options.name.empty()) 6035aee162fSJim Ingham { 6043a0b9cdfSJim Ingham if (old_exec_module_sp) 6053a0b9cdfSJim Ingham { 6063a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 6073a0b9cdfSJim Ingham } 6085aee162fSJim Ingham } 6095aee162fSJim Ingham else 6105aee162fSJim Ingham { 6113a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 6123a0b9cdfSJim Ingham } 6133a0b9cdfSJim Ingham 6143a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 6153a0b9cdfSJim Ingham if (m_options.waitfor) 6163a0b9cdfSJim Ingham { 6173a0b9cdfSJim Ingham 6183a0b9cdfSJim Ingham if (wait_name == NULL) 6193a0b9cdfSJim Ingham { 6203a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 6213a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 6223a0b9cdfSJim Ingham return false; 6233a0b9cdfSJim Ingham } 6243a0b9cdfSJim Ingham 625a7015092SGreg Clayton m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 6263a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 6275aee162fSJim Ingham if (error.Success()) 6285aee162fSJim Ingham { 6295aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6305aee162fSJim Ingham } 6315aee162fSJim Ingham else 6325aee162fSJim Ingham { 6335aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 6343a0b9cdfSJim Ingham wait_name, 6355aee162fSJim Ingham error.AsCString()); 6365aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6375aee162fSJim Ingham return false; 6385aee162fSJim Ingham } 6395aee162fSJim Ingham } 6405aee162fSJim Ingham else 6415aee162fSJim Ingham { 6425aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 6435aee162fSJim Ingham // processes with this pid. 6445aee162fSJim Ingham 6453a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 6465aee162fSJim Ingham { 6475aee162fSJim Ingham std::vector<lldb::pid_t> pids; 6485aee162fSJim Ingham StringList matches; 6495aee162fSJim Ingham 6503a0b9cdfSJim Ingham process->ListProcessesMatchingName(wait_name, matches, pids); 6515aee162fSJim Ingham if (matches.GetSize() > 1) 6525aee162fSJim Ingham { 6533a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 6545aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6555aee162fSJim Ingham return false; 6565aee162fSJim Ingham } 6575aee162fSJim Ingham else if (matches.GetSize() == 0) 6585aee162fSJim Ingham { 6593a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 6605aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6615aee162fSJim Ingham return false; 6625aee162fSJim Ingham } 6635aee162fSJim Ingham else 6645aee162fSJim Ingham { 6655aee162fSJim Ingham attach_pid = pids[0]; 6665aee162fSJim Ingham } 6675aee162fSJim Ingham 6685aee162fSJim Ingham } 6695aee162fSJim Ingham 6705aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 6715aee162fSJim Ingham { 6725aee162fSJim Ingham error = process->Attach (attach_pid); 6735aee162fSJim Ingham if (error.Success()) 6745aee162fSJim Ingham { 6755aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6765aee162fSJim Ingham } 6775aee162fSJim Ingham else 6785aee162fSJim Ingham { 6795aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 6805aee162fSJim Ingham attach_pid, 6815aee162fSJim Ingham error.AsCString()); 6825aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6835aee162fSJim Ingham } 6845aee162fSJim Ingham } 6855aee162fSJim Ingham else 6865aee162fSJim Ingham { 6875aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 6885aee162fSJim Ingham attach_pid, 6895aee162fSJim Ingham error.AsCString()); 6905aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6915aee162fSJim Ingham 6925aee162fSJim Ingham } 6935aee162fSJim Ingham } 6945aee162fSJim Ingham } 6955aee162fSJim Ingham } 6965aee162fSJim Ingham 6975aee162fSJim Ingham if (result.Succeeded()) 6985aee162fSJim Ingham { 6995aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 7005aee162fSJim Ingham if (!old_exec_module_sp) 7015aee162fSJim Ingham { 7025aee162fSJim Ingham char new_path[PATH_MAX + 1]; 7035aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 7045aee162fSJim Ingham 7055aee162fSJim Ingham result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 7065aee162fSJim Ingham new_path); 7075aee162fSJim Ingham } 7085aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 7095aee162fSJim Ingham { 7105aee162fSJim Ingham char old_path[PATH_MAX + 1]; 7115aee162fSJim Ingham char new_path[PATH_MAX + 1]; 7125aee162fSJim Ingham 7135aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 7145aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 7155aee162fSJim Ingham 7165aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 7175aee162fSJim Ingham old_path, new_path); 7185aee162fSJim Ingham } 7195aee162fSJim Ingham 7205aee162fSJim Ingham if (!old_arch_spec.IsValid()) 7215aee162fSJim Ingham { 7225aee162fSJim Ingham result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 7235aee162fSJim Ingham } 7245aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 7255aee162fSJim Ingham { 7265aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 7275aee162fSJim Ingham old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 7285aee162fSJim Ingham } 7295aee162fSJim Ingham } 7305aee162fSJim Ingham return result.Succeeded(); 7315aee162fSJim Ingham } 7325aee162fSJim Ingham 7335aee162fSJim Ingham Options * 7345aee162fSJim Ingham GetOptions () 7355aee162fSJim Ingham { 7365aee162fSJim Ingham return &m_options; 7375aee162fSJim Ingham } 7385aee162fSJim Ingham 73930fdc8d8SChris Lattner protected: 74030fdc8d8SChris Lattner 74130fdc8d8SChris Lattner CommandOptions m_options; 74230fdc8d8SChris Lattner }; 74330fdc8d8SChris Lattner 74430fdc8d8SChris Lattner 74530fdc8d8SChris Lattner lldb::OptionDefinition 74630fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 74730fdc8d8SChris Lattner { 748deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 749deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 750deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 751deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 752deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 75330fdc8d8SChris Lattner }; 75430fdc8d8SChris Lattner 75530fdc8d8SChris Lattner //------------------------------------------------------------------------- 75630fdc8d8SChris Lattner // CommandObjectProcessContinue 75730fdc8d8SChris Lattner //------------------------------------------------------------------------- 758bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue 75930fdc8d8SChris Lattner 76030fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 76130fdc8d8SChris Lattner { 76230fdc8d8SChris Lattner public: 76330fdc8d8SChris Lattner 764a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 765a7015092SGreg Clayton CommandObject (interpreter, 766a7015092SGreg Clayton "process continue", 767e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 76830fdc8d8SChris Lattner "process continue", 76930fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 77030fdc8d8SChris Lattner { 77130fdc8d8SChris Lattner } 77230fdc8d8SChris Lattner 77330fdc8d8SChris Lattner 77430fdc8d8SChris Lattner ~CommandObjectProcessContinue () 77530fdc8d8SChris Lattner { 77630fdc8d8SChris Lattner } 77730fdc8d8SChris Lattner 77830fdc8d8SChris Lattner bool 779a7015092SGreg Clayton Execute (Args& command, 78030fdc8d8SChris Lattner CommandReturnObject &result) 78130fdc8d8SChris Lattner { 782a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 783a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 78430fdc8d8SChris Lattner 78530fdc8d8SChris Lattner if (process == NULL) 78630fdc8d8SChris Lattner { 78730fdc8d8SChris Lattner result.AppendError ("no process to continue"); 78830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78930fdc8d8SChris Lattner return false; 79030fdc8d8SChris Lattner } 79130fdc8d8SChris Lattner 79230fdc8d8SChris Lattner StateType state = process->GetState(); 79330fdc8d8SChris Lattner if (state == eStateStopped) 79430fdc8d8SChris Lattner { 79530fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 79630fdc8d8SChris Lattner { 79730fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 79830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 79930fdc8d8SChris Lattner return false; 80030fdc8d8SChris Lattner } 80130fdc8d8SChris Lattner 80230fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 80330fdc8d8SChris Lattner 80430fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 80530fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 80630fdc8d8SChris Lattner { 80730fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 80830fdc8d8SChris Lattner } 80930fdc8d8SChris Lattner 81030fdc8d8SChris Lattner Error error(process->Resume()); 81130fdc8d8SChris Lattner if (error.Success()) 81230fdc8d8SChris Lattner { 81319388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 81430fdc8d8SChris Lattner if (synchronous_execution) 81530fdc8d8SChris Lattner { 816b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 81730fdc8d8SChris Lattner 81830fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 81930fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 82030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 82130fdc8d8SChris Lattner } 82230fdc8d8SChris Lattner else 82330fdc8d8SChris Lattner { 82430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 82530fdc8d8SChris Lattner } 82630fdc8d8SChris Lattner } 82730fdc8d8SChris Lattner else 82830fdc8d8SChris Lattner { 82930fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 83030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 83130fdc8d8SChris Lattner } 83230fdc8d8SChris Lattner } 83330fdc8d8SChris Lattner else 83430fdc8d8SChris Lattner { 83530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 83630fdc8d8SChris Lattner StateAsCString(state)); 83730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 83830fdc8d8SChris Lattner } 83930fdc8d8SChris Lattner return result.Succeeded(); 84030fdc8d8SChris Lattner } 84130fdc8d8SChris Lattner }; 84230fdc8d8SChris Lattner 84330fdc8d8SChris Lattner //------------------------------------------------------------------------- 84430fdc8d8SChris Lattner // CommandObjectProcessDetach 84530fdc8d8SChris Lattner //------------------------------------------------------------------------- 846bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach 84730fdc8d8SChris Lattner 84830fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 84930fdc8d8SChris Lattner { 85030fdc8d8SChris Lattner public: 85130fdc8d8SChris Lattner 852a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 853a7015092SGreg Clayton CommandObject (interpreter, 854a7015092SGreg Clayton "process detach", 855e3d26315SCaroline Tice "Detach from the current process being debugged.", 85630fdc8d8SChris Lattner "process detach", 85730fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 85830fdc8d8SChris Lattner { 85930fdc8d8SChris Lattner } 86030fdc8d8SChris Lattner 86130fdc8d8SChris Lattner ~CommandObjectProcessDetach () 86230fdc8d8SChris Lattner { 86330fdc8d8SChris Lattner } 86430fdc8d8SChris Lattner 86530fdc8d8SChris Lattner bool 866a7015092SGreg Clayton Execute (Args& command, 86730fdc8d8SChris Lattner CommandReturnObject &result) 86830fdc8d8SChris Lattner { 869a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 87030fdc8d8SChris Lattner if (process == NULL) 87130fdc8d8SChris Lattner { 87230fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 87330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 87430fdc8d8SChris Lattner return false; 87530fdc8d8SChris Lattner } 87630fdc8d8SChris Lattner 8775d7be2e6SCaroline Tice result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID()); 87830fdc8d8SChris Lattner Error error (process->Detach()); 87930fdc8d8SChris Lattner if (error.Success()) 88030fdc8d8SChris Lattner { 88130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 88230fdc8d8SChris Lattner } 88330fdc8d8SChris Lattner else 88430fdc8d8SChris Lattner { 88530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 88630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 88730fdc8d8SChris Lattner return false; 88830fdc8d8SChris Lattner } 88930fdc8d8SChris Lattner return result.Succeeded(); 89030fdc8d8SChris Lattner } 89130fdc8d8SChris Lattner }; 89230fdc8d8SChris Lattner 89330fdc8d8SChris Lattner //------------------------------------------------------------------------- 8948f343b09SGreg Clayton // CommandObjectProcessLoad 8958f343b09SGreg Clayton //------------------------------------------------------------------------- 896bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad 8978f343b09SGreg Clayton 8988f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject 8998f343b09SGreg Clayton { 9008f343b09SGreg Clayton public: 9018f343b09SGreg Clayton 9028f343b09SGreg Clayton CommandObjectProcessLoad (CommandInterpreter &interpreter) : 9038f343b09SGreg Clayton CommandObject (interpreter, 9048f343b09SGreg Clayton "process load", 9058f343b09SGreg Clayton "Load a shared library into the current process.", 9068f343b09SGreg Clayton "process load <filename> [<filename> ...]", 9078f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 9088f343b09SGreg Clayton { 9098f343b09SGreg Clayton } 9108f343b09SGreg Clayton 9118f343b09SGreg Clayton ~CommandObjectProcessLoad () 9128f343b09SGreg Clayton { 9138f343b09SGreg Clayton } 9148f343b09SGreg Clayton 9158f343b09SGreg Clayton bool 9168f343b09SGreg Clayton Execute (Args& command, 9178f343b09SGreg Clayton CommandReturnObject &result) 9188f343b09SGreg Clayton { 9198f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 9208f343b09SGreg Clayton if (process == NULL) 9218f343b09SGreg Clayton { 9228f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 9238f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9248f343b09SGreg Clayton return false; 9258f343b09SGreg Clayton } 9268f343b09SGreg Clayton 9278f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 9288f343b09SGreg Clayton 9298f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 9308f343b09SGreg Clayton { 9318f343b09SGreg Clayton Error error; 9328f343b09SGreg Clayton const char *image_path = command.GetArgumentAtIndex(i); 9338f343b09SGreg Clayton FileSpec image_spec (image_path, false); 9348f343b09SGreg Clayton uint32_t image_token = process->LoadImage(image_spec, error); 9358f343b09SGreg Clayton if (image_token != LLDB_INVALID_IMAGE_TOKEN) 9368f343b09SGreg Clayton { 9378f343b09SGreg Clayton result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 9388f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 9398f343b09SGreg Clayton } 9408f343b09SGreg Clayton else 9418f343b09SGreg Clayton { 9428f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 9438f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9448f343b09SGreg Clayton } 9458f343b09SGreg Clayton } 9468f343b09SGreg Clayton return result.Succeeded(); 9478f343b09SGreg Clayton } 9488f343b09SGreg Clayton }; 9498f343b09SGreg Clayton 9508f343b09SGreg Clayton 9518f343b09SGreg Clayton //------------------------------------------------------------------------- 9528f343b09SGreg Clayton // CommandObjectProcessUnload 9538f343b09SGreg Clayton //------------------------------------------------------------------------- 954bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload 9558f343b09SGreg Clayton 9568f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject 9578f343b09SGreg Clayton { 9588f343b09SGreg Clayton public: 9598f343b09SGreg Clayton 9608f343b09SGreg Clayton CommandObjectProcessUnload (CommandInterpreter &interpreter) : 9618f343b09SGreg Clayton CommandObject (interpreter, 9628f343b09SGreg Clayton "process unload", 9638f343b09SGreg Clayton "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 9648f343b09SGreg Clayton "process unload <index>", 9658f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 9668f343b09SGreg Clayton { 9678f343b09SGreg Clayton } 9688f343b09SGreg Clayton 9698f343b09SGreg Clayton ~CommandObjectProcessUnload () 9708f343b09SGreg Clayton { 9718f343b09SGreg Clayton } 9728f343b09SGreg Clayton 9738f343b09SGreg Clayton bool 9748f343b09SGreg Clayton Execute (Args& command, 9758f343b09SGreg Clayton CommandReturnObject &result) 9768f343b09SGreg Clayton { 9778f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 9788f343b09SGreg Clayton if (process == NULL) 9798f343b09SGreg Clayton { 9808f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 9818f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9828f343b09SGreg Clayton return false; 9838f343b09SGreg Clayton } 9848f343b09SGreg Clayton 9858f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 9868f343b09SGreg Clayton 9878f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 9888f343b09SGreg Clayton { 9898f343b09SGreg Clayton const char *image_token_cstr = command.GetArgumentAtIndex(i); 9908f343b09SGreg Clayton uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 9918f343b09SGreg Clayton if (image_token == LLDB_INVALID_IMAGE_TOKEN) 9928f343b09SGreg Clayton { 9938f343b09SGreg Clayton result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 9948f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9958f343b09SGreg Clayton break; 9968f343b09SGreg Clayton } 9978f343b09SGreg Clayton else 9988f343b09SGreg Clayton { 9998f343b09SGreg Clayton Error error (process->UnloadImage(image_token)); 10008f343b09SGreg Clayton if (error.Success()) 10018f343b09SGreg Clayton { 10028f343b09SGreg Clayton result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 10038f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 10048f343b09SGreg Clayton } 10058f343b09SGreg Clayton else 10068f343b09SGreg Clayton { 10078f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 10088f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 10098f343b09SGreg Clayton break; 10108f343b09SGreg Clayton } 10118f343b09SGreg Clayton } 10128f343b09SGreg Clayton } 10138f343b09SGreg Clayton return result.Succeeded(); 10148f343b09SGreg Clayton } 10158f343b09SGreg Clayton }; 10168f343b09SGreg Clayton 10178f343b09SGreg Clayton //------------------------------------------------------------------------- 101830fdc8d8SChris Lattner // CommandObjectProcessSignal 101930fdc8d8SChris Lattner //------------------------------------------------------------------------- 1020bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal 102130fdc8d8SChris Lattner 102230fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 102330fdc8d8SChris Lattner { 102430fdc8d8SChris Lattner public: 102530fdc8d8SChris Lattner 1026a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 1027a7015092SGreg Clayton CommandObject (interpreter, 1028a7015092SGreg Clayton "process signal", 1029e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 1030405fe67fSCaroline Tice NULL) 103130fdc8d8SChris Lattner { 1032405fe67fSCaroline Tice CommandArgumentEntry arg; 1033405fe67fSCaroline Tice CommandArgumentData signal_arg; 1034405fe67fSCaroline Tice 1035405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 1036c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1037405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 1038405fe67fSCaroline Tice 1039405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 1040405fe67fSCaroline Tice arg.push_back (signal_arg); 1041405fe67fSCaroline Tice 1042405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1043405fe67fSCaroline Tice m_arguments.push_back (arg); 104430fdc8d8SChris Lattner } 104530fdc8d8SChris Lattner 104630fdc8d8SChris Lattner ~CommandObjectProcessSignal () 104730fdc8d8SChris Lattner { 104830fdc8d8SChris Lattner } 104930fdc8d8SChris Lattner 105030fdc8d8SChris Lattner bool 1051a7015092SGreg Clayton Execute (Args& command, 105230fdc8d8SChris Lattner CommandReturnObject &result) 105330fdc8d8SChris Lattner { 1054a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 105530fdc8d8SChris Lattner if (process == NULL) 105630fdc8d8SChris Lattner { 105730fdc8d8SChris Lattner result.AppendError ("no process to signal"); 105830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 105930fdc8d8SChris Lattner return false; 106030fdc8d8SChris Lattner } 106130fdc8d8SChris Lattner 106230fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 106330fdc8d8SChris Lattner { 1064237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1065237cd906SGreg Clayton 1066237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1067237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 1068237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1069237cd906SGreg Clayton else 1070237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 1071237cd906SGreg Clayton 1072237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 107330fdc8d8SChris Lattner { 107430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 107530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 107630fdc8d8SChris Lattner } 107730fdc8d8SChris Lattner else 107830fdc8d8SChris Lattner { 107930fdc8d8SChris Lattner Error error (process->Signal (signo)); 108030fdc8d8SChris Lattner if (error.Success()) 108130fdc8d8SChris Lattner { 108230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 108330fdc8d8SChris Lattner } 108430fdc8d8SChris Lattner else 108530fdc8d8SChris Lattner { 108630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 108730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 108830fdc8d8SChris Lattner } 108930fdc8d8SChris Lattner } 109030fdc8d8SChris Lattner } 109130fdc8d8SChris Lattner else 109230fdc8d8SChris Lattner { 109330fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 109430fdc8d8SChris Lattner m_cmd_syntax.c_str()); 109530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 109630fdc8d8SChris Lattner } 109730fdc8d8SChris Lattner return result.Succeeded(); 109830fdc8d8SChris Lattner } 109930fdc8d8SChris Lattner }; 110030fdc8d8SChris Lattner 110130fdc8d8SChris Lattner 110230fdc8d8SChris Lattner //------------------------------------------------------------------------- 110330fdc8d8SChris Lattner // CommandObjectProcessInterrupt 110430fdc8d8SChris Lattner //------------------------------------------------------------------------- 1105bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt 110630fdc8d8SChris Lattner 110730fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 110830fdc8d8SChris Lattner { 110930fdc8d8SChris Lattner public: 111030fdc8d8SChris Lattner 111130fdc8d8SChris Lattner 1112a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 1113a7015092SGreg Clayton CommandObject (interpreter, 1114a7015092SGreg Clayton "process interrupt", 1115e3d26315SCaroline Tice "Interrupt the current process being debugged.", 111630fdc8d8SChris Lattner "process interrupt", 111730fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 111830fdc8d8SChris Lattner { 111930fdc8d8SChris Lattner } 112030fdc8d8SChris Lattner 112130fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 112230fdc8d8SChris Lattner { 112330fdc8d8SChris Lattner } 112430fdc8d8SChris Lattner 112530fdc8d8SChris Lattner bool 1126a7015092SGreg Clayton Execute (Args& command, 112730fdc8d8SChris Lattner CommandReturnObject &result) 112830fdc8d8SChris Lattner { 1129a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 113030fdc8d8SChris Lattner if (process == NULL) 113130fdc8d8SChris Lattner { 113230fdc8d8SChris Lattner result.AppendError ("no process to halt"); 113330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 113430fdc8d8SChris Lattner return false; 113530fdc8d8SChris Lattner } 113630fdc8d8SChris Lattner 113730fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 113830fdc8d8SChris Lattner { 113930fdc8d8SChris Lattner Error error(process->Halt ()); 114030fdc8d8SChris Lattner if (error.Success()) 114130fdc8d8SChris Lattner { 114230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 114330fdc8d8SChris Lattner 114430fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 114530fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 114630fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 114730fdc8d8SChris Lattner } 114830fdc8d8SChris Lattner else 114930fdc8d8SChris Lattner { 115030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 115130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 115230fdc8d8SChris Lattner } 115330fdc8d8SChris Lattner } 115430fdc8d8SChris Lattner else 115530fdc8d8SChris Lattner { 115630fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 115730fdc8d8SChris Lattner m_cmd_name.c_str(), 115830fdc8d8SChris Lattner m_cmd_syntax.c_str()); 115930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 116030fdc8d8SChris Lattner } 116130fdc8d8SChris Lattner return result.Succeeded(); 116230fdc8d8SChris Lattner } 116330fdc8d8SChris Lattner }; 116430fdc8d8SChris Lattner 116530fdc8d8SChris Lattner //------------------------------------------------------------------------- 116630fdc8d8SChris Lattner // CommandObjectProcessKill 116730fdc8d8SChris Lattner //------------------------------------------------------------------------- 1168bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill 116930fdc8d8SChris Lattner 117030fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 117130fdc8d8SChris Lattner { 117230fdc8d8SChris Lattner public: 117330fdc8d8SChris Lattner 1174a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1175a7015092SGreg Clayton CommandObject (interpreter, 1176a7015092SGreg Clayton "process kill", 1177e3d26315SCaroline Tice "Terminate the current process being debugged.", 117830fdc8d8SChris Lattner "process kill", 117930fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 118030fdc8d8SChris Lattner { 118130fdc8d8SChris Lattner } 118230fdc8d8SChris Lattner 118330fdc8d8SChris Lattner ~CommandObjectProcessKill () 118430fdc8d8SChris Lattner { 118530fdc8d8SChris Lattner } 118630fdc8d8SChris Lattner 118730fdc8d8SChris Lattner bool 1188a7015092SGreg Clayton Execute (Args& command, 118930fdc8d8SChris Lattner CommandReturnObject &result) 119030fdc8d8SChris Lattner { 1191a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 119230fdc8d8SChris Lattner if (process == NULL) 119330fdc8d8SChris Lattner { 119430fdc8d8SChris Lattner result.AppendError ("no process to kill"); 119530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 119630fdc8d8SChris Lattner return false; 119730fdc8d8SChris Lattner } 119830fdc8d8SChris Lattner 119930fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 120030fdc8d8SChris Lattner { 120130fdc8d8SChris Lattner Error error (process->Destroy()); 120230fdc8d8SChris Lattner if (error.Success()) 120330fdc8d8SChris Lattner { 120430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 120530fdc8d8SChris Lattner } 120630fdc8d8SChris Lattner else 120730fdc8d8SChris Lattner { 120830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 120930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 121030fdc8d8SChris Lattner } 121130fdc8d8SChris Lattner } 121230fdc8d8SChris Lattner else 121330fdc8d8SChris Lattner { 121430fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 121530fdc8d8SChris Lattner m_cmd_name.c_str(), 121630fdc8d8SChris Lattner m_cmd_syntax.c_str()); 121730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 121830fdc8d8SChris Lattner } 121930fdc8d8SChris Lattner return result.Succeeded(); 122030fdc8d8SChris Lattner } 122130fdc8d8SChris Lattner }; 122230fdc8d8SChris Lattner 122330fdc8d8SChris Lattner //------------------------------------------------------------------------- 12244b9bea87SJim Ingham // CommandObjectProcessStatus 12254b9bea87SJim Ingham //------------------------------------------------------------------------- 1226bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus 1227bb9caf73SJim Ingham 12284b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 12294b9bea87SJim Ingham { 12304b9bea87SJim Ingham public: 1231a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1232a7015092SGreg Clayton CommandObject (interpreter, 1233a7015092SGreg Clayton "process status", 1234e3d26315SCaroline Tice "Show the current status and location of executing process.", 1235e3d26315SCaroline Tice "process status", 12364b9bea87SJim Ingham 0) 12374b9bea87SJim Ingham { 12384b9bea87SJim Ingham } 12394b9bea87SJim Ingham 12404b9bea87SJim Ingham ~CommandObjectProcessStatus() 12414b9bea87SJim Ingham { 12424b9bea87SJim Ingham } 12434b9bea87SJim Ingham 12444b9bea87SJim Ingham 12454b9bea87SJim Ingham bool 12464b9bea87SJim Ingham Execute 12474b9bea87SJim Ingham ( 12484b9bea87SJim Ingham Args& command, 12494b9bea87SJim Ingham CommandReturnObject &result 12504b9bea87SJim Ingham ) 12514b9bea87SJim Ingham { 12524b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 12534b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1254a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 12554b9bea87SJim Ingham if (exe_ctx.process) 12564b9bea87SJim Ingham { 12574b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 12584b9bea87SJim Ingham if (StateIsStoppedState(state)) 12594b9bea87SJim Ingham { 12604b9bea87SJim Ingham if (state == eStateExited) 12614b9bea87SJim Ingham { 12624b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 12634b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 12644b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 12654b9bea87SJim Ingham exe_ctx.process->GetID(), 12664b9bea87SJim Ingham exit_status, 12674b9bea87SJim Ingham exit_status, 12684b9bea87SJim Ingham exit_description ? exit_description : ""); 12694b9bea87SJim Ingham } 12704b9bea87SJim Ingham else 12714b9bea87SJim Ingham { 12724b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 12734b9bea87SJim Ingham if (exe_ctx.thread == NULL) 12744b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 12754b9bea87SJim Ingham if (exe_ctx.thread != NULL) 12764b9bea87SJim Ingham { 1277a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 12784b9bea87SJim Ingham } 12794b9bea87SJim Ingham else 12804b9bea87SJim Ingham { 12814b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 12824b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 12834b9bea87SJim Ingham } 12844b9bea87SJim Ingham } 12854b9bea87SJim Ingham } 12864b9bea87SJim Ingham else 12874b9bea87SJim Ingham { 12884b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 12894b9bea87SJim Ingham exe_ctx.process->GetID()); 12904b9bea87SJim Ingham } 12914b9bea87SJim Ingham } 12924b9bea87SJim Ingham else 12934b9bea87SJim Ingham { 12944b9bea87SJim Ingham result.AppendError ("No current location or status available."); 12954b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 12964b9bea87SJim Ingham } 12974b9bea87SJim Ingham return result.Succeeded(); 12984b9bea87SJim Ingham } 12994b9bea87SJim Ingham }; 13004b9bea87SJim Ingham 13014b9bea87SJim Ingham //------------------------------------------------------------------------- 130235731357SCaroline Tice // CommandObjectProcessHandle 130335731357SCaroline Tice //------------------------------------------------------------------------- 1304bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle 130535731357SCaroline Tice 130635731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 130735731357SCaroline Tice { 130835731357SCaroline Tice public: 130935731357SCaroline Tice 131035731357SCaroline Tice class CommandOptions : public Options 131135731357SCaroline Tice { 131235731357SCaroline Tice public: 131335731357SCaroline Tice 131435731357SCaroline Tice CommandOptions () : 131535731357SCaroline Tice Options () 131635731357SCaroline Tice { 131735731357SCaroline Tice ResetOptionValues (); 131835731357SCaroline Tice } 131935731357SCaroline Tice 132035731357SCaroline Tice ~CommandOptions () 132135731357SCaroline Tice { 132235731357SCaroline Tice } 132335731357SCaroline Tice 132435731357SCaroline Tice Error 132535731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 132635731357SCaroline Tice { 132735731357SCaroline Tice Error error; 132835731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 132935731357SCaroline Tice 133035731357SCaroline Tice switch (short_option) 133135731357SCaroline Tice { 133235731357SCaroline Tice case 's': 133335731357SCaroline Tice stop = option_arg; 133435731357SCaroline Tice break; 133535731357SCaroline Tice case 'n': 133635731357SCaroline Tice notify = option_arg; 133735731357SCaroline Tice break; 133835731357SCaroline Tice case 'p': 133935731357SCaroline Tice pass = option_arg; 134035731357SCaroline Tice break; 134135731357SCaroline Tice default: 134235731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 134335731357SCaroline Tice break; 134435731357SCaroline Tice } 134535731357SCaroline Tice return error; 134635731357SCaroline Tice } 134735731357SCaroline Tice 134835731357SCaroline Tice void 134935731357SCaroline Tice ResetOptionValues () 135035731357SCaroline Tice { 135135731357SCaroline Tice Options::ResetOptionValues(); 135235731357SCaroline Tice stop.clear(); 135335731357SCaroline Tice notify.clear(); 135435731357SCaroline Tice pass.clear(); 135535731357SCaroline Tice } 135635731357SCaroline Tice 135735731357SCaroline Tice const lldb::OptionDefinition* 135835731357SCaroline Tice GetDefinitions () 135935731357SCaroline Tice { 136035731357SCaroline Tice return g_option_table; 136135731357SCaroline Tice } 136235731357SCaroline Tice 136335731357SCaroline Tice // Options table: Required for subclasses of Options. 136435731357SCaroline Tice 136535731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 136635731357SCaroline Tice 136735731357SCaroline Tice // Instance variables to hold the values for command options. 136835731357SCaroline Tice 136935731357SCaroline Tice std::string stop; 137035731357SCaroline Tice std::string notify; 137135731357SCaroline Tice std::string pass; 137235731357SCaroline Tice }; 137335731357SCaroline Tice 137435731357SCaroline Tice 137535731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 137635731357SCaroline Tice CommandObject (interpreter, 137735731357SCaroline Tice "process handle", 137810ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 137935731357SCaroline Tice NULL) 138035731357SCaroline Tice { 138110ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 138235731357SCaroline Tice CommandArgumentEntry arg; 1383c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 138435731357SCaroline Tice 1385c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1386c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 138735731357SCaroline Tice 1388c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 138935731357SCaroline Tice 139035731357SCaroline Tice m_arguments.push_back (arg); 139135731357SCaroline Tice } 139235731357SCaroline Tice 139335731357SCaroline Tice ~CommandObjectProcessHandle () 139435731357SCaroline Tice { 139535731357SCaroline Tice } 139635731357SCaroline Tice 139735731357SCaroline Tice Options * 139835731357SCaroline Tice GetOptions () 139935731357SCaroline Tice { 140035731357SCaroline Tice return &m_options; 140135731357SCaroline Tice } 140235731357SCaroline Tice 140335731357SCaroline Tice bool 140410ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 140535731357SCaroline Tice { 140635731357SCaroline Tice bool okay = true; 140735731357SCaroline Tice 140810ad7993SCaroline Tice bool success = false; 140910ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 141010ad7993SCaroline Tice 141110ad7993SCaroline Tice if (success && tmp_value) 141210ad7993SCaroline Tice real_value = 1; 141310ad7993SCaroline Tice else if (success && !tmp_value) 141410ad7993SCaroline Tice real_value = 0; 141535731357SCaroline Tice else 141635731357SCaroline Tice { 141735731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 141810ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 141910ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 142035731357SCaroline Tice okay = false; 142135731357SCaroline Tice } 142235731357SCaroline Tice 142335731357SCaroline Tice return okay; 142435731357SCaroline Tice } 142535731357SCaroline Tice 142610ad7993SCaroline Tice void 142710ad7993SCaroline Tice PrintSignalHeader (Stream &str) 142810ad7993SCaroline Tice { 142910ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 143010ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 143110ad7993SCaroline Tice } 143210ad7993SCaroline Tice 143310ad7993SCaroline Tice void 143410ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 143510ad7993SCaroline Tice { 143610ad7993SCaroline Tice bool stop; 143710ad7993SCaroline Tice bool suppress; 143810ad7993SCaroline Tice bool notify; 143910ad7993SCaroline Tice 144010ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 144110ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 144210ad7993SCaroline Tice { 144310ad7993SCaroline Tice bool pass = !suppress; 144410ad7993SCaroline Tice str.Printf ("%s %s %s", 144510ad7993SCaroline Tice (pass ? "true " : "false"), 144610ad7993SCaroline Tice (stop ? "true " : "false"), 144710ad7993SCaroline Tice (notify ? "true " : "false")); 144810ad7993SCaroline Tice } 144910ad7993SCaroline Tice str.Printf ("\n"); 145010ad7993SCaroline Tice } 145110ad7993SCaroline Tice 145210ad7993SCaroline Tice void 145310ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 145410ad7993SCaroline Tice { 145510ad7993SCaroline Tice PrintSignalHeader (str); 145610ad7993SCaroline Tice 145710ad7993SCaroline Tice if (num_valid_signals > 0) 145810ad7993SCaroline Tice { 145910ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 146010ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 146110ad7993SCaroline Tice { 146210ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 146310ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 146410ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 146510ad7993SCaroline Tice } 146610ad7993SCaroline Tice } 146710ad7993SCaroline Tice else // Print info for ALL signals 146810ad7993SCaroline Tice { 146910ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 147010ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 147110ad7993SCaroline Tice { 147210ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 147310ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 147410ad7993SCaroline Tice } 147510ad7993SCaroline Tice } 147610ad7993SCaroline Tice } 147710ad7993SCaroline Tice 147835731357SCaroline Tice bool 147935731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 148035731357SCaroline Tice { 148135731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 148235731357SCaroline Tice 148335731357SCaroline Tice if (!target_sp) 148435731357SCaroline Tice { 148535731357SCaroline Tice result.AppendError ("No current target;" 148635731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 148735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 148835731357SCaroline Tice return false; 148935731357SCaroline Tice } 149035731357SCaroline Tice 149135731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 149235731357SCaroline Tice 149335731357SCaroline Tice if (!process_sp) 149435731357SCaroline Tice { 149535731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 149635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 149735731357SCaroline Tice return false; 149835731357SCaroline Tice } 149935731357SCaroline Tice 150035731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 150135731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 150235731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 150335731357SCaroline Tice 150435731357SCaroline Tice if (! m_options.stop.empty() 150510ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 150635731357SCaroline Tice { 150735731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 150835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 150935731357SCaroline Tice return false; 151035731357SCaroline Tice } 151135731357SCaroline Tice 151235731357SCaroline Tice if (! m_options.notify.empty() 151310ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 151435731357SCaroline Tice { 151535731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 151635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 151735731357SCaroline Tice return false; 151835731357SCaroline Tice } 151935731357SCaroline Tice 152035731357SCaroline Tice if (! m_options.pass.empty() 152110ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 152235731357SCaroline Tice { 152335731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 152435731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 152535731357SCaroline Tice return false; 152635731357SCaroline Tice } 152735731357SCaroline Tice 152835731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 152935731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 153035731357SCaroline Tice int num_signals_set = 0; 153135731357SCaroline Tice 153210ad7993SCaroline Tice if (num_args > 0) 153310ad7993SCaroline Tice { 153435731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 153535731357SCaroline Tice { 153635731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 153735731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 153835731357SCaroline Tice { 153910ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 154035731357SCaroline Tice // the value is either 0 or 1. 154135731357SCaroline Tice if (stop_action != -1) 154235731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 154335731357SCaroline Tice if (pass_action != -1) 154435731357SCaroline Tice { 154510ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 154610ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 154735731357SCaroline Tice } 154835731357SCaroline Tice if (notify_action != -1) 154935731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 155035731357SCaroline Tice ++num_signals_set; 155135731357SCaroline Tice } 155235731357SCaroline Tice else 155335731357SCaroline Tice { 155435731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 155535731357SCaroline Tice } 155635731357SCaroline Tice } 155710ad7993SCaroline Tice } 155810ad7993SCaroline Tice else 155910ad7993SCaroline Tice { 156010ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 156110ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 156210ad7993SCaroline Tice { 156310ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 156410ad7993SCaroline Tice { 156510ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 156610ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 156710ad7993SCaroline Tice { 156810ad7993SCaroline Tice if (notify_action != -1) 156910ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 157010ad7993SCaroline Tice if (stop_action != -1) 157110ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 157210ad7993SCaroline Tice if (pass_action != -1) 157310ad7993SCaroline Tice { 157410ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 157510ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 157610ad7993SCaroline Tice } 157710ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 157810ad7993SCaroline Tice } 157910ad7993SCaroline Tice } 158010ad7993SCaroline Tice } 158110ad7993SCaroline Tice } 158210ad7993SCaroline Tice 158310ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 158435731357SCaroline Tice 158535731357SCaroline Tice if (num_signals_set > 0) 158635731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 158735731357SCaroline Tice else 158835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 158935731357SCaroline Tice 159035731357SCaroline Tice return result.Succeeded(); 159135731357SCaroline Tice } 159235731357SCaroline Tice 159335731357SCaroline Tice protected: 159435731357SCaroline Tice 159535731357SCaroline Tice CommandOptions m_options; 159635731357SCaroline Tice }; 159735731357SCaroline Tice 159835731357SCaroline Tice lldb::OptionDefinition 159935731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 160035731357SCaroline Tice { 160135731357SCaroline Tice { 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." }, 160235731357SCaroline Tice { 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." }, 160335731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 160435731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 160535731357SCaroline Tice }; 160635731357SCaroline Tice 160735731357SCaroline Tice //------------------------------------------------------------------------- 160830fdc8d8SChris Lattner // CommandObjectMultiwordProcess 160930fdc8d8SChris Lattner //------------------------------------------------------------------------- 161030fdc8d8SChris Lattner 16116611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1612a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1613a7015092SGreg Clayton "process", 161430fdc8d8SChris Lattner "A set of commands for operating on a process.", 161530fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 161630fdc8d8SChris Lattner { 1617a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1618a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1619a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1620a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 16218f343b09SGreg Clayton LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 16228f343b09SGreg Clayton LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1623a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 162435731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1625a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1626a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1627a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 162830fdc8d8SChris Lattner } 162930fdc8d8SChris Lattner 163030fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 163130fdc8d8SChris Lattner { 163230fdc8d8SChris Lattner } 163330fdc8d8SChris Lattner 1634