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 //------------------------------------------------------------------------- 3230fdc8d8SChris Lattner 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; 6130fdc8d8SChris Lattner case 'e': stderr_path = option_arg; break; 6230fdc8d8SChris Lattner case 'i': stdin_path = option_arg; break; 6330fdc8d8SChris Lattner case 'o': stdout_path = option_arg; break; 6430fdc8d8SChris Lattner case 'p': plugin_name = option_arg; break; 6519388cfcSGreg Clayton case 't': in_new_tty = true; break; 6630fdc8d8SChris Lattner default: 6730fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 6830fdc8d8SChris Lattner break; 6930fdc8d8SChris Lattner 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner return error; 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 7430fdc8d8SChris Lattner void 7530fdc8d8SChris Lattner ResetOptionValues () 7630fdc8d8SChris Lattner { 7730fdc8d8SChris Lattner Options::ResetOptionValues(); 7830fdc8d8SChris Lattner stop_at_entry = false; 7919388cfcSGreg Clayton in_new_tty = false; 8030fdc8d8SChris Lattner stdin_path.clear(); 8130fdc8d8SChris Lattner stdout_path.clear(); 8230fdc8d8SChris Lattner stderr_path.clear(); 8330fdc8d8SChris Lattner plugin_name.clear(); 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner 8630fdc8d8SChris Lattner const lldb::OptionDefinition* 8730fdc8d8SChris Lattner GetDefinitions () 8830fdc8d8SChris Lattner { 8930fdc8d8SChris Lattner return g_option_table; 9030fdc8d8SChris Lattner } 9130fdc8d8SChris Lattner 9230fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 9330fdc8d8SChris Lattner 9430fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 9530fdc8d8SChris Lattner 9630fdc8d8SChris Lattner // Instance variables to hold the values for command options. 9730fdc8d8SChris Lattner 9830fdc8d8SChris Lattner bool stop_at_entry; 9919388cfcSGreg Clayton bool in_new_tty; 10030fdc8d8SChris Lattner std::string stderr_path; 10130fdc8d8SChris Lattner std::string stdin_path; 10230fdc8d8SChris Lattner std::string stdout_path; 10330fdc8d8SChris Lattner std::string plugin_name; 10430fdc8d8SChris Lattner 10530fdc8d8SChris Lattner }; 10630fdc8d8SChris Lattner 107a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 108a7015092SGreg Clayton CommandObject (interpreter, 109a7015092SGreg Clayton "process launch", 110e3d26315SCaroline Tice "Launch the executable in the debugger.", 111405fe67fSCaroline Tice NULL) 11230fdc8d8SChris Lattner { 113405fe67fSCaroline Tice CommandArgumentEntry arg; 114405fe67fSCaroline Tice CommandArgumentData run_args_arg; 115405fe67fSCaroline Tice 116405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 117405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 118405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 119405fe67fSCaroline Tice 120405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 121405fe67fSCaroline Tice arg.push_back (run_args_arg); 122405fe67fSCaroline Tice 123405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 124405fe67fSCaroline Tice m_arguments.push_back (arg); 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner 12730fdc8d8SChris Lattner 12830fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 12930fdc8d8SChris Lattner { 13030fdc8d8SChris Lattner } 13130fdc8d8SChris Lattner 13230fdc8d8SChris Lattner Options * 13330fdc8d8SChris Lattner GetOptions () 13430fdc8d8SChris Lattner { 13530fdc8d8SChris Lattner return &m_options; 13630fdc8d8SChris Lattner } 13730fdc8d8SChris Lattner 13830fdc8d8SChris Lattner bool 13905faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 14030fdc8d8SChris Lattner { 141a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 14230fdc8d8SChris Lattner 14330fdc8d8SChris Lattner if (target == NULL) 14430fdc8d8SChris Lattner { 14530fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 14630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 14730fdc8d8SChris Lattner return false; 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner 15030fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 15130fdc8d8SChris Lattner char filename[PATH_MAX]; 15219388cfcSGreg Clayton const Module *exe_module = target->GetExecutableModule().get(); 15330fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 15430fdc8d8SChris Lattner 155a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 156a7015092SGreg Clayton if (process && process->IsAlive()) 15730fdc8d8SChris Lattner { 15830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", 15930fdc8d8SChris Lattner process->GetID()); 16030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 16130fdc8d8SChris Lattner return false; 16230fdc8d8SChris Lattner } 16330fdc8d8SChris Lattner 16430fdc8d8SChris Lattner const char *plugin_name; 16530fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 16630fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 16730fdc8d8SChris Lattner else 16830fdc8d8SChris Lattner plugin_name = NULL; 16930fdc8d8SChris Lattner 170a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 17130fdc8d8SChris Lattner 172a7015092SGreg Clayton if (process == NULL) 1733df9a8dfSCaroline Tice { 17443a8c39bSCaroline Tice result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 175a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 176a7015092SGreg Clayton return false; 1773df9a8dfSCaroline Tice } 1783df9a8dfSCaroline Tice 179a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 180a7015092SGreg Clayton // might have been set using the "run-args" set variable. 18130fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 18230fdc8d8SChris Lattner { 183a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 184a7015092SGreg Clayton launch_args = process->GetRunArguments(); 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner 18719388cfcSGreg Clayton if (m_options.in_new_tty) 18819388cfcSGreg Clayton { 18919388cfcSGreg Clayton char exec_file_path[PATH_MAX]; 19019388cfcSGreg Clayton if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 19119388cfcSGreg Clayton { 19219388cfcSGreg Clayton launch_args.InsertArgumentAtIndex(0, exec_file_path); 19319388cfcSGreg Clayton } 19419388cfcSGreg Clayton else 19519388cfcSGreg Clayton { 19619388cfcSGreg Clayton result.AppendError("invalid executable"); 19719388cfcSGreg Clayton result.SetStatus (eReturnStatusFailed); 19819388cfcSGreg Clayton return false; 19919388cfcSGreg Clayton } 20019388cfcSGreg Clayton } 20119388cfcSGreg Clayton 202a7015092SGreg Clayton Args environment; 20330fdc8d8SChris Lattner 204a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 205a7015092SGreg Clayton 206a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 207a7015092SGreg Clayton 208a7015092SGreg Clayton if (process->GetDisableASLR()) 209a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 210a7015092SGreg Clayton 21119388cfcSGreg Clayton const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 21219388cfcSGreg Clayton const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 21330fdc8d8SChris Lattner 21419388cfcSGreg Clayton Error error; 21519388cfcSGreg Clayton 21619388cfcSGreg Clayton if (m_options.in_new_tty) 21719388cfcSGreg Clayton { 21819388cfcSGreg Clayton 219*3fcbed6bSGreg Clayton lldb::pid_t pid = Host::LaunchInNewTerminal (inferior_argv, 22019388cfcSGreg Clayton inferior_envp, 22119388cfcSGreg Clayton &exe_module->GetArchitecture(), 22219388cfcSGreg Clayton true, 22319388cfcSGreg Clayton process->GetDisableASLR()); 22419388cfcSGreg Clayton 225*3fcbed6bSGreg Clayton if (pid != LLDB_INVALID_PROCESS_ID) 226*3fcbed6bSGreg Clayton error = process->Attach (pid); 22719388cfcSGreg Clayton } 22819388cfcSGreg Clayton else 22919388cfcSGreg Clayton { 23030fdc8d8SChris Lattner const char * stdin_path = NULL; 23130fdc8d8SChris Lattner const char * stdout_path = NULL; 23230fdc8d8SChris Lattner const char * stderr_path = NULL; 23330fdc8d8SChris Lattner 234a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 235a7015092SGreg Clayton if (m_options.stdin_path.empty() && 23630fdc8d8SChris Lattner m_options.stdout_path.empty() && 237a7015092SGreg Clayton m_options.stderr_path.empty()) 23830fdc8d8SChris Lattner { 239a7015092SGreg Clayton // No standard file handles were given on the command line, check 240a7015092SGreg Clayton // with the process object in case they were give using "set settings" 241a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 242a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 243a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 244a7015092SGreg Clayton } 245a7015092SGreg Clayton else 246a7015092SGreg Clayton { 247a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 248a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 249a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 25030fdc8d8SChris Lattner } 25130fdc8d8SChris Lattner 252a7015092SGreg Clayton if (stdin_path == NULL) 253a7015092SGreg Clayton stdin_path = "/dev/null"; 254a7015092SGreg Clayton if (stdout_path == NULL) 255a7015092SGreg Clayton stdout_path = "/dev/null"; 256a7015092SGreg Clayton if (stderr_path == NULL) 257a7015092SGreg Clayton stderr_path = "/dev/null"; 258a7015092SGreg Clayton 25919388cfcSGreg Clayton error = process->Launch (inferior_argv, 26019388cfcSGreg Clayton inferior_envp, 261f681b94fSGreg Clayton launch_flags, 26230fdc8d8SChris Lattner stdin_path, 26330fdc8d8SChris Lattner stdout_path, 26419388cfcSGreg Clayton stderr_path); 26519388cfcSGreg Clayton } 26630fdc8d8SChris Lattner 26730fdc8d8SChris Lattner if (error.Success()) 26830fdc8d8SChris Lattner { 26919388cfcSGreg Clayton const char *archname = exe_module->GetArchitecture().AsCString(); 27019388cfcSGreg Clayton 27119388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 27205faeb71SGreg Clayton result.SetDidChangeProcessState (true); 27330fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 27430fdc8d8SChris Lattner { 27505faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 27630fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 27730fdc8d8SChris Lattner 27830fdc8d8SChris Lattner if (state == eStateStopped) 27930fdc8d8SChris Lattner { 28005faeb71SGreg Clayton error = process->Resume(); 28105faeb71SGreg Clayton if (error.Success()) 28205faeb71SGreg Clayton { 28305faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 28430fdc8d8SChris Lattner if (synchronous_execution) 28530fdc8d8SChris Lattner { 28605faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 28730fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 28805faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 28905faeb71SGreg Clayton } 29005faeb71SGreg Clayton else 29105faeb71SGreg Clayton { 29205faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 29305faeb71SGreg Clayton } 29405faeb71SGreg Clayton } 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner } 29730fdc8d8SChris Lattner } 29830fdc8d8SChris Lattner 29930fdc8d8SChris Lattner return result.Succeeded(); 30030fdc8d8SChris Lattner } 30130fdc8d8SChris Lattner 302ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 303ebc09c36SJim Ingham { 304ebc09c36SJim Ingham // No repeat for "process launch"... 305ebc09c36SJim Ingham return ""; 306ebc09c36SJim Ingham } 307ebc09c36SJim Ingham 30830fdc8d8SChris Lattner protected: 30930fdc8d8SChris Lattner 31030fdc8d8SChris Lattner CommandOptions m_options; 31130fdc8d8SChris Lattner }; 31230fdc8d8SChris Lattner 31330fdc8d8SChris Lattner 31419388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1 31519388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2 31619388cfcSGreg Clayton 31730fdc8d8SChris Lattner lldb::OptionDefinition 31830fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 31930fdc8d8SChris Lattner { 32019388cfcSGreg Clayton { SET1 | SET2, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 32119388cfcSGreg Clayton { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 32219388cfcSGreg Clayton { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 32319388cfcSGreg Clayton { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 32419388cfcSGreg Clayton { SET1 | SET2, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 32519388cfcSGreg Clayton { SET2, false, "tty", 't', no_argument, NULL, 0, eArgTypeNone, "Start the process in a new terminal (tty)."}, 326deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 32730fdc8d8SChris Lattner }; 32830fdc8d8SChris Lattner 32919388cfcSGreg Clayton #undef SET1 33019388cfcSGreg Clayton #undef SET2 33130fdc8d8SChris Lattner 33230fdc8d8SChris Lattner //------------------------------------------------------------------------- 33330fdc8d8SChris Lattner // CommandObjectProcessAttach 33430fdc8d8SChris Lattner //------------------------------------------------------------------------- 33530fdc8d8SChris Lattner 33630fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 33730fdc8d8SChris Lattner { 33830fdc8d8SChris Lattner public: 33930fdc8d8SChris Lattner 34030fdc8d8SChris Lattner class CommandOptions : public Options 34130fdc8d8SChris Lattner { 34230fdc8d8SChris Lattner public: 34330fdc8d8SChris Lattner 34430fdc8d8SChris Lattner CommandOptions () : 34530fdc8d8SChris Lattner Options() 34630fdc8d8SChris Lattner { 34730fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 34830fdc8d8SChris Lattner ResetOptionValues (); 34930fdc8d8SChris Lattner } 35030fdc8d8SChris Lattner 35130fdc8d8SChris Lattner ~CommandOptions () 35230fdc8d8SChris Lattner { 35330fdc8d8SChris Lattner } 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner Error 35630fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 35730fdc8d8SChris Lattner { 35830fdc8d8SChris Lattner Error error; 35930fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 36030fdc8d8SChris Lattner bool success = false; 36130fdc8d8SChris Lattner switch (short_option) 36230fdc8d8SChris Lattner { 36330fdc8d8SChris Lattner case 'p': 36430fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 36530fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 36630fdc8d8SChris Lattner { 36730fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 36830fdc8d8SChris Lattner } 36930fdc8d8SChris Lattner break; 37030fdc8d8SChris Lattner 37130fdc8d8SChris Lattner case 'P': 37230fdc8d8SChris Lattner plugin_name = option_arg; 37330fdc8d8SChris Lattner break; 37430fdc8d8SChris Lattner 37530fdc8d8SChris Lattner case 'n': 37630fdc8d8SChris Lattner name.assign(option_arg); 37730fdc8d8SChris Lattner break; 37830fdc8d8SChris Lattner 37930fdc8d8SChris Lattner case 'w': 38030fdc8d8SChris Lattner waitfor = true; 38130fdc8d8SChris Lattner break; 38230fdc8d8SChris Lattner 38330fdc8d8SChris Lattner default: 38430fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 38530fdc8d8SChris Lattner break; 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner return error; 38830fdc8d8SChris Lattner } 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner void 39130fdc8d8SChris Lattner ResetOptionValues () 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner Options::ResetOptionValues(); 39430fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 39530fdc8d8SChris Lattner name.clear(); 39630fdc8d8SChris Lattner waitfor = false; 39730fdc8d8SChris Lattner } 39830fdc8d8SChris Lattner 39930fdc8d8SChris Lattner const lldb::OptionDefinition* 40030fdc8d8SChris Lattner GetDefinitions () 40130fdc8d8SChris Lattner { 40230fdc8d8SChris Lattner return g_option_table; 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner 4055aee162fSJim Ingham virtual bool 406a7015092SGreg Clayton HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 4075aee162fSJim Ingham Args &input, 4085aee162fSJim Ingham int cursor_index, 4095aee162fSJim Ingham int char_pos, 4105aee162fSJim Ingham OptionElementVector &opt_element_vector, 4115aee162fSJim Ingham int opt_element_index, 4125aee162fSJim Ingham int match_start_point, 4135aee162fSJim Ingham int max_return_elements, 4145aee162fSJim Ingham bool &word_complete, 4155aee162fSJim Ingham StringList &matches) 4165aee162fSJim Ingham { 4175aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4185aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4195aee162fSJim Ingham 4205aee162fSJim Ingham // We are only completing the name option for now... 4215aee162fSJim Ingham 4225aee162fSJim Ingham const lldb::OptionDefinition *opt_defs = GetDefinitions(); 4235aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4245aee162fSJim Ingham { 4255aee162fSJim Ingham // Are we in the name? 4265aee162fSJim Ingham 4275aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4285aee162fSJim Ingham // use the default plugin. 429a7015092SGreg Clayton Process *process = interpeter.GetDebugger().GetExecutionContext().process; 4305aee162fSJim Ingham bool need_to_delete_process = false; 4315aee162fSJim Ingham 4325aee162fSJim Ingham const char *partial_name = NULL; 4335aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4345aee162fSJim Ingham 4355aee162fSJim Ingham if (process && process->IsAlive()) 4365aee162fSJim Ingham return true; 4375aee162fSJim Ingham 438a7015092SGreg Clayton Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 4395aee162fSJim Ingham if (target == NULL) 4405aee162fSJim Ingham { 4415aee162fSJim Ingham // No target has been set yet, for now do host completion. Otherwise I don't know how we would 4425aee162fSJim Ingham // figure out what the right target to use is... 4435aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4445aee162fSJim Ingham Host::ListProcessesMatchingName (partial_name, matches, pids); 4455aee162fSJim Ingham return true; 4465aee162fSJim Ingham } 4475aee162fSJim Ingham if (!process) 4485aee162fSJim Ingham { 449a7015092SGreg Clayton process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 4505aee162fSJim Ingham need_to_delete_process = true; 4515aee162fSJim Ingham } 4525aee162fSJim Ingham 4535aee162fSJim Ingham if (process) 4545aee162fSJim Ingham { 4555aee162fSJim Ingham matches.Clear(); 4565aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4575aee162fSJim Ingham process->ListProcessesMatchingName (NULL, matches, pids); 4585aee162fSJim Ingham if (need_to_delete_process) 4595aee162fSJim Ingham target->DeleteCurrentProcess(); 4605aee162fSJim Ingham return true; 4615aee162fSJim Ingham } 4625aee162fSJim Ingham } 4635aee162fSJim Ingham 4645aee162fSJim Ingham return false; 4655aee162fSJim Ingham } 4665aee162fSJim Ingham 46730fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 46830fdc8d8SChris Lattner 46930fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 47030fdc8d8SChris Lattner 47130fdc8d8SChris Lattner // Instance variables to hold the values for command options. 47230fdc8d8SChris Lattner 47330fdc8d8SChris Lattner lldb::pid_t pid; 47430fdc8d8SChris Lattner std::string plugin_name; 47530fdc8d8SChris Lattner std::string name; 47630fdc8d8SChris Lattner bool waitfor; 47730fdc8d8SChris Lattner }; 47830fdc8d8SChris Lattner 479a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 480a7015092SGreg Clayton CommandObject (interpreter, 481a7015092SGreg Clayton "process attach", 482e3d26315SCaroline Tice "Attach to a process.", 4835aee162fSJim Ingham "process attach <cmd-options>") 4845aee162fSJim Ingham { 4855aee162fSJim Ingham } 4865aee162fSJim Ingham 4875aee162fSJim Ingham ~CommandObjectProcessAttach () 4885aee162fSJim Ingham { 4895aee162fSJim Ingham } 4905aee162fSJim Ingham 4915aee162fSJim Ingham bool 492a7015092SGreg Clayton Execute (Args& command, 4935aee162fSJim Ingham CommandReturnObject &result) 4945aee162fSJim Ingham { 495a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4965aee162fSJim Ingham 497a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 4985aee162fSJim Ingham if (process) 4995aee162fSJim Ingham { 5005aee162fSJim Ingham if (process->IsAlive()) 5015aee162fSJim Ingham { 5025aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 5035aee162fSJim Ingham process->GetID()); 5045aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5055aee162fSJim Ingham return false; 5065aee162fSJim Ingham } 5075aee162fSJim Ingham } 5085aee162fSJim Ingham 5095aee162fSJim Ingham if (target == NULL) 5105aee162fSJim Ingham { 5115aee162fSJim Ingham // If there isn't a current target create one. 5125aee162fSJim Ingham TargetSP new_target_sp; 5135aee162fSJim Ingham FileSpec emptyFileSpec; 5145aee162fSJim Ingham ArchSpec emptyArchSpec; 5155aee162fSJim Ingham Error error; 5165aee162fSJim Ingham 517a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 5185aee162fSJim Ingham emptyFileSpec, 5195aee162fSJim Ingham emptyArchSpec, 5205aee162fSJim Ingham NULL, 5215aee162fSJim Ingham false, 5225aee162fSJim Ingham new_target_sp); 5235aee162fSJim Ingham target = new_target_sp.get(); 5245aee162fSJim Ingham if (target == NULL || error.Fail()) 5255aee162fSJim Ingham { 5265aee162fSJim Ingham result.AppendError(error.AsCString("Error creating empty target")); 5275aee162fSJim Ingham return false; 5285aee162fSJim Ingham } 529a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5305aee162fSJim Ingham } 5315aee162fSJim Ingham 5325aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5335aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5345aee162fSJim Ingham 5355aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5365aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5375aee162fSJim Ingham 5385aee162fSJim Ingham if (command.GetArgumentCount()) 5395aee162fSJim Ingham { 5405aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5415aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5425aee162fSJim Ingham } 5435aee162fSJim Ingham else 5445aee162fSJim Ingham { 5455aee162fSJim Ingham const char *plugin_name = NULL; 5465aee162fSJim Ingham 5475aee162fSJim Ingham if (!m_options.plugin_name.empty()) 5485aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 5495aee162fSJim Ingham 550a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 5515aee162fSJim Ingham 5525aee162fSJim Ingham if (process) 5535aee162fSJim Ingham { 5545aee162fSJim Ingham Error error; 5555aee162fSJim Ingham int attach_pid = m_options.pid; 5565aee162fSJim Ingham 5573a0b9cdfSJim Ingham const char *wait_name = NULL; 5583a0b9cdfSJim Ingham 5595aee162fSJim Ingham if (m_options.name.empty()) 5605aee162fSJim Ingham { 5613a0b9cdfSJim Ingham if (old_exec_module_sp) 5623a0b9cdfSJim Ingham { 5633a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 5643a0b9cdfSJim Ingham } 5655aee162fSJim Ingham } 5665aee162fSJim Ingham else 5675aee162fSJim Ingham { 5683a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 5693a0b9cdfSJim Ingham } 5703a0b9cdfSJim Ingham 5713a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 5723a0b9cdfSJim Ingham if (m_options.waitfor) 5733a0b9cdfSJim Ingham { 5743a0b9cdfSJim Ingham 5753a0b9cdfSJim Ingham if (wait_name == NULL) 5763a0b9cdfSJim Ingham { 5773a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 5783a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 5793a0b9cdfSJim Ingham return false; 5803a0b9cdfSJim Ingham } 5813a0b9cdfSJim Ingham 582a7015092SGreg Clayton m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 5833a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 5845aee162fSJim Ingham if (error.Success()) 5855aee162fSJim Ingham { 5865aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 5875aee162fSJim Ingham } 5885aee162fSJim Ingham else 5895aee162fSJim Ingham { 5905aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 5913a0b9cdfSJim Ingham wait_name, 5925aee162fSJim Ingham error.AsCString()); 5935aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5945aee162fSJim Ingham return false; 5955aee162fSJim Ingham } 5965aee162fSJim Ingham } 5975aee162fSJim Ingham else 5985aee162fSJim Ingham { 5995aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 6005aee162fSJim Ingham // processes with this pid. 6015aee162fSJim Ingham 6023a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 6035aee162fSJim Ingham { 6045aee162fSJim Ingham std::vector<lldb::pid_t> pids; 6055aee162fSJim Ingham StringList matches; 6065aee162fSJim Ingham 6073a0b9cdfSJim Ingham process->ListProcessesMatchingName(wait_name, matches, pids); 6085aee162fSJim Ingham if (matches.GetSize() > 1) 6095aee162fSJim Ingham { 6103a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 6115aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6125aee162fSJim Ingham return false; 6135aee162fSJim Ingham } 6145aee162fSJim Ingham else if (matches.GetSize() == 0) 6155aee162fSJim Ingham { 6163a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 6175aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6185aee162fSJim Ingham return false; 6195aee162fSJim Ingham } 6205aee162fSJim Ingham else 6215aee162fSJim Ingham { 6225aee162fSJim Ingham attach_pid = pids[0]; 6235aee162fSJim Ingham } 6245aee162fSJim Ingham 6255aee162fSJim Ingham } 6265aee162fSJim Ingham 6275aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 6285aee162fSJim Ingham { 6295aee162fSJim Ingham error = process->Attach (attach_pid); 6305aee162fSJim Ingham if (error.Success()) 6315aee162fSJim Ingham { 6325aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6335aee162fSJim Ingham } 6345aee162fSJim Ingham else 6355aee162fSJim Ingham { 6365aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 6375aee162fSJim Ingham attach_pid, 6385aee162fSJim Ingham error.AsCString()); 6395aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6405aee162fSJim Ingham } 6415aee162fSJim Ingham } 6425aee162fSJim Ingham else 6435aee162fSJim Ingham { 6445aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 6455aee162fSJim Ingham attach_pid, 6465aee162fSJim Ingham error.AsCString()); 6475aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6485aee162fSJim Ingham 6495aee162fSJim Ingham } 6505aee162fSJim Ingham } 6515aee162fSJim Ingham } 6525aee162fSJim Ingham } 6535aee162fSJim Ingham 6545aee162fSJim Ingham if (result.Succeeded()) 6555aee162fSJim Ingham { 6565aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 6575aee162fSJim Ingham if (!old_exec_module_sp) 6585aee162fSJim Ingham { 6595aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6605aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 6615aee162fSJim Ingham 6625aee162fSJim Ingham result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 6635aee162fSJim Ingham new_path); 6645aee162fSJim Ingham } 6655aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 6665aee162fSJim Ingham { 6675aee162fSJim Ingham char old_path[PATH_MAX + 1]; 6685aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6695aee162fSJim Ingham 6705aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 6715aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 6725aee162fSJim Ingham 6735aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6745aee162fSJim Ingham old_path, new_path); 6755aee162fSJim Ingham } 6765aee162fSJim Ingham 6775aee162fSJim Ingham if (!old_arch_spec.IsValid()) 6785aee162fSJim Ingham { 6795aee162fSJim Ingham result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 6805aee162fSJim Ingham } 6815aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 6825aee162fSJim Ingham { 6835aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 6845aee162fSJim Ingham old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 6855aee162fSJim Ingham } 6865aee162fSJim Ingham } 6875aee162fSJim Ingham return result.Succeeded(); 6885aee162fSJim Ingham } 6895aee162fSJim Ingham 6905aee162fSJim Ingham Options * 6915aee162fSJim Ingham GetOptions () 6925aee162fSJim Ingham { 6935aee162fSJim Ingham return &m_options; 6945aee162fSJim Ingham } 6955aee162fSJim Ingham 69630fdc8d8SChris Lattner protected: 69730fdc8d8SChris Lattner 69830fdc8d8SChris Lattner CommandOptions m_options; 69930fdc8d8SChris Lattner }; 70030fdc8d8SChris Lattner 70130fdc8d8SChris Lattner 70230fdc8d8SChris Lattner lldb::OptionDefinition 70330fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 70430fdc8d8SChris Lattner { 705deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 706deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 707deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 708deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 709deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 71030fdc8d8SChris Lattner }; 71130fdc8d8SChris Lattner 71230fdc8d8SChris Lattner //------------------------------------------------------------------------- 71330fdc8d8SChris Lattner // CommandObjectProcessContinue 71430fdc8d8SChris Lattner //------------------------------------------------------------------------- 71530fdc8d8SChris Lattner 71630fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 71730fdc8d8SChris Lattner { 71830fdc8d8SChris Lattner public: 71930fdc8d8SChris Lattner 720a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 721a7015092SGreg Clayton CommandObject (interpreter, 722a7015092SGreg Clayton "process continue", 723e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 72430fdc8d8SChris Lattner "process continue", 72530fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 72630fdc8d8SChris Lattner { 72730fdc8d8SChris Lattner } 72830fdc8d8SChris Lattner 72930fdc8d8SChris Lattner 73030fdc8d8SChris Lattner ~CommandObjectProcessContinue () 73130fdc8d8SChris Lattner { 73230fdc8d8SChris Lattner } 73330fdc8d8SChris Lattner 73430fdc8d8SChris Lattner bool 735a7015092SGreg Clayton Execute (Args& command, 73630fdc8d8SChris Lattner CommandReturnObject &result) 73730fdc8d8SChris Lattner { 738a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 739a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 74030fdc8d8SChris Lattner 74130fdc8d8SChris Lattner if (process == NULL) 74230fdc8d8SChris Lattner { 74330fdc8d8SChris Lattner result.AppendError ("no process to continue"); 74430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 74530fdc8d8SChris Lattner return false; 74630fdc8d8SChris Lattner } 74730fdc8d8SChris Lattner 74830fdc8d8SChris Lattner StateType state = process->GetState(); 74930fdc8d8SChris Lattner if (state == eStateStopped) 75030fdc8d8SChris Lattner { 75130fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 75230fdc8d8SChris Lattner { 75330fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 75430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 75530fdc8d8SChris Lattner return false; 75630fdc8d8SChris Lattner } 75730fdc8d8SChris Lattner 75830fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 75930fdc8d8SChris Lattner 76030fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 76130fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 76230fdc8d8SChris Lattner { 76330fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 76430fdc8d8SChris Lattner } 76530fdc8d8SChris Lattner 76630fdc8d8SChris Lattner Error error(process->Resume()); 76730fdc8d8SChris Lattner if (error.Success()) 76830fdc8d8SChris Lattner { 76919388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 77030fdc8d8SChris Lattner if (synchronous_execution) 77130fdc8d8SChris Lattner { 772b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 77330fdc8d8SChris Lattner 77430fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 77530fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 77630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 77730fdc8d8SChris Lattner } 77830fdc8d8SChris Lattner else 77930fdc8d8SChris Lattner { 78030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 78130fdc8d8SChris Lattner } 78230fdc8d8SChris Lattner } 78330fdc8d8SChris Lattner else 78430fdc8d8SChris Lattner { 78530fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 78630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78730fdc8d8SChris Lattner } 78830fdc8d8SChris Lattner } 78930fdc8d8SChris Lattner else 79030fdc8d8SChris Lattner { 79130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 79230fdc8d8SChris Lattner StateAsCString(state)); 79330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 79430fdc8d8SChris Lattner } 79530fdc8d8SChris Lattner return result.Succeeded(); 79630fdc8d8SChris Lattner } 79730fdc8d8SChris Lattner }; 79830fdc8d8SChris Lattner 79930fdc8d8SChris Lattner //------------------------------------------------------------------------- 80030fdc8d8SChris Lattner // CommandObjectProcessDetach 80130fdc8d8SChris Lattner //------------------------------------------------------------------------- 80230fdc8d8SChris Lattner 80330fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 80430fdc8d8SChris Lattner { 80530fdc8d8SChris Lattner public: 80630fdc8d8SChris Lattner 807a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 808a7015092SGreg Clayton CommandObject (interpreter, 809a7015092SGreg Clayton "process detach", 810e3d26315SCaroline Tice "Detach from the current process being debugged.", 81130fdc8d8SChris Lattner "process detach", 81230fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 81330fdc8d8SChris Lattner { 81430fdc8d8SChris Lattner } 81530fdc8d8SChris Lattner 81630fdc8d8SChris Lattner ~CommandObjectProcessDetach () 81730fdc8d8SChris Lattner { 81830fdc8d8SChris Lattner } 81930fdc8d8SChris Lattner 82030fdc8d8SChris Lattner bool 821a7015092SGreg Clayton Execute (Args& command, 82230fdc8d8SChris Lattner CommandReturnObject &result) 82330fdc8d8SChris Lattner { 824a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 82530fdc8d8SChris Lattner if (process == NULL) 82630fdc8d8SChris Lattner { 82730fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 82830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 82930fdc8d8SChris Lattner return false; 83030fdc8d8SChris Lattner } 83130fdc8d8SChris Lattner 83230fdc8d8SChris Lattner Error error (process->Detach()); 83330fdc8d8SChris Lattner if (error.Success()) 83430fdc8d8SChris Lattner { 83530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 83630fdc8d8SChris Lattner } 83730fdc8d8SChris Lattner else 83830fdc8d8SChris Lattner { 83930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 84030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 84130fdc8d8SChris Lattner return false; 84230fdc8d8SChris Lattner } 84330fdc8d8SChris Lattner return result.Succeeded(); 84430fdc8d8SChris Lattner } 84530fdc8d8SChris Lattner }; 84630fdc8d8SChris Lattner 84730fdc8d8SChris Lattner //------------------------------------------------------------------------- 84830fdc8d8SChris Lattner // CommandObjectProcessSignal 84930fdc8d8SChris Lattner //------------------------------------------------------------------------- 85030fdc8d8SChris Lattner 85130fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 85230fdc8d8SChris Lattner { 85330fdc8d8SChris Lattner public: 85430fdc8d8SChris Lattner 855a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 856a7015092SGreg Clayton CommandObject (interpreter, 857a7015092SGreg Clayton "process signal", 858e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 859405fe67fSCaroline Tice NULL) 86030fdc8d8SChris Lattner { 861405fe67fSCaroline Tice CommandArgumentEntry arg; 862405fe67fSCaroline Tice CommandArgumentData signal_arg; 863405fe67fSCaroline Tice 864405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 865c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 866405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 867405fe67fSCaroline Tice 868405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 869405fe67fSCaroline Tice arg.push_back (signal_arg); 870405fe67fSCaroline Tice 871405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 872405fe67fSCaroline Tice m_arguments.push_back (arg); 87330fdc8d8SChris Lattner } 87430fdc8d8SChris Lattner 87530fdc8d8SChris Lattner ~CommandObjectProcessSignal () 87630fdc8d8SChris Lattner { 87730fdc8d8SChris Lattner } 87830fdc8d8SChris Lattner 87930fdc8d8SChris Lattner bool 880a7015092SGreg Clayton Execute (Args& command, 88130fdc8d8SChris Lattner CommandReturnObject &result) 88230fdc8d8SChris Lattner { 883a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 88430fdc8d8SChris Lattner if (process == NULL) 88530fdc8d8SChris Lattner { 88630fdc8d8SChris Lattner result.AppendError ("no process to signal"); 88730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 88830fdc8d8SChris Lattner return false; 88930fdc8d8SChris Lattner } 89030fdc8d8SChris Lattner 89130fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 89230fdc8d8SChris Lattner { 893237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 894237cd906SGreg Clayton 895237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 896237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 897237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 898237cd906SGreg Clayton else 899237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 900237cd906SGreg Clayton 901237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 90230fdc8d8SChris Lattner { 90330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 90430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 90530fdc8d8SChris Lattner } 90630fdc8d8SChris Lattner else 90730fdc8d8SChris Lattner { 90830fdc8d8SChris Lattner Error error (process->Signal (signo)); 90930fdc8d8SChris Lattner if (error.Success()) 91030fdc8d8SChris Lattner { 91130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 91230fdc8d8SChris Lattner } 91330fdc8d8SChris Lattner else 91430fdc8d8SChris Lattner { 91530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 91630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 91730fdc8d8SChris Lattner } 91830fdc8d8SChris Lattner } 91930fdc8d8SChris Lattner } 92030fdc8d8SChris Lattner else 92130fdc8d8SChris Lattner { 92230fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 92330fdc8d8SChris Lattner m_cmd_syntax.c_str()); 92430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 92530fdc8d8SChris Lattner } 92630fdc8d8SChris Lattner return result.Succeeded(); 92730fdc8d8SChris Lattner } 92830fdc8d8SChris Lattner }; 92930fdc8d8SChris Lattner 93030fdc8d8SChris Lattner 93130fdc8d8SChris Lattner //------------------------------------------------------------------------- 93230fdc8d8SChris Lattner // CommandObjectProcessInterrupt 93330fdc8d8SChris Lattner //------------------------------------------------------------------------- 93430fdc8d8SChris Lattner 93530fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 93630fdc8d8SChris Lattner { 93730fdc8d8SChris Lattner public: 93830fdc8d8SChris Lattner 93930fdc8d8SChris Lattner 940a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 941a7015092SGreg Clayton CommandObject (interpreter, 942a7015092SGreg Clayton "process interrupt", 943e3d26315SCaroline Tice "Interrupt the current process being debugged.", 94430fdc8d8SChris Lattner "process interrupt", 94530fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 94630fdc8d8SChris Lattner { 94730fdc8d8SChris Lattner } 94830fdc8d8SChris Lattner 94930fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 95030fdc8d8SChris Lattner { 95130fdc8d8SChris Lattner } 95230fdc8d8SChris Lattner 95330fdc8d8SChris Lattner bool 954a7015092SGreg Clayton Execute (Args& command, 95530fdc8d8SChris Lattner CommandReturnObject &result) 95630fdc8d8SChris Lattner { 957a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 95830fdc8d8SChris Lattner if (process == NULL) 95930fdc8d8SChris Lattner { 96030fdc8d8SChris Lattner result.AppendError ("no process to halt"); 96130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 96230fdc8d8SChris Lattner return false; 96330fdc8d8SChris Lattner } 96430fdc8d8SChris Lattner 96530fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 96630fdc8d8SChris Lattner { 96730fdc8d8SChris Lattner Error error(process->Halt ()); 96830fdc8d8SChris Lattner if (error.Success()) 96930fdc8d8SChris Lattner { 97030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 97130fdc8d8SChris Lattner 97230fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 97330fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 97430fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 97530fdc8d8SChris Lattner } 97630fdc8d8SChris Lattner else 97730fdc8d8SChris Lattner { 97830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 97930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 98030fdc8d8SChris Lattner } 98130fdc8d8SChris Lattner } 98230fdc8d8SChris Lattner else 98330fdc8d8SChris Lattner { 98430fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 98530fdc8d8SChris Lattner m_cmd_name.c_str(), 98630fdc8d8SChris Lattner m_cmd_syntax.c_str()); 98730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 98830fdc8d8SChris Lattner } 98930fdc8d8SChris Lattner return result.Succeeded(); 99030fdc8d8SChris Lattner } 99130fdc8d8SChris Lattner }; 99230fdc8d8SChris Lattner 99330fdc8d8SChris Lattner //------------------------------------------------------------------------- 99430fdc8d8SChris Lattner // CommandObjectProcessKill 99530fdc8d8SChris Lattner //------------------------------------------------------------------------- 99630fdc8d8SChris Lattner 99730fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 99830fdc8d8SChris Lattner { 99930fdc8d8SChris Lattner public: 100030fdc8d8SChris Lattner 1001a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1002a7015092SGreg Clayton CommandObject (interpreter, 1003a7015092SGreg Clayton "process kill", 1004e3d26315SCaroline Tice "Terminate the current process being debugged.", 100530fdc8d8SChris Lattner "process kill", 100630fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 100730fdc8d8SChris Lattner { 100830fdc8d8SChris Lattner } 100930fdc8d8SChris Lattner 101030fdc8d8SChris Lattner ~CommandObjectProcessKill () 101130fdc8d8SChris Lattner { 101230fdc8d8SChris Lattner } 101330fdc8d8SChris Lattner 101430fdc8d8SChris Lattner bool 1015a7015092SGreg Clayton Execute (Args& command, 101630fdc8d8SChris Lattner CommandReturnObject &result) 101730fdc8d8SChris Lattner { 1018a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 101930fdc8d8SChris Lattner if (process == NULL) 102030fdc8d8SChris Lattner { 102130fdc8d8SChris Lattner result.AppendError ("no process to kill"); 102230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 102330fdc8d8SChris Lattner return false; 102430fdc8d8SChris Lattner } 102530fdc8d8SChris Lattner 102630fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 102730fdc8d8SChris Lattner { 102830fdc8d8SChris Lattner Error error (process->Destroy()); 102930fdc8d8SChris Lattner if (error.Success()) 103030fdc8d8SChris Lattner { 103130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 103230fdc8d8SChris Lattner } 103330fdc8d8SChris Lattner else 103430fdc8d8SChris Lattner { 103530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 103630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 103730fdc8d8SChris Lattner } 103830fdc8d8SChris Lattner } 103930fdc8d8SChris Lattner else 104030fdc8d8SChris Lattner { 104130fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 104230fdc8d8SChris Lattner m_cmd_name.c_str(), 104330fdc8d8SChris Lattner m_cmd_syntax.c_str()); 104430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 104530fdc8d8SChris Lattner } 104630fdc8d8SChris Lattner return result.Succeeded(); 104730fdc8d8SChris Lattner } 104830fdc8d8SChris Lattner }; 104930fdc8d8SChris Lattner 105030fdc8d8SChris Lattner //------------------------------------------------------------------------- 10514b9bea87SJim Ingham // CommandObjectProcessStatus 10524b9bea87SJim Ingham //------------------------------------------------------------------------- 10534b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 10544b9bea87SJim Ingham { 10554b9bea87SJim Ingham public: 1056a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1057a7015092SGreg Clayton CommandObject (interpreter, 1058a7015092SGreg Clayton "process status", 1059e3d26315SCaroline Tice "Show the current status and location of executing process.", 1060e3d26315SCaroline Tice "process status", 10614b9bea87SJim Ingham 0) 10624b9bea87SJim Ingham { 10634b9bea87SJim Ingham } 10644b9bea87SJim Ingham 10654b9bea87SJim Ingham ~CommandObjectProcessStatus() 10664b9bea87SJim Ingham { 10674b9bea87SJim Ingham } 10684b9bea87SJim Ingham 10694b9bea87SJim Ingham 10704b9bea87SJim Ingham bool 10714b9bea87SJim Ingham Execute 10724b9bea87SJim Ingham ( 10734b9bea87SJim Ingham Args& command, 10744b9bea87SJim Ingham CommandReturnObject &result 10754b9bea87SJim Ingham ) 10764b9bea87SJim Ingham { 10774b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 10784b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1079a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 10804b9bea87SJim Ingham if (exe_ctx.process) 10814b9bea87SJim Ingham { 10824b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 10834b9bea87SJim Ingham if (StateIsStoppedState(state)) 10844b9bea87SJim Ingham { 10854b9bea87SJim Ingham if (state == eStateExited) 10864b9bea87SJim Ingham { 10874b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 10884b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 10894b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 10904b9bea87SJim Ingham exe_ctx.process->GetID(), 10914b9bea87SJim Ingham exit_status, 10924b9bea87SJim Ingham exit_status, 10934b9bea87SJim Ingham exit_description ? exit_description : ""); 10944b9bea87SJim Ingham } 10954b9bea87SJim Ingham else 10964b9bea87SJim Ingham { 10974b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 10984b9bea87SJim Ingham if (exe_ctx.thread == NULL) 10994b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 11004b9bea87SJim Ingham if (exe_ctx.thread != NULL) 11014b9bea87SJim Ingham { 1102a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 11034b9bea87SJim Ingham } 11044b9bea87SJim Ingham else 11054b9bea87SJim Ingham { 11064b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 11074b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 11084b9bea87SJim Ingham } 11094b9bea87SJim Ingham } 11104b9bea87SJim Ingham } 11114b9bea87SJim Ingham else 11124b9bea87SJim Ingham { 11134b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 11144b9bea87SJim Ingham exe_ctx.process->GetID()); 11154b9bea87SJim Ingham } 11164b9bea87SJim Ingham } 11174b9bea87SJim Ingham else 11184b9bea87SJim Ingham { 11194b9bea87SJim Ingham result.AppendError ("No current location or status available."); 11204b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 11214b9bea87SJim Ingham } 11224b9bea87SJim Ingham return result.Succeeded(); 11234b9bea87SJim Ingham } 11244b9bea87SJim Ingham }; 11254b9bea87SJim Ingham 11264b9bea87SJim Ingham //------------------------------------------------------------------------- 112735731357SCaroline Tice // CommandObjectProcessHandle 112835731357SCaroline Tice //------------------------------------------------------------------------- 112935731357SCaroline Tice 113035731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 113135731357SCaroline Tice { 113235731357SCaroline Tice public: 113335731357SCaroline Tice 113435731357SCaroline Tice class CommandOptions : public Options 113535731357SCaroline Tice { 113635731357SCaroline Tice public: 113735731357SCaroline Tice 113835731357SCaroline Tice CommandOptions () : 113935731357SCaroline Tice Options () 114035731357SCaroline Tice { 114135731357SCaroline Tice ResetOptionValues (); 114235731357SCaroline Tice } 114335731357SCaroline Tice 114435731357SCaroline Tice ~CommandOptions () 114535731357SCaroline Tice { 114635731357SCaroline Tice } 114735731357SCaroline Tice 114835731357SCaroline Tice Error 114935731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 115035731357SCaroline Tice { 115135731357SCaroline Tice Error error; 115235731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 115335731357SCaroline Tice 115435731357SCaroline Tice switch (short_option) 115535731357SCaroline Tice { 115635731357SCaroline Tice case 's': 115735731357SCaroline Tice stop = option_arg; 115835731357SCaroline Tice break; 115935731357SCaroline Tice case 'n': 116035731357SCaroline Tice notify = option_arg; 116135731357SCaroline Tice break; 116235731357SCaroline Tice case 'p': 116335731357SCaroline Tice pass = option_arg; 116435731357SCaroline Tice break; 116535731357SCaroline Tice default: 116635731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 116735731357SCaroline Tice break; 116835731357SCaroline Tice } 116935731357SCaroline Tice return error; 117035731357SCaroline Tice } 117135731357SCaroline Tice 117235731357SCaroline Tice void 117335731357SCaroline Tice ResetOptionValues () 117435731357SCaroline Tice { 117535731357SCaroline Tice Options::ResetOptionValues(); 117635731357SCaroline Tice stop.clear(); 117735731357SCaroline Tice notify.clear(); 117835731357SCaroline Tice pass.clear(); 117935731357SCaroline Tice } 118035731357SCaroline Tice 118135731357SCaroline Tice const lldb::OptionDefinition* 118235731357SCaroline Tice GetDefinitions () 118335731357SCaroline Tice { 118435731357SCaroline Tice return g_option_table; 118535731357SCaroline Tice } 118635731357SCaroline Tice 118735731357SCaroline Tice // Options table: Required for subclasses of Options. 118835731357SCaroline Tice 118935731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 119035731357SCaroline Tice 119135731357SCaroline Tice // Instance variables to hold the values for command options. 119235731357SCaroline Tice 119335731357SCaroline Tice std::string stop; 119435731357SCaroline Tice std::string notify; 119535731357SCaroline Tice std::string pass; 119635731357SCaroline Tice }; 119735731357SCaroline Tice 119835731357SCaroline Tice 119935731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 120035731357SCaroline Tice CommandObject (interpreter, 120135731357SCaroline Tice "process handle", 120210ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 120335731357SCaroline Tice NULL) 120435731357SCaroline Tice { 120510ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 120635731357SCaroline Tice CommandArgumentEntry arg; 1207c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 120835731357SCaroline Tice 1209c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1210c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 121135731357SCaroline Tice 1212c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 121335731357SCaroline Tice 121435731357SCaroline Tice m_arguments.push_back (arg); 121535731357SCaroline Tice } 121635731357SCaroline Tice 121735731357SCaroline Tice ~CommandObjectProcessHandle () 121835731357SCaroline Tice { 121935731357SCaroline Tice } 122035731357SCaroline Tice 122135731357SCaroline Tice Options * 122235731357SCaroline Tice GetOptions () 122335731357SCaroline Tice { 122435731357SCaroline Tice return &m_options; 122535731357SCaroline Tice } 122635731357SCaroline Tice 122735731357SCaroline Tice bool 122810ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 122935731357SCaroline Tice { 123035731357SCaroline Tice bool okay = true; 123135731357SCaroline Tice 123210ad7993SCaroline Tice bool success = false; 123310ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 123410ad7993SCaroline Tice 123510ad7993SCaroline Tice if (success && tmp_value) 123610ad7993SCaroline Tice real_value = 1; 123710ad7993SCaroline Tice else if (success && !tmp_value) 123810ad7993SCaroline Tice real_value = 0; 123935731357SCaroline Tice else 124035731357SCaroline Tice { 124135731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 124210ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 124310ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 124435731357SCaroline Tice okay = false; 124535731357SCaroline Tice } 124635731357SCaroline Tice 124735731357SCaroline Tice return okay; 124835731357SCaroline Tice } 124935731357SCaroline Tice 125010ad7993SCaroline Tice void 125110ad7993SCaroline Tice PrintSignalHeader (Stream &str) 125210ad7993SCaroline Tice { 125310ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 125410ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 125510ad7993SCaroline Tice } 125610ad7993SCaroline Tice 125710ad7993SCaroline Tice void 125810ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 125910ad7993SCaroline Tice { 126010ad7993SCaroline Tice bool stop; 126110ad7993SCaroline Tice bool suppress; 126210ad7993SCaroline Tice bool notify; 126310ad7993SCaroline Tice 126410ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 126510ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 126610ad7993SCaroline Tice { 126710ad7993SCaroline Tice bool pass = !suppress; 126810ad7993SCaroline Tice str.Printf ("%s %s %s", 126910ad7993SCaroline Tice (pass ? "true " : "false"), 127010ad7993SCaroline Tice (stop ? "true " : "false"), 127110ad7993SCaroline Tice (notify ? "true " : "false")); 127210ad7993SCaroline Tice } 127310ad7993SCaroline Tice str.Printf ("\n"); 127410ad7993SCaroline Tice } 127510ad7993SCaroline Tice 127610ad7993SCaroline Tice void 127710ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 127810ad7993SCaroline Tice { 127910ad7993SCaroline Tice PrintSignalHeader (str); 128010ad7993SCaroline Tice 128110ad7993SCaroline Tice if (num_valid_signals > 0) 128210ad7993SCaroline Tice { 128310ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 128410ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 128510ad7993SCaroline Tice { 128610ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 128710ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 128810ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 128910ad7993SCaroline Tice } 129010ad7993SCaroline Tice } 129110ad7993SCaroline Tice else // Print info for ALL signals 129210ad7993SCaroline Tice { 129310ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 129410ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 129510ad7993SCaroline Tice { 129610ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 129710ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 129810ad7993SCaroline Tice } 129910ad7993SCaroline Tice } 130010ad7993SCaroline Tice } 130110ad7993SCaroline Tice 130235731357SCaroline Tice bool 130335731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 130435731357SCaroline Tice { 130535731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 130635731357SCaroline Tice 130735731357SCaroline Tice if (!target_sp) 130835731357SCaroline Tice { 130935731357SCaroline Tice result.AppendError ("No current target;" 131035731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 131135731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 131235731357SCaroline Tice return false; 131335731357SCaroline Tice } 131435731357SCaroline Tice 131535731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 131635731357SCaroline Tice 131735731357SCaroline Tice if (!process_sp) 131835731357SCaroline Tice { 131935731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 132035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 132135731357SCaroline Tice return false; 132235731357SCaroline Tice } 132335731357SCaroline Tice 132435731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 132535731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 132635731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 132735731357SCaroline Tice 132835731357SCaroline Tice if (! m_options.stop.empty() 132910ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 133035731357SCaroline Tice { 133135731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 133235731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 133335731357SCaroline Tice return false; 133435731357SCaroline Tice } 133535731357SCaroline Tice 133635731357SCaroline Tice if (! m_options.notify.empty() 133710ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 133835731357SCaroline Tice { 133935731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 134035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 134135731357SCaroline Tice return false; 134235731357SCaroline Tice } 134335731357SCaroline Tice 134435731357SCaroline Tice if (! m_options.pass.empty() 134510ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 134635731357SCaroline Tice { 134735731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 134835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 134935731357SCaroline Tice return false; 135035731357SCaroline Tice } 135135731357SCaroline Tice 135235731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 135335731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 135435731357SCaroline Tice int num_signals_set = 0; 135535731357SCaroline Tice 135610ad7993SCaroline Tice if (num_args > 0) 135710ad7993SCaroline Tice { 135835731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 135935731357SCaroline Tice { 136035731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 136135731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 136235731357SCaroline Tice { 136310ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 136435731357SCaroline Tice // the value is either 0 or 1. 136535731357SCaroline Tice if (stop_action != -1) 136635731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 136735731357SCaroline Tice if (pass_action != -1) 136835731357SCaroline Tice { 136910ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 137010ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 137135731357SCaroline Tice } 137235731357SCaroline Tice if (notify_action != -1) 137335731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 137435731357SCaroline Tice ++num_signals_set; 137535731357SCaroline Tice } 137635731357SCaroline Tice else 137735731357SCaroline Tice { 137835731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 137935731357SCaroline Tice } 138035731357SCaroline Tice } 138110ad7993SCaroline Tice } 138210ad7993SCaroline Tice else 138310ad7993SCaroline Tice { 138410ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 138510ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 138610ad7993SCaroline Tice { 138710ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 138810ad7993SCaroline Tice { 138910ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 139010ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 139110ad7993SCaroline Tice { 139210ad7993SCaroline Tice if (notify_action != -1) 139310ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 139410ad7993SCaroline Tice if (stop_action != -1) 139510ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 139610ad7993SCaroline Tice if (pass_action != -1) 139710ad7993SCaroline Tice { 139810ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 139910ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 140010ad7993SCaroline Tice } 140110ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 140210ad7993SCaroline Tice } 140310ad7993SCaroline Tice } 140410ad7993SCaroline Tice } 140510ad7993SCaroline Tice } 140610ad7993SCaroline Tice 140710ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 140835731357SCaroline Tice 140935731357SCaroline Tice if (num_signals_set > 0) 141035731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 141135731357SCaroline Tice else 141235731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 141335731357SCaroline Tice 141435731357SCaroline Tice return result.Succeeded(); 141535731357SCaroline Tice } 141635731357SCaroline Tice 141735731357SCaroline Tice protected: 141835731357SCaroline Tice 141935731357SCaroline Tice CommandOptions m_options; 142035731357SCaroline Tice }; 142135731357SCaroline Tice 142235731357SCaroline Tice lldb::OptionDefinition 142335731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 142435731357SCaroline Tice { 142535731357SCaroline 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." }, 142635731357SCaroline 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." }, 142735731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 142835731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 142935731357SCaroline Tice }; 143035731357SCaroline Tice 143135731357SCaroline Tice //------------------------------------------------------------------------- 143230fdc8d8SChris Lattner // CommandObjectMultiwordProcess 143330fdc8d8SChris Lattner //------------------------------------------------------------------------- 143430fdc8d8SChris Lattner 14356611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1436a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1437a7015092SGreg Clayton "process", 143830fdc8d8SChris Lattner "A set of commands for operating on a process.", 143930fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 144030fdc8d8SChris Lattner { 1441a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1442a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1443a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1444a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1445a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 144635731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1447a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1448a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1449a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 145030fdc8d8SChris Lattner } 145130fdc8d8SChris Lattner 145230fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 145330fdc8d8SChris Lattner { 145430fdc8d8SChris Lattner } 145530fdc8d8SChris Lattner 1456