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" 197260f620SGreg Clayton #include "lldb/Host/Host.h" 2030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 22e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2330fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2430fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2630fdc8d8SChris Lattner 2730fdc8d8SChris Lattner using namespace lldb; 2830fdc8d8SChris Lattner using namespace lldb_private; 2930fdc8d8SChris Lattner 3030fdc8d8SChris Lattner //------------------------------------------------------------------------- 3130fdc8d8SChris Lattner // CommandObjectProcessLaunch 3230fdc8d8SChris Lattner //------------------------------------------------------------------------- 334bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch 345a988416SJim Ingham class CommandObjectProcessLaunch : public CommandObjectParsed 3530fdc8d8SChris Lattner { 3630fdc8d8SChris Lattner public: 3730fdc8d8SChris Lattner 38a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 395a988416SJim Ingham CommandObjectParsed (interpreter, 40a7015092SGreg Clayton "process launch", 41e3d26315SCaroline Tice "Launch the executable in the debugger.", 42eb0103f2SGreg Clayton NULL), 43eb0103f2SGreg Clayton m_options (interpreter) 4430fdc8d8SChris Lattner { 45405fe67fSCaroline Tice CommandArgumentEntry arg; 46405fe67fSCaroline Tice CommandArgumentData run_args_arg; 47405fe67fSCaroline Tice 48405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 49405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 50405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 51405fe67fSCaroline Tice 52405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 53405fe67fSCaroline Tice arg.push_back (run_args_arg); 54405fe67fSCaroline Tice 55405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 56405fe67fSCaroline Tice m_arguments.push_back (arg); 5730fdc8d8SChris Lattner } 5830fdc8d8SChris Lattner 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 6130fdc8d8SChris Lattner { 6230fdc8d8SChris Lattner } 6330fdc8d8SChris Lattner 64*e9ce62b6SJim Ingham int 65*e9ce62b6SJim Ingham HandleArgumentCompletion (Args &input, 66*e9ce62b6SJim Ingham int &cursor_index, 67*e9ce62b6SJim Ingham int &cursor_char_position, 68*e9ce62b6SJim Ingham OptionElementVector &opt_element_vector, 69*e9ce62b6SJim Ingham int match_start_point, 70*e9ce62b6SJim Ingham int max_return_elements, 71*e9ce62b6SJim Ingham bool &word_complete, 72*e9ce62b6SJim Ingham StringList &matches) 73*e9ce62b6SJim Ingham { 74*e9ce62b6SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 75*e9ce62b6SJim Ingham completion_str.erase (cursor_char_position); 76*e9ce62b6SJim Ingham 77*e9ce62b6SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 78*e9ce62b6SJim Ingham CommandCompletions::eDiskFileCompletion, 79*e9ce62b6SJim Ingham completion_str.c_str(), 80*e9ce62b6SJim Ingham match_start_point, 81*e9ce62b6SJim Ingham max_return_elements, 82*e9ce62b6SJim Ingham NULL, 83*e9ce62b6SJim Ingham word_complete, 84*e9ce62b6SJim Ingham matches); 85*e9ce62b6SJim Ingham return matches.GetSize(); 86*e9ce62b6SJim Ingham } 87*e9ce62b6SJim Ingham 8830fdc8d8SChris Lattner Options * 8930fdc8d8SChris Lattner GetOptions () 9030fdc8d8SChris Lattner { 9130fdc8d8SChris Lattner return &m_options; 9230fdc8d8SChris Lattner } 9330fdc8d8SChris Lattner 945a988416SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 955a988416SJim Ingham { 965a988416SJim Ingham // No repeat for "process launch"... 975a988416SJim Ingham return ""; 985a988416SJim Ingham } 995a988416SJim Ingham 1005a988416SJim Ingham protected: 10130fdc8d8SChris Lattner bool 1025a988416SJim Ingham DoExecute (Args& launch_args, CommandReturnObject &result) 10330fdc8d8SChris Lattner { 1041d885966SGreg Clayton Debugger &debugger = m_interpreter.GetDebugger(); 1051d885966SGreg Clayton Target *target = debugger.GetSelectedTarget().get(); 1061d885966SGreg Clayton Error error; 10730fdc8d8SChris Lattner 10830fdc8d8SChris Lattner if (target == NULL) 10930fdc8d8SChris Lattner { 110effe5c95SGreg Clayton result.AppendError ("invalid target, create a debug target using the 'target create' command"); 11130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 11230fdc8d8SChris Lattner return false; 11330fdc8d8SChris Lattner } 11430fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 11530fdc8d8SChris Lattner char filename[PATH_MAX]; 116aa149cbdSGreg Clayton const Module *exe_module = target->GetExecutableModulePointer(); 11771337622SGreg Clayton 11871337622SGreg Clayton if (exe_module == NULL) 11971337622SGreg Clayton { 120effe5c95SGreg Clayton result.AppendError ("no file in target, create a debug target using the 'target create' command"); 12171337622SGreg Clayton result.SetStatus (eReturnStatusFailed); 12271337622SGreg Clayton return false; 12371337622SGreg Clayton } 12471337622SGreg Clayton 12530fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath (filename, sizeof(filename)); 12630fdc8d8SChris Lattner 127982c9762SGreg Clayton const bool add_exe_file_as_first_arg = true; 128ad9e828cSGreg Clayton m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), add_exe_file_as_first_arg); 129982c9762SGreg Clayton 13071337622SGreg Clayton StateType state = eStateInvalid; 131c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 13271337622SGreg Clayton if (process) 13371337622SGreg Clayton { 13471337622SGreg Clayton state = process->GetState(); 13571337622SGreg Clayton 13671337622SGreg Clayton if (process->IsAlive() && state != eStateConnected) 13730fdc8d8SChris Lattner { 138513c26ceSGreg Clayton char message[1024]; 139513c26ceSGreg Clayton if (process->GetState() == eStateAttaching) 140513c26ceSGreg Clayton ::strncpy (message, "There is a pending attach, abort it and launch a new process?", sizeof(message)); 141513c26ceSGreg Clayton else 142513c26ceSGreg Clayton ::strncpy (message, "There is a running process, kill it and restart?", sizeof(message)); 143513c26ceSGreg Clayton 144513c26ceSGreg Clayton if (!m_interpreter.Confirm (message, true)) 145bb9caf73SJim Ingham { 14630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 14730fdc8d8SChris Lattner return false; 14830fdc8d8SChris Lattner } 149bb9caf73SJim Ingham else 150bb9caf73SJim Ingham { 1511d885966SGreg Clayton Error destroy_error (process->Destroy()); 1521d885966SGreg Clayton if (destroy_error.Success()) 153bb9caf73SJim Ingham { 154bb9caf73SJim Ingham result.SetStatus (eReturnStatusSuccessFinishResult); 155bb9caf73SJim Ingham } 156bb9caf73SJim Ingham else 157bb9caf73SJim Ingham { 1581d885966SGreg Clayton result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString()); 159bb9caf73SJim Ingham result.SetStatus (eReturnStatusFailed); 160bb9caf73SJim Ingham } 161bb9caf73SJim Ingham } 162bb9caf73SJim Ingham } 16371337622SGreg Clayton } 16430fdc8d8SChris Lattner 165144f3a9cSGreg Clayton if (launch_args.GetArgumentCount() == 0) 166144f3a9cSGreg Clayton { 167144f3a9cSGreg Clayton const Args &process_args = target->GetRunArguments(); 168144f3a9cSGreg Clayton if (process_args.GetArgumentCount() > 0) 169144f3a9cSGreg Clayton m_options.launch_info.GetArguments().AppendArguments (process_args); 170144f3a9cSGreg Clayton } 171144f3a9cSGreg Clayton else 17230fdc8d8SChris Lattner { 173162b597cSGreg Clayton // Save the arguments for subsequent runs in the current target. 174162b597cSGreg Clayton target->SetRunArguments (launch_args); 175162b597cSGreg Clayton 176982c9762SGreg Clayton m_options.launch_info.GetArguments().AppendArguments (launch_args); 177982c9762SGreg Clayton } 1781d885966SGreg Clayton 179144f3a9cSGreg Clayton if (target->GetDisableASLR()) 180144f3a9cSGreg Clayton m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 181144f3a9cSGreg Clayton 182144f3a9cSGreg Clayton if (target->GetDisableSTDIO()) 183144f3a9cSGreg Clayton m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO); 184144f3a9cSGreg Clayton 185144f3a9cSGreg Clayton m_options.launch_info.GetFlags().Set (eLaunchFlagDebug); 186144f3a9cSGreg Clayton 187144f3a9cSGreg Clayton Args environment; 188144f3a9cSGreg Clayton target->GetEnvironmentAsArgs (environment); 189144f3a9cSGreg Clayton if (environment.GetArgumentCount() > 0) 190144f3a9cSGreg Clayton m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment); 191144f3a9cSGreg Clayton 192ee95ed50SGreg Clayton // Finalize the file actions, and if none were given, default to opening 193ee95ed50SGreg Clayton // up a pseudo terminal 194ee95ed50SGreg Clayton const bool default_to_use_pty = true; 195ee95ed50SGreg Clayton m_options.launch_info.FinalizeFileActions (target, default_to_use_pty); 1961d885966SGreg Clayton 1971d885966SGreg Clayton if (state == eStateConnected) 1981d885966SGreg Clayton { 1991d885966SGreg Clayton if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)) 2001d885966SGreg Clayton { 2011d885966SGreg Clayton result.AppendWarning("can't launch in tty when launching through a remote connection"); 2021d885966SGreg Clayton m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY); 2031d885966SGreg Clayton } 2041d885966SGreg Clayton } 205982c9762SGreg Clayton else 206982c9762SGreg Clayton { 207144f3a9cSGreg Clayton if (!m_options.launch_info.GetArchitecture().IsValid()) 208c9ed478aSGreg Clayton m_options.launch_info.GetArchitecture() = target->GetArchitecture(); 209c9ed478aSGreg Clayton 210c982b3d6SGreg Clayton PlatformSP platform_sp (target->GetPlatform()); 211c982b3d6SGreg Clayton 212c982b3d6SGreg Clayton if (platform_sp && platform_sp->CanDebugProcess ()) 213c982b3d6SGreg Clayton { 2141d885966SGreg Clayton process = target->GetPlatform()->DebugProcess (m_options.launch_info, 2151d885966SGreg Clayton debugger, 2161d885966SGreg Clayton target, 2171d885966SGreg Clayton debugger.GetListener(), 2181d885966SGreg Clayton error).get(); 219c982b3d6SGreg Clayton } 220c982b3d6SGreg Clayton else 221c982b3d6SGreg Clayton { 222c982b3d6SGreg Clayton const char *plugin_name = m_options.launch_info.GetProcessPluginName(); 223c3776bf2SGreg Clayton process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get(); 224c982b3d6SGreg Clayton if (process) 225c982b3d6SGreg Clayton error = process->Launch (m_options.launch_info); 226c982b3d6SGreg Clayton } 2271d885966SGreg Clayton 2281d885966SGreg Clayton if (process == NULL) 2291d885966SGreg Clayton { 230144f3a9cSGreg Clayton result.SetError (error, "failed to launch or debug process"); 2311d885966SGreg Clayton return false; 2321d885966SGreg Clayton } 2331d885966SGreg Clayton } 23430fdc8d8SChris Lattner 23530fdc8d8SChris Lattner if (error.Success()) 23630fdc8d8SChris Lattner { 23764195a2cSGreg Clayton const char *archname = exe_module->GetArchitecture().GetArchitectureName(); 23819388cfcSGreg Clayton 23981c22f61SGreg Clayton result.AppendMessageWithFormat ("Process %llu launched: '%s' (%s)\n", process->GetID(), filename, archname); 24005faeb71SGreg Clayton result.SetDidChangeProcessState (true); 241982c9762SGreg Clayton if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false) 24230fdc8d8SChris Lattner { 24305faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 24430fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 24530fdc8d8SChris Lattner 24630fdc8d8SChris Lattner if (state == eStateStopped) 24730fdc8d8SChris Lattner { 24805faeb71SGreg Clayton error = process->Resume(); 24905faeb71SGreg Clayton if (error.Success()) 25005faeb71SGreg Clayton { 25105faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 25230fdc8d8SChris Lattner if (synchronous_execution) 25330fdc8d8SChris Lattner { 25405faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 2552637f825SGreg Clayton const bool must_be_alive = true; 2562637f825SGreg Clayton if (!StateIsStoppedState(state, must_be_alive)) 257514487e8SGreg Clayton { 258144f3a9cSGreg Clayton result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state)); 259514487e8SGreg Clayton } 26030fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 26105faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 26205faeb71SGreg Clayton } 26305faeb71SGreg Clayton else 26405faeb71SGreg Clayton { 26505faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 26605faeb71SGreg Clayton } 26705faeb71SGreg Clayton } 268514487e8SGreg Clayton else 269514487e8SGreg Clayton { 270144f3a9cSGreg Clayton result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString()); 271514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 27230fdc8d8SChris Lattner } 27330fdc8d8SChris Lattner } 274514487e8SGreg Clayton else 275514487e8SGreg Clayton { 276144f3a9cSGreg Clayton result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state)); 277514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 278514487e8SGreg Clayton } 279514487e8SGreg Clayton } 280514487e8SGreg Clayton } 281514487e8SGreg Clayton else 282514487e8SGreg Clayton { 283197bacffSGreg Clayton result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString()); 284514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 28530fdc8d8SChris Lattner } 28630fdc8d8SChris Lattner 28730fdc8d8SChris Lattner return result.Succeeded(); 28830fdc8d8SChris Lattner } 28930fdc8d8SChris Lattner 29030fdc8d8SChris Lattner protected: 291982c9762SGreg Clayton ProcessLaunchCommandOptions m_options; 29230fdc8d8SChris Lattner }; 29330fdc8d8SChris Lattner 29430fdc8d8SChris Lattner 295982c9762SGreg Clayton //#define SET1 LLDB_OPT_SET_1 296982c9762SGreg Clayton //#define SET2 LLDB_OPT_SET_2 297982c9762SGreg Clayton //#define SET3 LLDB_OPT_SET_3 298982c9762SGreg Clayton // 299982c9762SGreg Clayton //OptionDefinition 300982c9762SGreg Clayton //CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 301982c9762SGreg Clayton //{ 302982c9762SGreg Clayton //{ 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."}, 303982c9762SGreg Clayton //{ SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 304982c9762SGreg Clayton //{ SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 305982c9762SGreg Clayton //{ SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 306982c9762SGreg Clayton //{ SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 307982c9762SGreg 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."}, 308982c9762SGreg Clayton //{ SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, 309982c9762SGreg Clayton //{ SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."}, 310982c9762SGreg Clayton //{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 311982c9762SGreg Clayton //}; 312982c9762SGreg Clayton // 313982c9762SGreg Clayton //#undef SET1 314982c9762SGreg Clayton //#undef SET2 315982c9762SGreg Clayton //#undef SET3 31630fdc8d8SChris Lattner 31730fdc8d8SChris Lattner //------------------------------------------------------------------------- 31830fdc8d8SChris Lattner // CommandObjectProcessAttach 31930fdc8d8SChris Lattner //------------------------------------------------------------------------- 320bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach 3215a988416SJim Ingham class CommandObjectProcessAttach : public CommandObjectParsed 32230fdc8d8SChris Lattner { 32330fdc8d8SChris Lattner public: 32430fdc8d8SChris Lattner 32530fdc8d8SChris Lattner class CommandOptions : public Options 32630fdc8d8SChris Lattner { 32730fdc8d8SChris Lattner public: 32830fdc8d8SChris Lattner 329eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 330eb0103f2SGreg Clayton Options(interpreter) 33130fdc8d8SChris Lattner { 332f6b8b581SGreg Clayton // Keep default values of all options in one place: OptionParsingStarting () 333f6b8b581SGreg Clayton OptionParsingStarting (); 33430fdc8d8SChris Lattner } 33530fdc8d8SChris Lattner 33630fdc8d8SChris Lattner ~CommandOptions () 33730fdc8d8SChris Lattner { 33830fdc8d8SChris Lattner } 33930fdc8d8SChris Lattner 34030fdc8d8SChris Lattner Error 341f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 34230fdc8d8SChris Lattner { 34330fdc8d8SChris Lattner Error error; 34430fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 34530fdc8d8SChris Lattner bool success = false; 34630fdc8d8SChris Lattner switch (short_option) 34730fdc8d8SChris Lattner { 348a95ce623SJohnny Chen case 'c': 349a95ce623SJohnny Chen attach_info.SetContinueOnceAttached(true); 350a95ce623SJohnny Chen break; 351a95ce623SJohnny Chen 35230fdc8d8SChris Lattner case 'p': 353144f3a9cSGreg Clayton { 354144f3a9cSGreg Clayton lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 35530fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 35630fdc8d8SChris Lattner { 35786edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg); 35830fdc8d8SChris Lattner } 359144f3a9cSGreg Clayton else 360144f3a9cSGreg Clayton { 361144f3a9cSGreg Clayton attach_info.SetProcessID (pid); 362144f3a9cSGreg Clayton } 363144f3a9cSGreg Clayton } 36430fdc8d8SChris Lattner break; 36530fdc8d8SChris Lattner 36630fdc8d8SChris Lattner case 'P': 367144f3a9cSGreg Clayton attach_info.SetProcessPluginName (option_arg); 36830fdc8d8SChris Lattner break; 36930fdc8d8SChris Lattner 37030fdc8d8SChris Lattner case 'n': 371144f3a9cSGreg Clayton attach_info.GetExecutableFile().SetFile(option_arg, false); 37230fdc8d8SChris Lattner break; 37330fdc8d8SChris Lattner 37430fdc8d8SChris Lattner case 'w': 375144f3a9cSGreg Clayton attach_info.SetWaitForLaunch(true); 37630fdc8d8SChris Lattner break; 37730fdc8d8SChris Lattner 378cd16df91SJim Ingham case 'i': 379cd16df91SJim Ingham attach_info.SetIgnoreExisting(false); 380cd16df91SJim Ingham break; 381cd16df91SJim Ingham 38230fdc8d8SChris Lattner default: 38386edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 38430fdc8d8SChris Lattner break; 38530fdc8d8SChris Lattner } 38630fdc8d8SChris Lattner return error; 38730fdc8d8SChris Lattner } 38830fdc8d8SChris Lattner 38930fdc8d8SChris Lattner void 390f6b8b581SGreg Clayton OptionParsingStarting () 39130fdc8d8SChris Lattner { 392144f3a9cSGreg Clayton attach_info.Clear(); 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner 395e0d378b3SGreg Clayton const OptionDefinition* 39630fdc8d8SChris Lattner GetDefinitions () 39730fdc8d8SChris Lattner { 39830fdc8d8SChris Lattner return g_option_table; 39930fdc8d8SChris Lattner } 40030fdc8d8SChris Lattner 4015aee162fSJim Ingham virtual bool 402eb0103f2SGreg Clayton HandleOptionArgumentCompletion (Args &input, 4035aee162fSJim Ingham int cursor_index, 4045aee162fSJim Ingham int char_pos, 4055aee162fSJim Ingham OptionElementVector &opt_element_vector, 4065aee162fSJim Ingham int opt_element_index, 4075aee162fSJim Ingham int match_start_point, 4085aee162fSJim Ingham int max_return_elements, 4095aee162fSJim Ingham bool &word_complete, 4105aee162fSJim Ingham StringList &matches) 4115aee162fSJim Ingham { 4125aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4135aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4145aee162fSJim Ingham 4155aee162fSJim Ingham // We are only completing the name option for now... 4165aee162fSJim Ingham 417e0d378b3SGreg Clayton const OptionDefinition *opt_defs = GetDefinitions(); 4185aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4195aee162fSJim Ingham { 4205aee162fSJim Ingham // Are we in the name? 4215aee162fSJim Ingham 4225aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4235aee162fSJim Ingham // use the default plugin. 4245aee162fSJim Ingham 4255aee162fSJim Ingham const char *partial_name = NULL; 4265aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4275aee162fSJim Ingham 4288b82f087SGreg Clayton PlatformSP platform_sp (m_interpreter.GetPlatform (true)); 429e996fd30SGreg Clayton if (platform_sp) 4305aee162fSJim Ingham { 4318b82f087SGreg Clayton ProcessInstanceInfoList process_infos; 4328b82f087SGreg Clayton ProcessInstanceInfoMatch match_info; 43332e0a750SGreg Clayton if (partial_name) 43432e0a750SGreg Clayton { 435144f3a9cSGreg Clayton match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false); 43632e0a750SGreg Clayton match_info.SetNameMatchType(eNameMatchStartsWith); 43732e0a750SGreg Clayton } 43832e0a750SGreg Clayton platform_sp->FindProcesses (match_info, process_infos); 439e996fd30SGreg Clayton const uint32_t num_matches = process_infos.GetSize(); 440e996fd30SGreg Clayton if (num_matches > 0) 441e996fd30SGreg Clayton { 442e996fd30SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 443e996fd30SGreg Clayton { 444e996fd30SGreg Clayton matches.AppendString (process_infos.GetProcessNameAtIndex(i), 445e996fd30SGreg Clayton process_infos.GetProcessNameLengthAtIndex(i)); 4465aee162fSJim Ingham } 4475aee162fSJim Ingham } 4485aee162fSJim Ingham } 4495aee162fSJim Ingham } 4505aee162fSJim Ingham 4515aee162fSJim Ingham return false; 4525aee162fSJim Ingham } 4535aee162fSJim Ingham 45430fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 45530fdc8d8SChris Lattner 456e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 45730fdc8d8SChris Lattner 45830fdc8d8SChris Lattner // Instance variables to hold the values for command options. 45930fdc8d8SChris Lattner 460144f3a9cSGreg Clayton ProcessAttachInfo attach_info; 46130fdc8d8SChris Lattner }; 46230fdc8d8SChris Lattner 463a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 4645a988416SJim Ingham CommandObjectParsed (interpreter, 465a7015092SGreg Clayton "process attach", 466e3d26315SCaroline Tice "Attach to a process.", 467eb0103f2SGreg Clayton "process attach <cmd-options>"), 468eb0103f2SGreg Clayton m_options (interpreter) 4695aee162fSJim Ingham { 4705aee162fSJim Ingham } 4715aee162fSJim Ingham 4725aee162fSJim Ingham ~CommandObjectProcessAttach () 4735aee162fSJim Ingham { 4745aee162fSJim Ingham } 4755aee162fSJim Ingham 4765a988416SJim Ingham Options * 4775a988416SJim Ingham GetOptions () 4785a988416SJim Ingham { 4795a988416SJim Ingham return &m_options; 4805a988416SJim Ingham } 4815a988416SJim Ingham 4825a988416SJim Ingham protected: 4835aee162fSJim Ingham bool 4845a988416SJim Ingham DoExecute (Args& command, 4855aee162fSJim Ingham CommandReturnObject &result) 4865aee162fSJim Ingham { 487a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 48831412642SJim Ingham // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach 48931412642SJim Ingham // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop 49031412642SJim Ingham // ourselves here. 4915aee162fSJim Ingham 492c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 49371337622SGreg Clayton StateType state = eStateInvalid; 4945aee162fSJim Ingham if (process) 4955aee162fSJim Ingham { 49671337622SGreg Clayton state = process->GetState(); 49771337622SGreg Clayton if (process->IsAlive() && state != eStateConnected) 4985aee162fSJim Ingham { 49981c22f61SGreg Clayton result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before attaching.\n", 5005aee162fSJim Ingham process->GetID()); 5015aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5025aee162fSJim Ingham return false; 5035aee162fSJim Ingham } 5045aee162fSJim Ingham } 5055aee162fSJim Ingham 5065aee162fSJim Ingham if (target == NULL) 5075aee162fSJim Ingham { 5085aee162fSJim Ingham // If there isn't a current target create one. 5095aee162fSJim Ingham TargetSP new_target_sp; 5105aee162fSJim Ingham FileSpec emptyFileSpec; 5115aee162fSJim Ingham Error error; 5125aee162fSJim Ingham 513a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 5145aee162fSJim Ingham emptyFileSpec, 515cac9c5f9SGreg Clayton NULL, 5165aee162fSJim Ingham false, 517cac9c5f9SGreg Clayton NULL, // No platform options 5185aee162fSJim Ingham new_target_sp); 5195aee162fSJim Ingham target = new_target_sp.get(); 5205aee162fSJim Ingham if (target == NULL || error.Fail()) 5215aee162fSJim Ingham { 522b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 5235aee162fSJim Ingham return false; 5245aee162fSJim Ingham } 525a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5265aee162fSJim Ingham } 5275aee162fSJim Ingham 5285aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5295aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5305aee162fSJim Ingham 5315aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5325aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5335aee162fSJim Ingham 5345aee162fSJim Ingham if (command.GetArgumentCount()) 5355aee162fSJim Ingham { 536fd54b368SJason Molenda result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5375aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5385aee162fSJim Ingham } 5395aee162fSJim Ingham else 5405aee162fSJim Ingham { 54171337622SGreg Clayton if (state != eStateConnected) 54271337622SGreg Clayton { 543144f3a9cSGreg Clayton const char *plugin_name = m_options.attach_info.GetProcessPluginName(); 544c3776bf2SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get(); 54571337622SGreg Clayton } 5465aee162fSJim Ingham 5475aee162fSJim Ingham if (process) 5485aee162fSJim Ingham { 5495aee162fSJim Ingham Error error; 550144f3a9cSGreg Clayton // If no process info was specified, then use the target executable 551144f3a9cSGreg Clayton // name as the process to attach to by default 552144f3a9cSGreg Clayton if (!m_options.attach_info.ProcessInfoSpecified ()) 5535aee162fSJim Ingham { 5543a0b9cdfSJim Ingham if (old_exec_module_sp) 555ad9e828cSGreg Clayton m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename(); 556144f3a9cSGreg Clayton 557144f3a9cSGreg Clayton if (!m_options.attach_info.ProcessInfoSpecified ()) 5583a0b9cdfSJim Ingham { 559144f3a9cSGreg Clayton error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option"); 5603a0b9cdfSJim Ingham } 5615aee162fSJim Ingham } 5623a0b9cdfSJim Ingham 563144f3a9cSGreg Clayton if (error.Success()) 5643a0b9cdfSJim Ingham { 565144f3a9cSGreg Clayton error = process->Attach (m_options.attach_info); 5663a0b9cdfSJim Ingham 5675aee162fSJim Ingham if (error.Success()) 5685aee162fSJim Ingham { 5695aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 5705aee162fSJim Ingham } 5715aee162fSJim Ingham else 5725aee162fSJim Ingham { 573144f3a9cSGreg Clayton result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString()); 5745aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5755aee162fSJim Ingham return false; 5765aee162fSJim Ingham } 577bb3a283bSJim Ingham // If we're synchronous, wait for the stopped event and report that. 578bb3a283bSJim Ingham // Otherwise just return. 579bb3a283bSJim Ingham // FIXME: in the async case it will now be possible to get to the command 580bb3a283bSJim Ingham // interpreter with a state eStateAttaching. Make sure we handle that correctly. 581bb3a283bSJim Ingham StateType state = process->WaitForProcessToStop (NULL); 582bb3a283bSJim Ingham 583bb3a283bSJim Ingham result.SetDidChangeProcessState (true); 584aa739093SJohnny Chen 585aa739093SJohnny Chen if (state == eStateStopped) 586aa739093SJohnny Chen { 58781c22f61SGreg Clayton result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 588bb3a283bSJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 589bb3a283bSJim Ingham } 590aa739093SJohnny Chen else 591aa739093SJohnny Chen { 592aa739093SJohnny Chen result.AppendError ("attach failed: process did not stop (no such process or permission problem?)"); 593cfc0935eSJim Ingham process->Destroy(); 594aa739093SJohnny Chen result.SetStatus (eReturnStatusFailed); 595aa739093SJohnny Chen return false; 596aa739093SJohnny Chen } 597aa739093SJohnny Chen } 5985aee162fSJim Ingham } 5995aee162fSJim Ingham } 6005aee162fSJim Ingham 6015aee162fSJim Ingham if (result.Succeeded()) 6025aee162fSJim Ingham { 6035aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 604513c26ceSGreg Clayton char new_path[PATH_MAX]; 605aa149cbdSGreg Clayton ModuleSP new_exec_module_sp (target->GetExecutableModule()); 6065aee162fSJim Ingham if (!old_exec_module_sp) 6075aee162fSJim Ingham { 608513c26ceSGreg Clayton // We might not have a module if we attached to a raw pid... 609aa149cbdSGreg Clayton if (new_exec_module_sp) 610513c26ceSGreg Clayton { 611aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 612513c26ceSGreg Clayton result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path); 613513c26ceSGreg Clayton } 6145aee162fSJim Ingham } 615aa149cbdSGreg Clayton else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec()) 6165aee162fSJim Ingham { 617513c26ceSGreg Clayton char old_path[PATH_MAX]; 6185aee162fSJim Ingham 6195aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX); 620aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX); 6215aee162fSJim Ingham 6225aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6235aee162fSJim Ingham old_path, new_path); 6245aee162fSJim Ingham } 6255aee162fSJim Ingham 6265aee162fSJim Ingham if (!old_arch_spec.IsValid()) 6275aee162fSJim Ingham { 62864195a2cSGreg Clayton result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetArchitectureName()); 6295aee162fSJim Ingham } 6305aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 6315aee162fSJim Ingham { 6325aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 63364195a2cSGreg Clayton old_arch_spec.GetArchitectureName(), target->GetArchitecture().GetArchitectureName()); 6345aee162fSJim Ingham } 635a95ce623SJohnny Chen 636a95ce623SJohnny Chen // This supports the use-case scenario of immediately continuing the process once attached. 637a95ce623SJohnny Chen if (m_options.attach_info.GetContinueOnceAttached()) 6385bcaf583SSean Callanan m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); 6395aee162fSJim Ingham } 6405aee162fSJim Ingham return result.Succeeded(); 6415aee162fSJim Ingham } 6425aee162fSJim Ingham 64330fdc8d8SChris Lattner CommandOptions m_options; 64430fdc8d8SChris Lattner }; 64530fdc8d8SChris Lattner 64630fdc8d8SChris Lattner 647e0d378b3SGreg Clayton OptionDefinition 64830fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 64930fdc8d8SChris Lattner { 650a95ce623SJohnny Chen { LLDB_OPT_SET_ALL, false, "continue",'c', no_argument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, 651deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 652deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 653deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 654cd16df91SJim Ingham { LLDB_OPT_SET_2, false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, 6554ce37abbSJohnny Chen { LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."}, 656deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 65730fdc8d8SChris Lattner }; 65830fdc8d8SChris Lattner 65930fdc8d8SChris Lattner //------------------------------------------------------------------------- 66030fdc8d8SChris Lattner // CommandObjectProcessContinue 66130fdc8d8SChris Lattner //------------------------------------------------------------------------- 662bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue 66330fdc8d8SChris Lattner 6645a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed 66530fdc8d8SChris Lattner { 66630fdc8d8SChris Lattner public: 66730fdc8d8SChris Lattner 668a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 6695a988416SJim Ingham CommandObjectParsed (interpreter, 670a7015092SGreg Clayton "process continue", 671e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 67230fdc8d8SChris Lattner "process continue", 67330fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 67430fdc8d8SChris Lattner { 67530fdc8d8SChris Lattner } 67630fdc8d8SChris Lattner 67730fdc8d8SChris Lattner 67830fdc8d8SChris Lattner ~CommandObjectProcessContinue () 67930fdc8d8SChris Lattner { 68030fdc8d8SChris Lattner } 68130fdc8d8SChris Lattner 6825a988416SJim Ingham protected: 68330fdc8d8SChris Lattner bool 6845a988416SJim Ingham DoExecute (Args& command, 68530fdc8d8SChris Lattner CommandReturnObject &result) 68630fdc8d8SChris Lattner { 687c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 688a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 68930fdc8d8SChris Lattner 69030fdc8d8SChris Lattner if (process == NULL) 69130fdc8d8SChris Lattner { 69230fdc8d8SChris Lattner result.AppendError ("no process to continue"); 69330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 69430fdc8d8SChris Lattner return false; 69530fdc8d8SChris Lattner } 69630fdc8d8SChris Lattner 69730fdc8d8SChris Lattner StateType state = process->GetState(); 69830fdc8d8SChris Lattner if (state == eStateStopped) 69930fdc8d8SChris Lattner { 70030fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 70130fdc8d8SChris Lattner { 70230fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 70330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 70430fdc8d8SChris Lattner return false; 70530fdc8d8SChris Lattner } 70630fdc8d8SChris Lattner 70730fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 70830fdc8d8SChris Lattner 70930fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 71030fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 71130fdc8d8SChris Lattner { 71230fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 71330fdc8d8SChris Lattner } 71430fdc8d8SChris Lattner 71530fdc8d8SChris Lattner Error error(process->Resume()); 71630fdc8d8SChris Lattner if (error.Success()) 71730fdc8d8SChris Lattner { 71881c22f61SGreg Clayton result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID()); 71930fdc8d8SChris Lattner if (synchronous_execution) 72030fdc8d8SChris Lattner { 721b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 72230fdc8d8SChris Lattner 72330fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 72481c22f61SGreg Clayton result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state)); 72530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 72630fdc8d8SChris Lattner } 72730fdc8d8SChris Lattner else 72830fdc8d8SChris Lattner { 72930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 73030fdc8d8SChris Lattner } 73130fdc8d8SChris Lattner } 73230fdc8d8SChris Lattner else 73330fdc8d8SChris Lattner { 73430fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 73530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 73630fdc8d8SChris Lattner } 73730fdc8d8SChris Lattner } 73830fdc8d8SChris Lattner else 73930fdc8d8SChris Lattner { 74030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 74130fdc8d8SChris Lattner StateAsCString(state)); 74230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 74330fdc8d8SChris Lattner } 74430fdc8d8SChris Lattner return result.Succeeded(); 74530fdc8d8SChris Lattner } 74630fdc8d8SChris Lattner }; 74730fdc8d8SChris Lattner 74830fdc8d8SChris Lattner //------------------------------------------------------------------------- 74930fdc8d8SChris Lattner // CommandObjectProcessDetach 75030fdc8d8SChris Lattner //------------------------------------------------------------------------- 751bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach 75230fdc8d8SChris Lattner 7535a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed 75430fdc8d8SChris Lattner { 75530fdc8d8SChris Lattner public: 75630fdc8d8SChris Lattner 757a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 7585a988416SJim Ingham CommandObjectParsed (interpreter, 759a7015092SGreg Clayton "process detach", 760e3d26315SCaroline Tice "Detach from the current process being debugged.", 76130fdc8d8SChris Lattner "process detach", 76230fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 76330fdc8d8SChris Lattner { 76430fdc8d8SChris Lattner } 76530fdc8d8SChris Lattner 76630fdc8d8SChris Lattner ~CommandObjectProcessDetach () 76730fdc8d8SChris Lattner { 76830fdc8d8SChris Lattner } 76930fdc8d8SChris Lattner 7705a988416SJim Ingham protected: 77130fdc8d8SChris Lattner bool 7725a988416SJim Ingham DoExecute (Args& command, 77330fdc8d8SChris Lattner CommandReturnObject &result) 77430fdc8d8SChris Lattner { 775c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 77630fdc8d8SChris Lattner if (process == NULL) 77730fdc8d8SChris Lattner { 77830fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 77930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78030fdc8d8SChris Lattner return false; 78130fdc8d8SChris Lattner } 78230fdc8d8SChris Lattner 78381c22f61SGreg Clayton result.AppendMessageWithFormat ("Detaching from process %llu\n", process->GetID()); 78430fdc8d8SChris Lattner Error error (process->Detach()); 78530fdc8d8SChris Lattner if (error.Success()) 78630fdc8d8SChris Lattner { 78730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 78830fdc8d8SChris Lattner } 78930fdc8d8SChris Lattner else 79030fdc8d8SChris Lattner { 79130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 79230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 79330fdc8d8SChris Lattner return false; 79430fdc8d8SChris Lattner } 79530fdc8d8SChris Lattner return result.Succeeded(); 79630fdc8d8SChris Lattner } 79730fdc8d8SChris Lattner }; 79830fdc8d8SChris Lattner 79930fdc8d8SChris Lattner //------------------------------------------------------------------------- 800b766a73dSGreg Clayton // CommandObjectProcessConnect 801b766a73dSGreg Clayton //------------------------------------------------------------------------- 802b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect 803b766a73dSGreg Clayton 8045a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed 805b766a73dSGreg Clayton { 806b766a73dSGreg Clayton public: 807b766a73dSGreg Clayton 808b766a73dSGreg Clayton class CommandOptions : public Options 809b766a73dSGreg Clayton { 810b766a73dSGreg Clayton public: 811b766a73dSGreg Clayton 812eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 813eb0103f2SGreg Clayton Options(interpreter) 814b766a73dSGreg Clayton { 815f6b8b581SGreg Clayton // Keep default values of all options in one place: OptionParsingStarting () 816f6b8b581SGreg Clayton OptionParsingStarting (); 817b766a73dSGreg Clayton } 818b766a73dSGreg Clayton 819b766a73dSGreg Clayton ~CommandOptions () 820b766a73dSGreg Clayton { 821b766a73dSGreg Clayton } 822b766a73dSGreg Clayton 823b766a73dSGreg Clayton Error 824f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 825b766a73dSGreg Clayton { 826b766a73dSGreg Clayton Error error; 827b766a73dSGreg Clayton char short_option = (char) m_getopt_table[option_idx].val; 828b766a73dSGreg Clayton 829b766a73dSGreg Clayton switch (short_option) 830b766a73dSGreg Clayton { 831b766a73dSGreg Clayton case 'p': 832b766a73dSGreg Clayton plugin_name.assign (option_arg); 833b766a73dSGreg Clayton break; 834b766a73dSGreg Clayton 835b766a73dSGreg Clayton default: 83686edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 837b766a73dSGreg Clayton break; 838b766a73dSGreg Clayton } 839b766a73dSGreg Clayton return error; 840b766a73dSGreg Clayton } 841b766a73dSGreg Clayton 842b766a73dSGreg Clayton void 843f6b8b581SGreg Clayton OptionParsingStarting () 844b766a73dSGreg Clayton { 845b766a73dSGreg Clayton plugin_name.clear(); 846b766a73dSGreg Clayton } 847b766a73dSGreg Clayton 848e0d378b3SGreg Clayton const OptionDefinition* 849b766a73dSGreg Clayton GetDefinitions () 850b766a73dSGreg Clayton { 851b766a73dSGreg Clayton return g_option_table; 852b766a73dSGreg Clayton } 853b766a73dSGreg Clayton 854b766a73dSGreg Clayton // Options table: Required for subclasses of Options. 855b766a73dSGreg Clayton 856e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 857b766a73dSGreg Clayton 858b766a73dSGreg Clayton // Instance variables to hold the values for command options. 859b766a73dSGreg Clayton 860b766a73dSGreg Clayton std::string plugin_name; 861b766a73dSGreg Clayton }; 862b766a73dSGreg Clayton 863b766a73dSGreg Clayton CommandObjectProcessConnect (CommandInterpreter &interpreter) : 8645a988416SJim Ingham CommandObjectParsed (interpreter, 865b766a73dSGreg Clayton "process connect", 866b766a73dSGreg Clayton "Connect to a remote debug service.", 867b766a73dSGreg Clayton "process connect <remote-url>", 868eb0103f2SGreg Clayton 0), 869eb0103f2SGreg Clayton m_options (interpreter) 870b766a73dSGreg Clayton { 871b766a73dSGreg Clayton } 872b766a73dSGreg Clayton 873b766a73dSGreg Clayton ~CommandObjectProcessConnect () 874b766a73dSGreg Clayton { 875b766a73dSGreg Clayton } 876b766a73dSGreg Clayton 877b766a73dSGreg Clayton 8785a988416SJim Ingham Options * 8795a988416SJim Ingham GetOptions () 8805a988416SJim Ingham { 8815a988416SJim Ingham return &m_options; 8825a988416SJim Ingham } 8835a988416SJim Ingham 8845a988416SJim Ingham protected: 885b766a73dSGreg Clayton bool 8865a988416SJim Ingham DoExecute (Args& command, 887b766a73dSGreg Clayton CommandReturnObject &result) 888b766a73dSGreg Clayton { 889b766a73dSGreg Clayton 890b766a73dSGreg Clayton TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget()); 891b766a73dSGreg Clayton Error error; 892c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 893b766a73dSGreg Clayton if (process) 894b766a73dSGreg Clayton { 895b766a73dSGreg Clayton if (process->IsAlive()) 896b766a73dSGreg Clayton { 89781c22f61SGreg Clayton result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before connecting.\n", 898b766a73dSGreg Clayton process->GetID()); 899b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 900b766a73dSGreg Clayton return false; 901b766a73dSGreg Clayton } 902b766a73dSGreg Clayton } 903b766a73dSGreg Clayton 904b766a73dSGreg Clayton if (!target_sp) 905b766a73dSGreg Clayton { 906b766a73dSGreg Clayton // If there isn't a current target create one. 907b766a73dSGreg Clayton FileSpec emptyFileSpec; 908b766a73dSGreg Clayton 909b766a73dSGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 910b766a73dSGreg Clayton emptyFileSpec, 911cac9c5f9SGreg Clayton NULL, 912b766a73dSGreg Clayton false, 913cac9c5f9SGreg Clayton NULL, // No platform options 914b766a73dSGreg Clayton target_sp); 915b766a73dSGreg Clayton if (!target_sp || error.Fail()) 916b766a73dSGreg Clayton { 917b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 918b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 919b766a73dSGreg Clayton return false; 920b766a73dSGreg Clayton } 921b766a73dSGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get()); 922b766a73dSGreg Clayton } 923b766a73dSGreg Clayton 924b766a73dSGreg Clayton if (command.GetArgumentCount() == 1) 925b766a73dSGreg Clayton { 926b766a73dSGreg Clayton const char *plugin_name = NULL; 927b766a73dSGreg Clayton if (!m_options.plugin_name.empty()) 928b766a73dSGreg Clayton plugin_name = m_options.plugin_name.c_str(); 929b766a73dSGreg Clayton 930b766a73dSGreg Clayton const char *remote_url = command.GetArgumentAtIndex(0); 931c3776bf2SGreg Clayton process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get(); 932b766a73dSGreg Clayton 933b766a73dSGreg Clayton if (process) 934b766a73dSGreg Clayton { 935b766a73dSGreg Clayton error = process->ConnectRemote (remote_url); 936b766a73dSGreg Clayton 937b766a73dSGreg Clayton if (error.Fail()) 938b766a73dSGreg Clayton { 939b766a73dSGreg Clayton result.AppendError(error.AsCString("Remote connect failed")); 940b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 9411517dd33SGreg Clayton target_sp->DeleteCurrentProcess(); 942b766a73dSGreg Clayton return false; 943b766a73dSGreg Clayton } 944b766a73dSGreg Clayton } 945b766a73dSGreg Clayton else 946b766a73dSGreg Clayton { 947fd54b368SJason Molenda 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", 948fd54b368SJason Molenda m_cmd_name.c_str()); 949b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 950b766a73dSGreg Clayton } 951b766a73dSGreg Clayton } 952b766a73dSGreg Clayton else 953b766a73dSGreg Clayton { 954fd54b368SJason Molenda result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n", 955b766a73dSGreg Clayton m_cmd_name.c_str(), 956b766a73dSGreg Clayton m_cmd_syntax.c_str()); 957b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 958b766a73dSGreg Clayton } 959b766a73dSGreg Clayton return result.Succeeded(); 960b766a73dSGreg Clayton } 961b766a73dSGreg Clayton 962b766a73dSGreg Clayton CommandOptions m_options; 963b766a73dSGreg Clayton }; 964b766a73dSGreg Clayton 965b766a73dSGreg Clayton 966e0d378b3SGreg Clayton OptionDefinition 967b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] = 968b766a73dSGreg Clayton { 969b766a73dSGreg Clayton { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 970b766a73dSGreg Clayton { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 971b766a73dSGreg Clayton }; 972b766a73dSGreg Clayton 973b766a73dSGreg Clayton //------------------------------------------------------------------------- 9748f343b09SGreg Clayton // CommandObjectProcessLoad 9758f343b09SGreg Clayton //------------------------------------------------------------------------- 976bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad 9778f343b09SGreg Clayton 9785a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed 9798f343b09SGreg Clayton { 9808f343b09SGreg Clayton public: 9818f343b09SGreg Clayton 9828f343b09SGreg Clayton CommandObjectProcessLoad (CommandInterpreter &interpreter) : 9835a988416SJim Ingham CommandObjectParsed (interpreter, 9848f343b09SGreg Clayton "process load", 9858f343b09SGreg Clayton "Load a shared library into the current process.", 9868f343b09SGreg Clayton "process load <filename> [<filename> ...]", 9878f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 9888f343b09SGreg Clayton { 9898f343b09SGreg Clayton } 9908f343b09SGreg Clayton 9918f343b09SGreg Clayton ~CommandObjectProcessLoad () 9928f343b09SGreg Clayton { 9938f343b09SGreg Clayton } 9948f343b09SGreg Clayton 9955a988416SJim Ingham protected: 9968f343b09SGreg Clayton bool 9975a988416SJim Ingham DoExecute (Args& command, 9988f343b09SGreg Clayton CommandReturnObject &result) 9998f343b09SGreg Clayton { 1000c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 10018f343b09SGreg Clayton if (process == NULL) 10028f343b09SGreg Clayton { 10038f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 10048f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 10058f343b09SGreg Clayton return false; 10068f343b09SGreg Clayton } 10078f343b09SGreg Clayton 10088f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 10098f343b09SGreg Clayton 10108f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 10118f343b09SGreg Clayton { 10128f343b09SGreg Clayton Error error; 10138f343b09SGreg Clayton const char *image_path = command.GetArgumentAtIndex(i); 10148f343b09SGreg Clayton FileSpec image_spec (image_path, false); 1015aa516843SGreg Clayton process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec); 10168f343b09SGreg Clayton uint32_t image_token = process->LoadImage(image_spec, error); 10178f343b09SGreg Clayton if (image_token != LLDB_INVALID_IMAGE_TOKEN) 10188f343b09SGreg Clayton { 10198f343b09SGreg Clayton result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 10208f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 10218f343b09SGreg Clayton } 10228f343b09SGreg Clayton else 10238f343b09SGreg Clayton { 10248f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 10258f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 10268f343b09SGreg Clayton } 10278f343b09SGreg Clayton } 10288f343b09SGreg Clayton return result.Succeeded(); 10298f343b09SGreg Clayton } 10308f343b09SGreg Clayton }; 10318f343b09SGreg Clayton 10328f343b09SGreg Clayton 10338f343b09SGreg Clayton //------------------------------------------------------------------------- 10348f343b09SGreg Clayton // CommandObjectProcessUnload 10358f343b09SGreg Clayton //------------------------------------------------------------------------- 1036bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload 10378f343b09SGreg Clayton 10385a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed 10398f343b09SGreg Clayton { 10408f343b09SGreg Clayton public: 10418f343b09SGreg Clayton 10428f343b09SGreg Clayton CommandObjectProcessUnload (CommandInterpreter &interpreter) : 10435a988416SJim Ingham CommandObjectParsed (interpreter, 10448f343b09SGreg Clayton "process unload", 10458f343b09SGreg Clayton "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 10468f343b09SGreg Clayton "process unload <index>", 10478f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 10488f343b09SGreg Clayton { 10498f343b09SGreg Clayton } 10508f343b09SGreg Clayton 10518f343b09SGreg Clayton ~CommandObjectProcessUnload () 10528f343b09SGreg Clayton { 10538f343b09SGreg Clayton } 10548f343b09SGreg Clayton 10555a988416SJim Ingham protected: 10568f343b09SGreg Clayton bool 10575a988416SJim Ingham DoExecute (Args& command, 10588f343b09SGreg Clayton CommandReturnObject &result) 10598f343b09SGreg Clayton { 1060c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 10618f343b09SGreg Clayton if (process == NULL) 10628f343b09SGreg Clayton { 10638f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 10648f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 10658f343b09SGreg Clayton return false; 10668f343b09SGreg Clayton } 10678f343b09SGreg Clayton 10688f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 10698f343b09SGreg Clayton 10708f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 10718f343b09SGreg Clayton { 10728f343b09SGreg Clayton const char *image_token_cstr = command.GetArgumentAtIndex(i); 10738f343b09SGreg Clayton uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 10748f343b09SGreg Clayton if (image_token == LLDB_INVALID_IMAGE_TOKEN) 10758f343b09SGreg Clayton { 10768f343b09SGreg Clayton result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 10778f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 10788f343b09SGreg Clayton break; 10798f343b09SGreg Clayton } 10808f343b09SGreg Clayton else 10818f343b09SGreg Clayton { 10828f343b09SGreg Clayton Error error (process->UnloadImage(image_token)); 10838f343b09SGreg Clayton if (error.Success()) 10848f343b09SGreg Clayton { 10858f343b09SGreg Clayton result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 10868f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 10878f343b09SGreg Clayton } 10888f343b09SGreg Clayton else 10898f343b09SGreg Clayton { 10908f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 10918f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 10928f343b09SGreg Clayton break; 10938f343b09SGreg Clayton } 10948f343b09SGreg Clayton } 10958f343b09SGreg Clayton } 10968f343b09SGreg Clayton return result.Succeeded(); 10978f343b09SGreg Clayton } 10988f343b09SGreg Clayton }; 10998f343b09SGreg Clayton 11008f343b09SGreg Clayton //------------------------------------------------------------------------- 110130fdc8d8SChris Lattner // CommandObjectProcessSignal 110230fdc8d8SChris Lattner //------------------------------------------------------------------------- 1103bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal 110430fdc8d8SChris Lattner 11055a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed 110630fdc8d8SChris Lattner { 110730fdc8d8SChris Lattner public: 110830fdc8d8SChris Lattner 1109a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 11105a988416SJim Ingham CommandObjectParsed (interpreter, 1111a7015092SGreg Clayton "process signal", 1112e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 1113405fe67fSCaroline Tice NULL) 111430fdc8d8SChris Lattner { 1115405fe67fSCaroline Tice CommandArgumentEntry arg; 1116405fe67fSCaroline Tice CommandArgumentData signal_arg; 1117405fe67fSCaroline Tice 1118405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 1119c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1120405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 1121405fe67fSCaroline Tice 1122405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 1123405fe67fSCaroline Tice arg.push_back (signal_arg); 1124405fe67fSCaroline Tice 1125405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1126405fe67fSCaroline Tice m_arguments.push_back (arg); 112730fdc8d8SChris Lattner } 112830fdc8d8SChris Lattner 112930fdc8d8SChris Lattner ~CommandObjectProcessSignal () 113030fdc8d8SChris Lattner { 113130fdc8d8SChris Lattner } 113230fdc8d8SChris Lattner 11335a988416SJim Ingham protected: 113430fdc8d8SChris Lattner bool 11355a988416SJim Ingham DoExecute (Args& command, 113630fdc8d8SChris Lattner CommandReturnObject &result) 113730fdc8d8SChris Lattner { 1138c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 113930fdc8d8SChris Lattner if (process == NULL) 114030fdc8d8SChris Lattner { 114130fdc8d8SChris Lattner result.AppendError ("no process to signal"); 114230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 114330fdc8d8SChris Lattner return false; 114430fdc8d8SChris Lattner } 114530fdc8d8SChris Lattner 114630fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 114730fdc8d8SChris Lattner { 1148237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1149237cd906SGreg Clayton 1150237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1151237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 1152237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1153237cd906SGreg Clayton else 1154237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 1155237cd906SGreg Clayton 1156237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 115730fdc8d8SChris Lattner { 115830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 115930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 116030fdc8d8SChris Lattner } 116130fdc8d8SChris Lattner else 116230fdc8d8SChris Lattner { 116330fdc8d8SChris Lattner Error error (process->Signal (signo)); 116430fdc8d8SChris Lattner if (error.Success()) 116530fdc8d8SChris Lattner { 116630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 116730fdc8d8SChris Lattner } 116830fdc8d8SChris Lattner else 116930fdc8d8SChris Lattner { 117030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 117130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 117230fdc8d8SChris Lattner } 117330fdc8d8SChris Lattner } 117430fdc8d8SChris Lattner } 117530fdc8d8SChris Lattner else 117630fdc8d8SChris Lattner { 1177fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(), 117830fdc8d8SChris Lattner m_cmd_syntax.c_str()); 117930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 118030fdc8d8SChris Lattner } 118130fdc8d8SChris Lattner return result.Succeeded(); 118230fdc8d8SChris Lattner } 118330fdc8d8SChris Lattner }; 118430fdc8d8SChris Lattner 118530fdc8d8SChris Lattner 118630fdc8d8SChris Lattner //------------------------------------------------------------------------- 118730fdc8d8SChris Lattner // CommandObjectProcessInterrupt 118830fdc8d8SChris Lattner //------------------------------------------------------------------------- 1189bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt 119030fdc8d8SChris Lattner 11915a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed 119230fdc8d8SChris Lattner { 119330fdc8d8SChris Lattner public: 119430fdc8d8SChris Lattner 119530fdc8d8SChris Lattner 1196a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 11975a988416SJim Ingham CommandObjectParsed (interpreter, 1198a7015092SGreg Clayton "process interrupt", 1199e3d26315SCaroline Tice "Interrupt the current process being debugged.", 120030fdc8d8SChris Lattner "process interrupt", 120130fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 120230fdc8d8SChris Lattner { 120330fdc8d8SChris Lattner } 120430fdc8d8SChris Lattner 120530fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 120630fdc8d8SChris Lattner { 120730fdc8d8SChris Lattner } 120830fdc8d8SChris Lattner 12095a988416SJim Ingham protected: 121030fdc8d8SChris Lattner bool 12115a988416SJim Ingham DoExecute (Args& command, 121230fdc8d8SChris Lattner CommandReturnObject &result) 121330fdc8d8SChris Lattner { 1214c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 121530fdc8d8SChris Lattner if (process == NULL) 121630fdc8d8SChris Lattner { 121730fdc8d8SChris Lattner result.AppendError ("no process to halt"); 121830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 121930fdc8d8SChris Lattner return false; 122030fdc8d8SChris Lattner } 122130fdc8d8SChris Lattner 122230fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 122330fdc8d8SChris Lattner { 122430fdc8d8SChris Lattner Error error(process->Halt ()); 122530fdc8d8SChris Lattner if (error.Success()) 122630fdc8d8SChris Lattner { 122730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 122830fdc8d8SChris Lattner 122930fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 123030fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 123130fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 123230fdc8d8SChris Lattner } 123330fdc8d8SChris Lattner else 123430fdc8d8SChris Lattner { 123530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 123630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 123730fdc8d8SChris Lattner } 123830fdc8d8SChris Lattner } 123930fdc8d8SChris Lattner else 124030fdc8d8SChris Lattner { 1241fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 124230fdc8d8SChris Lattner m_cmd_name.c_str(), 124330fdc8d8SChris Lattner m_cmd_syntax.c_str()); 124430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 124530fdc8d8SChris Lattner } 124630fdc8d8SChris Lattner return result.Succeeded(); 124730fdc8d8SChris Lattner } 124830fdc8d8SChris Lattner }; 124930fdc8d8SChris Lattner 125030fdc8d8SChris Lattner //------------------------------------------------------------------------- 125130fdc8d8SChris Lattner // CommandObjectProcessKill 125230fdc8d8SChris Lattner //------------------------------------------------------------------------- 1253bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill 125430fdc8d8SChris Lattner 12555a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed 125630fdc8d8SChris Lattner { 125730fdc8d8SChris Lattner public: 125830fdc8d8SChris Lattner 1259a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 12605a988416SJim Ingham CommandObjectParsed (interpreter, 1261a7015092SGreg Clayton "process kill", 1262e3d26315SCaroline Tice "Terminate the current process being debugged.", 126330fdc8d8SChris Lattner "process kill", 126430fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 126530fdc8d8SChris Lattner { 126630fdc8d8SChris Lattner } 126730fdc8d8SChris Lattner 126830fdc8d8SChris Lattner ~CommandObjectProcessKill () 126930fdc8d8SChris Lattner { 127030fdc8d8SChris Lattner } 127130fdc8d8SChris Lattner 12725a988416SJim Ingham protected: 127330fdc8d8SChris Lattner bool 12745a988416SJim Ingham DoExecute (Args& command, 127530fdc8d8SChris Lattner CommandReturnObject &result) 127630fdc8d8SChris Lattner { 1277c14ee32dSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 127830fdc8d8SChris Lattner if (process == NULL) 127930fdc8d8SChris Lattner { 128030fdc8d8SChris Lattner result.AppendError ("no process to kill"); 128130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 128230fdc8d8SChris Lattner return false; 128330fdc8d8SChris Lattner } 128430fdc8d8SChris Lattner 128530fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 128630fdc8d8SChris Lattner { 128730fdc8d8SChris Lattner Error error (process->Destroy()); 128830fdc8d8SChris Lattner if (error.Success()) 128930fdc8d8SChris Lattner { 129030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 129130fdc8d8SChris Lattner } 129230fdc8d8SChris Lattner else 129330fdc8d8SChris Lattner { 129430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 129530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 129630fdc8d8SChris Lattner } 129730fdc8d8SChris Lattner } 129830fdc8d8SChris Lattner else 129930fdc8d8SChris Lattner { 1300fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 130130fdc8d8SChris Lattner m_cmd_name.c_str(), 130230fdc8d8SChris Lattner m_cmd_syntax.c_str()); 130330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 130430fdc8d8SChris Lattner } 130530fdc8d8SChris Lattner return result.Succeeded(); 130630fdc8d8SChris Lattner } 130730fdc8d8SChris Lattner }; 130830fdc8d8SChris Lattner 130930fdc8d8SChris Lattner //------------------------------------------------------------------------- 13104b9bea87SJim Ingham // CommandObjectProcessStatus 13114b9bea87SJim Ingham //------------------------------------------------------------------------- 1312bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus 1313bb9caf73SJim Ingham 13145a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed 13154b9bea87SJim Ingham { 13164b9bea87SJim Ingham public: 1317a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 13185a988416SJim Ingham CommandObjectParsed (interpreter, 1319a7015092SGreg Clayton "process status", 1320e3d26315SCaroline Tice "Show the current status and location of executing process.", 1321e3d26315SCaroline Tice "process status", 13224b9bea87SJim Ingham 0) 13234b9bea87SJim Ingham { 13244b9bea87SJim Ingham } 13254b9bea87SJim Ingham 13264b9bea87SJim Ingham ~CommandObjectProcessStatus() 13274b9bea87SJim Ingham { 13284b9bea87SJim Ingham } 13294b9bea87SJim Ingham 13304b9bea87SJim Ingham 13314b9bea87SJim Ingham bool 13325a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 13334b9bea87SJim Ingham { 13347260f620SGreg Clayton Stream &strm = result.GetOutputStream(); 13354b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 13368b82f087SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 1337c14ee32dSGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 1338c14ee32dSGreg Clayton if (process) 13394b9bea87SJim Ingham { 13407260f620SGreg Clayton const bool only_threads_with_stop_reason = true; 13417260f620SGreg Clayton const uint32_t start_frame = 0; 13427260f620SGreg Clayton const uint32_t num_frames = 1; 13437260f620SGreg Clayton const uint32_t num_frames_with_source = 1; 1344c14ee32dSGreg Clayton process->GetStatus(strm); 1345c14ee32dSGreg Clayton process->GetThreadStatus (strm, 13467260f620SGreg Clayton only_threads_with_stop_reason, 13477260f620SGreg Clayton start_frame, 13487260f620SGreg Clayton num_frames, 13497260f620SGreg Clayton num_frames_with_source); 13507260f620SGreg Clayton 13514b9bea87SJim Ingham } 13524b9bea87SJim Ingham else 13534b9bea87SJim Ingham { 13547260f620SGreg Clayton result.AppendError ("No process."); 13554b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 13564b9bea87SJim Ingham } 13574b9bea87SJim Ingham return result.Succeeded(); 13584b9bea87SJim Ingham } 13594b9bea87SJim Ingham }; 13604b9bea87SJim Ingham 13614b9bea87SJim Ingham //------------------------------------------------------------------------- 136235731357SCaroline Tice // CommandObjectProcessHandle 136335731357SCaroline Tice //------------------------------------------------------------------------- 1364bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle 136535731357SCaroline Tice 13665a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed 136735731357SCaroline Tice { 136835731357SCaroline Tice public: 136935731357SCaroline Tice 137035731357SCaroline Tice class CommandOptions : public Options 137135731357SCaroline Tice { 137235731357SCaroline Tice public: 137335731357SCaroline Tice 1374eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1375eb0103f2SGreg Clayton Options (interpreter) 137635731357SCaroline Tice { 1377f6b8b581SGreg Clayton OptionParsingStarting (); 137835731357SCaroline Tice } 137935731357SCaroline Tice 138035731357SCaroline Tice ~CommandOptions () 138135731357SCaroline Tice { 138235731357SCaroline Tice } 138335731357SCaroline Tice 138435731357SCaroline Tice Error 1385f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 138635731357SCaroline Tice { 138735731357SCaroline Tice Error error; 138835731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 138935731357SCaroline Tice 139035731357SCaroline Tice switch (short_option) 139135731357SCaroline Tice { 139235731357SCaroline Tice case 's': 139335731357SCaroline Tice stop = option_arg; 139435731357SCaroline Tice break; 139535731357SCaroline Tice case 'n': 139635731357SCaroline Tice notify = option_arg; 139735731357SCaroline Tice break; 139835731357SCaroline Tice case 'p': 139935731357SCaroline Tice pass = option_arg; 140035731357SCaroline Tice break; 140135731357SCaroline Tice default: 140286edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 140335731357SCaroline Tice break; 140435731357SCaroline Tice } 140535731357SCaroline Tice return error; 140635731357SCaroline Tice } 140735731357SCaroline Tice 140835731357SCaroline Tice void 1409f6b8b581SGreg Clayton OptionParsingStarting () 141035731357SCaroline Tice { 141135731357SCaroline Tice stop.clear(); 141235731357SCaroline Tice notify.clear(); 141335731357SCaroline Tice pass.clear(); 141435731357SCaroline Tice } 141535731357SCaroline Tice 1416e0d378b3SGreg Clayton const OptionDefinition* 141735731357SCaroline Tice GetDefinitions () 141835731357SCaroline Tice { 141935731357SCaroline Tice return g_option_table; 142035731357SCaroline Tice } 142135731357SCaroline Tice 142235731357SCaroline Tice // Options table: Required for subclasses of Options. 142335731357SCaroline Tice 1424e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 142535731357SCaroline Tice 142635731357SCaroline Tice // Instance variables to hold the values for command options. 142735731357SCaroline Tice 142835731357SCaroline Tice std::string stop; 142935731357SCaroline Tice std::string notify; 143035731357SCaroline Tice std::string pass; 143135731357SCaroline Tice }; 143235731357SCaroline Tice 143335731357SCaroline Tice 143435731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 14355a988416SJim Ingham CommandObjectParsed (interpreter, 143635731357SCaroline Tice "process handle", 143710ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 1438eb0103f2SGreg Clayton NULL), 1439eb0103f2SGreg Clayton m_options (interpreter) 144035731357SCaroline Tice { 144110ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 144235731357SCaroline Tice CommandArgumentEntry arg; 1443c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 144435731357SCaroline Tice 1445c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1446c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 144735731357SCaroline Tice 1448c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 144935731357SCaroline Tice 145035731357SCaroline Tice m_arguments.push_back (arg); 145135731357SCaroline Tice } 145235731357SCaroline Tice 145335731357SCaroline Tice ~CommandObjectProcessHandle () 145435731357SCaroline Tice { 145535731357SCaroline Tice } 145635731357SCaroline Tice 145735731357SCaroline Tice Options * 145835731357SCaroline Tice GetOptions () 145935731357SCaroline Tice { 146035731357SCaroline Tice return &m_options; 146135731357SCaroline Tice } 146235731357SCaroline Tice 146335731357SCaroline Tice bool 146410ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 146535731357SCaroline Tice { 146635731357SCaroline Tice bool okay = true; 146735731357SCaroline Tice 146810ad7993SCaroline Tice bool success = false; 146910ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 147010ad7993SCaroline Tice 147110ad7993SCaroline Tice if (success && tmp_value) 147210ad7993SCaroline Tice real_value = 1; 147310ad7993SCaroline Tice else if (success && !tmp_value) 147410ad7993SCaroline Tice real_value = 0; 147535731357SCaroline Tice else 147635731357SCaroline Tice { 147735731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 147810ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 147910ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 148035731357SCaroline Tice okay = false; 148135731357SCaroline Tice } 148235731357SCaroline Tice 148335731357SCaroline Tice return okay; 148435731357SCaroline Tice } 148535731357SCaroline Tice 148610ad7993SCaroline Tice void 148710ad7993SCaroline Tice PrintSignalHeader (Stream &str) 148810ad7993SCaroline Tice { 148910ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 149010ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 149110ad7993SCaroline Tice } 149210ad7993SCaroline Tice 149310ad7993SCaroline Tice void 149410ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 149510ad7993SCaroline Tice { 149610ad7993SCaroline Tice bool stop; 149710ad7993SCaroline Tice bool suppress; 149810ad7993SCaroline Tice bool notify; 149910ad7993SCaroline Tice 150010ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 150110ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 150210ad7993SCaroline Tice { 150310ad7993SCaroline Tice bool pass = !suppress; 150410ad7993SCaroline Tice str.Printf ("%s %s %s", 150510ad7993SCaroline Tice (pass ? "true " : "false"), 150610ad7993SCaroline Tice (stop ? "true " : "false"), 150710ad7993SCaroline Tice (notify ? "true " : "false")); 150810ad7993SCaroline Tice } 150910ad7993SCaroline Tice str.Printf ("\n"); 151010ad7993SCaroline Tice } 151110ad7993SCaroline Tice 151210ad7993SCaroline Tice void 151310ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 151410ad7993SCaroline Tice { 151510ad7993SCaroline Tice PrintSignalHeader (str); 151610ad7993SCaroline Tice 151710ad7993SCaroline Tice if (num_valid_signals > 0) 151810ad7993SCaroline Tice { 151910ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 152010ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 152110ad7993SCaroline Tice { 152210ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 152310ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 152410ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 152510ad7993SCaroline Tice } 152610ad7993SCaroline Tice } 152710ad7993SCaroline Tice else // Print info for ALL signals 152810ad7993SCaroline Tice { 152910ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 153010ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 153110ad7993SCaroline Tice { 153210ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 153310ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 153410ad7993SCaroline Tice } 153510ad7993SCaroline Tice } 153610ad7993SCaroline Tice } 153710ad7993SCaroline Tice 15385a988416SJim Ingham protected: 153935731357SCaroline Tice bool 15405a988416SJim Ingham DoExecute (Args &signal_args, CommandReturnObject &result) 154135731357SCaroline Tice { 154235731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 154335731357SCaroline Tice 154435731357SCaroline Tice if (!target_sp) 154535731357SCaroline Tice { 154635731357SCaroline Tice result.AppendError ("No current target;" 154735731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 154835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 154935731357SCaroline Tice return false; 155035731357SCaroline Tice } 155135731357SCaroline Tice 155235731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 155335731357SCaroline Tice 155435731357SCaroline Tice if (!process_sp) 155535731357SCaroline Tice { 155635731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 155735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 155835731357SCaroline Tice return false; 155935731357SCaroline Tice } 156035731357SCaroline Tice 156135731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 156235731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 156335731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 156435731357SCaroline Tice 156535731357SCaroline Tice if (! m_options.stop.empty() 156610ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 156735731357SCaroline Tice { 156835731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 156935731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 157035731357SCaroline Tice return false; 157135731357SCaroline Tice } 157235731357SCaroline Tice 157335731357SCaroline Tice if (! m_options.notify.empty() 157410ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 157535731357SCaroline Tice { 157635731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 157735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 157835731357SCaroline Tice return false; 157935731357SCaroline Tice } 158035731357SCaroline Tice 158135731357SCaroline Tice if (! m_options.pass.empty() 158210ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 158335731357SCaroline Tice { 158435731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 158535731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 158635731357SCaroline Tice return false; 158735731357SCaroline Tice } 158835731357SCaroline Tice 158935731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 159035731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 159135731357SCaroline Tice int num_signals_set = 0; 159235731357SCaroline Tice 159310ad7993SCaroline Tice if (num_args > 0) 159410ad7993SCaroline Tice { 159535731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 159635731357SCaroline Tice { 159735731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 159835731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 159935731357SCaroline Tice { 160010ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 160135731357SCaroline Tice // the value is either 0 or 1. 160235731357SCaroline Tice if (stop_action != -1) 160335731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 160435731357SCaroline Tice if (pass_action != -1) 160535731357SCaroline Tice { 160610ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 160710ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 160835731357SCaroline Tice } 160935731357SCaroline Tice if (notify_action != -1) 161035731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 161135731357SCaroline Tice ++num_signals_set; 161235731357SCaroline Tice } 161335731357SCaroline Tice else 161435731357SCaroline Tice { 161535731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 161635731357SCaroline Tice } 161735731357SCaroline Tice } 161810ad7993SCaroline Tice } 161910ad7993SCaroline Tice else 162010ad7993SCaroline Tice { 162110ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 162210ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 162310ad7993SCaroline Tice { 162410ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 162510ad7993SCaroline Tice { 162610ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 162710ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 162810ad7993SCaroline Tice { 162910ad7993SCaroline Tice if (notify_action != -1) 163010ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 163110ad7993SCaroline Tice if (stop_action != -1) 163210ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 163310ad7993SCaroline Tice if (pass_action != -1) 163410ad7993SCaroline Tice { 163510ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 163610ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 163710ad7993SCaroline Tice } 163810ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 163910ad7993SCaroline Tice } 164010ad7993SCaroline Tice } 164110ad7993SCaroline Tice } 164210ad7993SCaroline Tice } 164310ad7993SCaroline Tice 164410ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 164535731357SCaroline Tice 164635731357SCaroline Tice if (num_signals_set > 0) 164735731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 164835731357SCaroline Tice else 164935731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 165035731357SCaroline Tice 165135731357SCaroline Tice return result.Succeeded(); 165235731357SCaroline Tice } 165335731357SCaroline Tice 165435731357SCaroline Tice CommandOptions m_options; 165535731357SCaroline Tice }; 165635731357SCaroline Tice 1657e0d378b3SGreg Clayton OptionDefinition 165835731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 165935731357SCaroline Tice { 166035731357SCaroline 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." }, 166135731357SCaroline 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." }, 166235731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 166335731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 166435731357SCaroline Tice }; 166535731357SCaroline Tice 166635731357SCaroline Tice //------------------------------------------------------------------------- 166730fdc8d8SChris Lattner // CommandObjectMultiwordProcess 166830fdc8d8SChris Lattner //------------------------------------------------------------------------- 166930fdc8d8SChris Lattner 16706611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1671a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1672a7015092SGreg Clayton "process", 167330fdc8d8SChris Lattner "A set of commands for operating on a process.", 167430fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 167530fdc8d8SChris Lattner { 1676a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1677a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1678a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1679b766a73dSGreg Clayton LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); 1680a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 16818f343b09SGreg Clayton LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 16828f343b09SGreg Clayton LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1683a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 168435731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1685a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1686a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1687a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 168830fdc8d8SChris Lattner } 168930fdc8d8SChris Lattner 169030fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 169130fdc8d8SChris Lattner { 169230fdc8d8SChris Lattner } 169330fdc8d8SChris Lattner 1694