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; 65913c4fa1SGreg Clayton case 't': 66913c4fa1SGreg Clayton if (option_arg && option_arg[0]) 67913c4fa1SGreg Clayton tty_name.assign (option_arg); 68913c4fa1SGreg Clayton in_new_tty = true; 69913c4fa1SGreg Clayton break; 7030fdc8d8SChris Lattner default: 7130fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 7230fdc8d8SChris Lattner break; 7330fdc8d8SChris Lattner 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner return error; 7630fdc8d8SChris Lattner } 7730fdc8d8SChris Lattner 7830fdc8d8SChris Lattner void 7930fdc8d8SChris Lattner ResetOptionValues () 8030fdc8d8SChris Lattner { 8130fdc8d8SChris Lattner Options::ResetOptionValues(); 8230fdc8d8SChris Lattner stop_at_entry = false; 8319388cfcSGreg Clayton in_new_tty = false; 84913c4fa1SGreg Clayton tty_name.clear(); 8530fdc8d8SChris Lattner stdin_path.clear(); 8630fdc8d8SChris Lattner stdout_path.clear(); 8730fdc8d8SChris Lattner stderr_path.clear(); 8830fdc8d8SChris Lattner plugin_name.clear(); 8930fdc8d8SChris Lattner } 9030fdc8d8SChris Lattner 9130fdc8d8SChris Lattner const lldb::OptionDefinition* 9230fdc8d8SChris Lattner GetDefinitions () 9330fdc8d8SChris Lattner { 9430fdc8d8SChris Lattner return g_option_table; 9530fdc8d8SChris Lattner } 9630fdc8d8SChris Lattner 9730fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 9830fdc8d8SChris Lattner 9930fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 10030fdc8d8SChris Lattner 10130fdc8d8SChris Lattner // Instance variables to hold the values for command options. 10230fdc8d8SChris Lattner 10330fdc8d8SChris Lattner bool stop_at_entry; 10419388cfcSGreg Clayton bool in_new_tty; 105913c4fa1SGreg Clayton std::string tty_name; 10630fdc8d8SChris Lattner std::string stderr_path; 10730fdc8d8SChris Lattner std::string stdin_path; 10830fdc8d8SChris Lattner std::string stdout_path; 10930fdc8d8SChris Lattner std::string plugin_name; 11030fdc8d8SChris Lattner 11130fdc8d8SChris Lattner }; 11230fdc8d8SChris Lattner 113a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 114a7015092SGreg Clayton CommandObject (interpreter, 115a7015092SGreg Clayton "process launch", 116e3d26315SCaroline Tice "Launch the executable in the debugger.", 117405fe67fSCaroline Tice NULL) 11830fdc8d8SChris Lattner { 119405fe67fSCaroline Tice CommandArgumentEntry arg; 120405fe67fSCaroline Tice CommandArgumentData run_args_arg; 121405fe67fSCaroline Tice 122405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 123405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 124405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 125405fe67fSCaroline Tice 126405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 127405fe67fSCaroline Tice arg.push_back (run_args_arg); 128405fe67fSCaroline Tice 129405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 130405fe67fSCaroline Tice m_arguments.push_back (arg); 13130fdc8d8SChris Lattner } 13230fdc8d8SChris Lattner 13330fdc8d8SChris Lattner 13430fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 13530fdc8d8SChris Lattner { 13630fdc8d8SChris Lattner } 13730fdc8d8SChris Lattner 13830fdc8d8SChris Lattner Options * 13930fdc8d8SChris Lattner GetOptions () 14030fdc8d8SChris Lattner { 14130fdc8d8SChris Lattner return &m_options; 14230fdc8d8SChris Lattner } 14330fdc8d8SChris Lattner 14430fdc8d8SChris Lattner bool 14505faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 14630fdc8d8SChris Lattner { 147a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 14830fdc8d8SChris Lattner 14930fdc8d8SChris Lattner if (target == NULL) 15030fdc8d8SChris Lattner { 15130fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 15230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 15330fdc8d8SChris Lattner return false; 15430fdc8d8SChris Lattner } 15530fdc8d8SChris Lattner 15630fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 15730fdc8d8SChris Lattner char filename[PATH_MAX]; 15819388cfcSGreg Clayton const Module *exe_module = target->GetExecutableModule().get(); 15930fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 16030fdc8d8SChris Lattner 161a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 162a7015092SGreg Clayton if (process && process->IsAlive()) 16330fdc8d8SChris Lattner { 16430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", 16530fdc8d8SChris Lattner process->GetID()); 16630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 16730fdc8d8SChris Lattner return false; 16830fdc8d8SChris Lattner } 16930fdc8d8SChris Lattner 17030fdc8d8SChris Lattner const char *plugin_name; 17130fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 17230fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 17330fdc8d8SChris Lattner else 17430fdc8d8SChris Lattner plugin_name = NULL; 17530fdc8d8SChris Lattner 176a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 17730fdc8d8SChris Lattner 178a7015092SGreg Clayton if (process == NULL) 1793df9a8dfSCaroline Tice { 18043a8c39bSCaroline Tice result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 181a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 182a7015092SGreg Clayton return false; 1833df9a8dfSCaroline Tice } 1843df9a8dfSCaroline Tice 185a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 186a7015092SGreg Clayton // might have been set using the "run-args" set variable. 18730fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 18830fdc8d8SChris Lattner { 189a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 190a7015092SGreg Clayton launch_args = process->GetRunArguments(); 19130fdc8d8SChris Lattner } 19230fdc8d8SChris Lattner 19319388cfcSGreg Clayton if (m_options.in_new_tty) 19419388cfcSGreg Clayton { 19519388cfcSGreg Clayton char exec_file_path[PATH_MAX]; 19619388cfcSGreg Clayton if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 19719388cfcSGreg Clayton { 19819388cfcSGreg Clayton launch_args.InsertArgumentAtIndex(0, exec_file_path); 19919388cfcSGreg Clayton } 20019388cfcSGreg Clayton else 20119388cfcSGreg Clayton { 20219388cfcSGreg Clayton result.AppendError("invalid executable"); 20319388cfcSGreg Clayton result.SetStatus (eReturnStatusFailed); 20419388cfcSGreg Clayton return false; 20519388cfcSGreg Clayton } 20619388cfcSGreg Clayton } 20719388cfcSGreg Clayton 208a7015092SGreg Clayton Args environment; 20930fdc8d8SChris Lattner 210a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 211a7015092SGreg Clayton 212a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 213a7015092SGreg Clayton 214a7015092SGreg Clayton if (process->GetDisableASLR()) 215a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 216a7015092SGreg Clayton 21719388cfcSGreg Clayton const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 21819388cfcSGreg Clayton const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 21930fdc8d8SChris Lattner 22019388cfcSGreg Clayton Error error; 22119388cfcSGreg Clayton 22219388cfcSGreg Clayton if (m_options.in_new_tty) 22319388cfcSGreg Clayton { 22419388cfcSGreg Clayton 225913c4fa1SGreg Clayton lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(), 226913c4fa1SGreg Clayton inferior_argv, 22719388cfcSGreg Clayton inferior_envp, 22819388cfcSGreg Clayton &exe_module->GetArchitecture(), 22919388cfcSGreg Clayton true, 23019388cfcSGreg Clayton process->GetDisableASLR()); 23119388cfcSGreg Clayton 2323fcbed6bSGreg Clayton if (pid != LLDB_INVALID_PROCESS_ID) 2333fcbed6bSGreg Clayton error = process->Attach (pid); 23419388cfcSGreg Clayton } 23519388cfcSGreg Clayton else 23619388cfcSGreg Clayton { 23730fdc8d8SChris Lattner const char * stdin_path = NULL; 23830fdc8d8SChris Lattner const char * stdout_path = NULL; 23930fdc8d8SChris Lattner const char * stderr_path = NULL; 24030fdc8d8SChris Lattner 241a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 242a7015092SGreg Clayton if (m_options.stdin_path.empty() && 24330fdc8d8SChris Lattner m_options.stdout_path.empty() && 244a7015092SGreg Clayton m_options.stderr_path.empty()) 24530fdc8d8SChris Lattner { 246a7015092SGreg Clayton // No standard file handles were given on the command line, check 247a7015092SGreg Clayton // with the process object in case they were give using "set settings" 248a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 249a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 250a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 251a7015092SGreg Clayton } 252a7015092SGreg Clayton else 253a7015092SGreg Clayton { 254a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 255a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 256a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 25730fdc8d8SChris Lattner } 25830fdc8d8SChris Lattner 259a7015092SGreg Clayton if (stdin_path == NULL) 260a7015092SGreg Clayton stdin_path = "/dev/null"; 261a7015092SGreg Clayton if (stdout_path == NULL) 262a7015092SGreg Clayton stdout_path = "/dev/null"; 263a7015092SGreg Clayton if (stderr_path == NULL) 264a7015092SGreg Clayton stderr_path = "/dev/null"; 265a7015092SGreg Clayton 26619388cfcSGreg Clayton error = process->Launch (inferior_argv, 26719388cfcSGreg Clayton inferior_envp, 268f681b94fSGreg Clayton launch_flags, 26930fdc8d8SChris Lattner stdin_path, 27030fdc8d8SChris Lattner stdout_path, 27119388cfcSGreg Clayton stderr_path); 27219388cfcSGreg Clayton } 27330fdc8d8SChris Lattner 27430fdc8d8SChris Lattner if (error.Success()) 27530fdc8d8SChris Lattner { 27619388cfcSGreg Clayton const char *archname = exe_module->GetArchitecture().AsCString(); 27719388cfcSGreg Clayton 27819388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 27905faeb71SGreg Clayton result.SetDidChangeProcessState (true); 28030fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 28130fdc8d8SChris Lattner { 28205faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 28330fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 28430fdc8d8SChris Lattner 28530fdc8d8SChris Lattner if (state == eStateStopped) 28630fdc8d8SChris Lattner { 28705faeb71SGreg Clayton error = process->Resume(); 28805faeb71SGreg Clayton if (error.Success()) 28905faeb71SGreg Clayton { 29005faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 29130fdc8d8SChris Lattner if (synchronous_execution) 29230fdc8d8SChris Lattner { 29305faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 29430fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 29505faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 29605faeb71SGreg Clayton } 29705faeb71SGreg Clayton else 29805faeb71SGreg Clayton { 29905faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 30005faeb71SGreg Clayton } 30105faeb71SGreg Clayton } 30230fdc8d8SChris Lattner } 30330fdc8d8SChris Lattner } 30430fdc8d8SChris Lattner } 30530fdc8d8SChris Lattner 30630fdc8d8SChris Lattner return result.Succeeded(); 30730fdc8d8SChris Lattner } 30830fdc8d8SChris Lattner 309ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 310ebc09c36SJim Ingham { 311ebc09c36SJim Ingham // No repeat for "process launch"... 312ebc09c36SJim Ingham return ""; 313ebc09c36SJim Ingham } 314ebc09c36SJim Ingham 31530fdc8d8SChris Lattner protected: 31630fdc8d8SChris Lattner 31730fdc8d8SChris Lattner CommandOptions m_options; 31830fdc8d8SChris Lattner }; 31930fdc8d8SChris Lattner 32030fdc8d8SChris Lattner 32119388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1 32219388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2 32319388cfcSGreg Clayton 32430fdc8d8SChris Lattner lldb::OptionDefinition 32530fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 32630fdc8d8SChris Lattner { 32719388cfcSGreg 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."}, 32819388cfcSGreg Clayton { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 32919388cfcSGreg Clayton { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 33019388cfcSGreg Clayton { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 33119388cfcSGreg Clayton { SET1 | SET2, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 332913c4fa1SGreg 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."}, 333deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 33430fdc8d8SChris Lattner }; 33530fdc8d8SChris Lattner 33619388cfcSGreg Clayton #undef SET1 33719388cfcSGreg Clayton #undef SET2 33830fdc8d8SChris Lattner 33930fdc8d8SChris Lattner //------------------------------------------------------------------------- 34030fdc8d8SChris Lattner // CommandObjectProcessAttach 34130fdc8d8SChris Lattner //------------------------------------------------------------------------- 34230fdc8d8SChris Lattner 34330fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 34430fdc8d8SChris Lattner { 34530fdc8d8SChris Lattner public: 34630fdc8d8SChris Lattner 34730fdc8d8SChris Lattner class CommandOptions : public Options 34830fdc8d8SChris Lattner { 34930fdc8d8SChris Lattner public: 35030fdc8d8SChris Lattner 35130fdc8d8SChris Lattner CommandOptions () : 35230fdc8d8SChris Lattner Options() 35330fdc8d8SChris Lattner { 35430fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 35530fdc8d8SChris Lattner ResetOptionValues (); 35630fdc8d8SChris Lattner } 35730fdc8d8SChris Lattner 35830fdc8d8SChris Lattner ~CommandOptions () 35930fdc8d8SChris Lattner { 36030fdc8d8SChris Lattner } 36130fdc8d8SChris Lattner 36230fdc8d8SChris Lattner Error 36330fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 36430fdc8d8SChris Lattner { 36530fdc8d8SChris Lattner Error error; 36630fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 36730fdc8d8SChris Lattner bool success = false; 36830fdc8d8SChris Lattner switch (short_option) 36930fdc8d8SChris Lattner { 37030fdc8d8SChris Lattner case 'p': 37130fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 37230fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 37330fdc8d8SChris Lattner { 37430fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 37530fdc8d8SChris Lattner } 37630fdc8d8SChris Lattner break; 37730fdc8d8SChris Lattner 37830fdc8d8SChris Lattner case 'P': 37930fdc8d8SChris Lattner plugin_name = option_arg; 38030fdc8d8SChris Lattner break; 38130fdc8d8SChris Lattner 38230fdc8d8SChris Lattner case 'n': 38330fdc8d8SChris Lattner name.assign(option_arg); 38430fdc8d8SChris Lattner break; 38530fdc8d8SChris Lattner 38630fdc8d8SChris Lattner case 'w': 38730fdc8d8SChris Lattner waitfor = true; 38830fdc8d8SChris Lattner break; 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner default: 39130fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 39230fdc8d8SChris Lattner break; 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner return error; 39530fdc8d8SChris Lattner } 39630fdc8d8SChris Lattner 39730fdc8d8SChris Lattner void 39830fdc8d8SChris Lattner ResetOptionValues () 39930fdc8d8SChris Lattner { 40030fdc8d8SChris Lattner Options::ResetOptionValues(); 40130fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 40230fdc8d8SChris Lattner name.clear(); 40330fdc8d8SChris Lattner waitfor = false; 40430fdc8d8SChris Lattner } 40530fdc8d8SChris Lattner 40630fdc8d8SChris Lattner const lldb::OptionDefinition* 40730fdc8d8SChris Lattner GetDefinitions () 40830fdc8d8SChris Lattner { 40930fdc8d8SChris Lattner return g_option_table; 41030fdc8d8SChris Lattner } 41130fdc8d8SChris Lattner 4125aee162fSJim Ingham virtual bool 413a7015092SGreg Clayton HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 4145aee162fSJim Ingham Args &input, 4155aee162fSJim Ingham int cursor_index, 4165aee162fSJim Ingham int char_pos, 4175aee162fSJim Ingham OptionElementVector &opt_element_vector, 4185aee162fSJim Ingham int opt_element_index, 4195aee162fSJim Ingham int match_start_point, 4205aee162fSJim Ingham int max_return_elements, 4215aee162fSJim Ingham bool &word_complete, 4225aee162fSJim Ingham StringList &matches) 4235aee162fSJim Ingham { 4245aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4255aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4265aee162fSJim Ingham 4275aee162fSJim Ingham // We are only completing the name option for now... 4285aee162fSJim Ingham 4295aee162fSJim Ingham const lldb::OptionDefinition *opt_defs = GetDefinitions(); 4305aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4315aee162fSJim Ingham { 4325aee162fSJim Ingham // Are we in the name? 4335aee162fSJim Ingham 4345aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4355aee162fSJim Ingham // use the default plugin. 436a7015092SGreg Clayton Process *process = interpeter.GetDebugger().GetExecutionContext().process; 4375aee162fSJim Ingham bool need_to_delete_process = false; 4385aee162fSJim Ingham 4395aee162fSJim Ingham const char *partial_name = NULL; 4405aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4415aee162fSJim Ingham 4425aee162fSJim Ingham if (process && process->IsAlive()) 4435aee162fSJim Ingham return true; 4445aee162fSJim Ingham 445a7015092SGreg Clayton Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 4465aee162fSJim Ingham if (target == NULL) 4475aee162fSJim Ingham { 4485aee162fSJim Ingham // No target has been set yet, for now do host completion. Otherwise I don't know how we would 4495aee162fSJim Ingham // figure out what the right target to use is... 4505aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4515aee162fSJim Ingham Host::ListProcessesMatchingName (partial_name, matches, pids); 4525aee162fSJim Ingham return true; 4535aee162fSJim Ingham } 4545aee162fSJim Ingham if (!process) 4555aee162fSJim Ingham { 456a7015092SGreg Clayton process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 4575aee162fSJim Ingham need_to_delete_process = true; 4585aee162fSJim Ingham } 4595aee162fSJim Ingham 4605aee162fSJim Ingham if (process) 4615aee162fSJim Ingham { 4625aee162fSJim Ingham matches.Clear(); 4635aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4645aee162fSJim Ingham process->ListProcessesMatchingName (NULL, matches, pids); 4655aee162fSJim Ingham if (need_to_delete_process) 4665aee162fSJim Ingham target->DeleteCurrentProcess(); 4675aee162fSJim Ingham return true; 4685aee162fSJim Ingham } 4695aee162fSJim Ingham } 4705aee162fSJim Ingham 4715aee162fSJim Ingham return false; 4725aee162fSJim Ingham } 4735aee162fSJim Ingham 47430fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 47530fdc8d8SChris Lattner 47630fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 47730fdc8d8SChris Lattner 47830fdc8d8SChris Lattner // Instance variables to hold the values for command options. 47930fdc8d8SChris Lattner 48030fdc8d8SChris Lattner lldb::pid_t pid; 48130fdc8d8SChris Lattner std::string plugin_name; 48230fdc8d8SChris Lattner std::string name; 48330fdc8d8SChris Lattner bool waitfor; 48430fdc8d8SChris Lattner }; 48530fdc8d8SChris Lattner 486a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 487a7015092SGreg Clayton CommandObject (interpreter, 488a7015092SGreg Clayton "process attach", 489e3d26315SCaroline Tice "Attach to a process.", 4905aee162fSJim Ingham "process attach <cmd-options>") 4915aee162fSJim Ingham { 4925aee162fSJim Ingham } 4935aee162fSJim Ingham 4945aee162fSJim Ingham ~CommandObjectProcessAttach () 4955aee162fSJim Ingham { 4965aee162fSJim Ingham } 4975aee162fSJim Ingham 4985aee162fSJim Ingham bool 499a7015092SGreg Clayton Execute (Args& command, 5005aee162fSJim Ingham CommandReturnObject &result) 5015aee162fSJim Ingham { 502a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5035aee162fSJim Ingham 504a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 5055aee162fSJim Ingham if (process) 5065aee162fSJim Ingham { 5075aee162fSJim Ingham if (process->IsAlive()) 5085aee162fSJim Ingham { 5095aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 5105aee162fSJim Ingham process->GetID()); 5115aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5125aee162fSJim Ingham return false; 5135aee162fSJim Ingham } 5145aee162fSJim Ingham } 5155aee162fSJim Ingham 5165aee162fSJim Ingham if (target == NULL) 5175aee162fSJim Ingham { 5185aee162fSJim Ingham // If there isn't a current target create one. 5195aee162fSJim Ingham TargetSP new_target_sp; 5205aee162fSJim Ingham FileSpec emptyFileSpec; 5215aee162fSJim Ingham ArchSpec emptyArchSpec; 5225aee162fSJim Ingham Error error; 5235aee162fSJim Ingham 524a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 5255aee162fSJim Ingham emptyFileSpec, 5265aee162fSJim Ingham emptyArchSpec, 5275aee162fSJim Ingham NULL, 5285aee162fSJim Ingham false, 5295aee162fSJim Ingham new_target_sp); 5305aee162fSJim Ingham target = new_target_sp.get(); 5315aee162fSJim Ingham if (target == NULL || error.Fail()) 5325aee162fSJim Ingham { 5335aee162fSJim Ingham result.AppendError(error.AsCString("Error creating empty target")); 5345aee162fSJim Ingham return false; 5355aee162fSJim Ingham } 536a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5375aee162fSJim Ingham } 5385aee162fSJim Ingham 5395aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5405aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5415aee162fSJim Ingham 5425aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5435aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5445aee162fSJim Ingham 5455aee162fSJim Ingham if (command.GetArgumentCount()) 5465aee162fSJim Ingham { 5475aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5485aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5495aee162fSJim Ingham } 5505aee162fSJim Ingham else 5515aee162fSJim Ingham { 5525aee162fSJim Ingham const char *plugin_name = NULL; 5535aee162fSJim Ingham 5545aee162fSJim Ingham if (!m_options.plugin_name.empty()) 5555aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 5565aee162fSJim Ingham 557a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 5585aee162fSJim Ingham 5595aee162fSJim Ingham if (process) 5605aee162fSJim Ingham { 5615aee162fSJim Ingham Error error; 5625aee162fSJim Ingham int attach_pid = m_options.pid; 5635aee162fSJim Ingham 5643a0b9cdfSJim Ingham const char *wait_name = NULL; 5653a0b9cdfSJim Ingham 5665aee162fSJim Ingham if (m_options.name.empty()) 5675aee162fSJim Ingham { 5683a0b9cdfSJim Ingham if (old_exec_module_sp) 5693a0b9cdfSJim Ingham { 5703a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 5713a0b9cdfSJim Ingham } 5725aee162fSJim Ingham } 5735aee162fSJim Ingham else 5745aee162fSJim Ingham { 5753a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 5763a0b9cdfSJim Ingham } 5773a0b9cdfSJim Ingham 5783a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 5793a0b9cdfSJim Ingham if (m_options.waitfor) 5803a0b9cdfSJim Ingham { 5813a0b9cdfSJim Ingham 5823a0b9cdfSJim Ingham if (wait_name == NULL) 5833a0b9cdfSJim Ingham { 5843a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 5853a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 5863a0b9cdfSJim Ingham return false; 5873a0b9cdfSJim Ingham } 5883a0b9cdfSJim Ingham 589a7015092SGreg Clayton m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 5903a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 5915aee162fSJim Ingham if (error.Success()) 5925aee162fSJim Ingham { 5935aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 5945aee162fSJim Ingham } 5955aee162fSJim Ingham else 5965aee162fSJim Ingham { 5975aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 5983a0b9cdfSJim Ingham wait_name, 5995aee162fSJim Ingham error.AsCString()); 6005aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6015aee162fSJim Ingham return false; 6025aee162fSJim Ingham } 6035aee162fSJim Ingham } 6045aee162fSJim Ingham else 6055aee162fSJim Ingham { 6065aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 6075aee162fSJim Ingham // processes with this pid. 6085aee162fSJim Ingham 6093a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 6105aee162fSJim Ingham { 6115aee162fSJim Ingham std::vector<lldb::pid_t> pids; 6125aee162fSJim Ingham StringList matches; 6135aee162fSJim Ingham 6143a0b9cdfSJim Ingham process->ListProcessesMatchingName(wait_name, matches, pids); 6155aee162fSJim Ingham if (matches.GetSize() > 1) 6165aee162fSJim Ingham { 6173a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 6185aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6195aee162fSJim Ingham return false; 6205aee162fSJim Ingham } 6215aee162fSJim Ingham else if (matches.GetSize() == 0) 6225aee162fSJim Ingham { 6233a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 6245aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6255aee162fSJim Ingham return false; 6265aee162fSJim Ingham } 6275aee162fSJim Ingham else 6285aee162fSJim Ingham { 6295aee162fSJim Ingham attach_pid = pids[0]; 6305aee162fSJim Ingham } 6315aee162fSJim Ingham 6325aee162fSJim Ingham } 6335aee162fSJim Ingham 6345aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 6355aee162fSJim Ingham { 6365aee162fSJim Ingham error = process->Attach (attach_pid); 6375aee162fSJim Ingham if (error.Success()) 6385aee162fSJim Ingham { 6395aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6405aee162fSJim Ingham } 6415aee162fSJim Ingham else 6425aee162fSJim Ingham { 6435aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 6445aee162fSJim Ingham attach_pid, 6455aee162fSJim Ingham error.AsCString()); 6465aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6475aee162fSJim Ingham } 6485aee162fSJim Ingham } 6495aee162fSJim Ingham else 6505aee162fSJim Ingham { 6515aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 6525aee162fSJim Ingham attach_pid, 6535aee162fSJim Ingham error.AsCString()); 6545aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6555aee162fSJim Ingham 6565aee162fSJim Ingham } 6575aee162fSJim Ingham } 6585aee162fSJim Ingham } 6595aee162fSJim Ingham } 6605aee162fSJim Ingham 6615aee162fSJim Ingham if (result.Succeeded()) 6625aee162fSJim Ingham { 6635aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 6645aee162fSJim Ingham if (!old_exec_module_sp) 6655aee162fSJim Ingham { 6665aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6675aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 6685aee162fSJim Ingham 6695aee162fSJim Ingham result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 6705aee162fSJim Ingham new_path); 6715aee162fSJim Ingham } 6725aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 6735aee162fSJim Ingham { 6745aee162fSJim Ingham char old_path[PATH_MAX + 1]; 6755aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6765aee162fSJim Ingham 6775aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 6785aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 6795aee162fSJim Ingham 6805aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6815aee162fSJim Ingham old_path, new_path); 6825aee162fSJim Ingham } 6835aee162fSJim Ingham 6845aee162fSJim Ingham if (!old_arch_spec.IsValid()) 6855aee162fSJim Ingham { 6865aee162fSJim Ingham result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 6875aee162fSJim Ingham } 6885aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 6895aee162fSJim Ingham { 6905aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 6915aee162fSJim Ingham old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 6925aee162fSJim Ingham } 6935aee162fSJim Ingham } 6945aee162fSJim Ingham return result.Succeeded(); 6955aee162fSJim Ingham } 6965aee162fSJim Ingham 6975aee162fSJim Ingham Options * 6985aee162fSJim Ingham GetOptions () 6995aee162fSJim Ingham { 7005aee162fSJim Ingham return &m_options; 7015aee162fSJim Ingham } 7025aee162fSJim Ingham 70330fdc8d8SChris Lattner protected: 70430fdc8d8SChris Lattner 70530fdc8d8SChris Lattner CommandOptions m_options; 70630fdc8d8SChris Lattner }; 70730fdc8d8SChris Lattner 70830fdc8d8SChris Lattner 70930fdc8d8SChris Lattner lldb::OptionDefinition 71030fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 71130fdc8d8SChris Lattner { 712deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 713deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 714deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 715deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 716deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 71730fdc8d8SChris Lattner }; 71830fdc8d8SChris Lattner 71930fdc8d8SChris Lattner //------------------------------------------------------------------------- 72030fdc8d8SChris Lattner // CommandObjectProcessContinue 72130fdc8d8SChris Lattner //------------------------------------------------------------------------- 72230fdc8d8SChris Lattner 72330fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 72430fdc8d8SChris Lattner { 72530fdc8d8SChris Lattner public: 72630fdc8d8SChris Lattner 727a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 728a7015092SGreg Clayton CommandObject (interpreter, 729a7015092SGreg Clayton "process continue", 730e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 73130fdc8d8SChris Lattner "process continue", 73230fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 73330fdc8d8SChris Lattner { 73430fdc8d8SChris Lattner } 73530fdc8d8SChris Lattner 73630fdc8d8SChris Lattner 73730fdc8d8SChris Lattner ~CommandObjectProcessContinue () 73830fdc8d8SChris Lattner { 73930fdc8d8SChris Lattner } 74030fdc8d8SChris Lattner 74130fdc8d8SChris Lattner bool 742a7015092SGreg Clayton Execute (Args& command, 74330fdc8d8SChris Lattner CommandReturnObject &result) 74430fdc8d8SChris Lattner { 745a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 746a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 74730fdc8d8SChris Lattner 74830fdc8d8SChris Lattner if (process == NULL) 74930fdc8d8SChris Lattner { 75030fdc8d8SChris Lattner result.AppendError ("no process to continue"); 75130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 75230fdc8d8SChris Lattner return false; 75330fdc8d8SChris Lattner } 75430fdc8d8SChris Lattner 75530fdc8d8SChris Lattner StateType state = process->GetState(); 75630fdc8d8SChris Lattner if (state == eStateStopped) 75730fdc8d8SChris Lattner { 75830fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 75930fdc8d8SChris Lattner { 76030fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 76130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 76230fdc8d8SChris Lattner return false; 76330fdc8d8SChris Lattner } 76430fdc8d8SChris Lattner 76530fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 76630fdc8d8SChris Lattner 76730fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 76830fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 76930fdc8d8SChris Lattner { 77030fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 77130fdc8d8SChris Lattner } 77230fdc8d8SChris Lattner 77330fdc8d8SChris Lattner Error error(process->Resume()); 77430fdc8d8SChris Lattner if (error.Success()) 77530fdc8d8SChris Lattner { 77619388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 77730fdc8d8SChris Lattner if (synchronous_execution) 77830fdc8d8SChris Lattner { 779b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 78030fdc8d8SChris Lattner 78130fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 78230fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 78330fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 78430fdc8d8SChris Lattner } 78530fdc8d8SChris Lattner else 78630fdc8d8SChris Lattner { 78730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 78830fdc8d8SChris Lattner } 78930fdc8d8SChris Lattner } 79030fdc8d8SChris Lattner else 79130fdc8d8SChris Lattner { 79230fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 79330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 79430fdc8d8SChris Lattner } 79530fdc8d8SChris Lattner } 79630fdc8d8SChris Lattner else 79730fdc8d8SChris Lattner { 79830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 79930fdc8d8SChris Lattner StateAsCString(state)); 80030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 80130fdc8d8SChris Lattner } 80230fdc8d8SChris Lattner return result.Succeeded(); 80330fdc8d8SChris Lattner } 80430fdc8d8SChris Lattner }; 80530fdc8d8SChris Lattner 80630fdc8d8SChris Lattner //------------------------------------------------------------------------- 80730fdc8d8SChris Lattner // CommandObjectProcessDetach 80830fdc8d8SChris Lattner //------------------------------------------------------------------------- 80930fdc8d8SChris Lattner 81030fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 81130fdc8d8SChris Lattner { 81230fdc8d8SChris Lattner public: 81330fdc8d8SChris Lattner 814a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 815a7015092SGreg Clayton CommandObject (interpreter, 816a7015092SGreg Clayton "process detach", 817e3d26315SCaroline Tice "Detach from the current process being debugged.", 81830fdc8d8SChris Lattner "process detach", 81930fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 82030fdc8d8SChris Lattner { 82130fdc8d8SChris Lattner } 82230fdc8d8SChris Lattner 82330fdc8d8SChris Lattner ~CommandObjectProcessDetach () 82430fdc8d8SChris Lattner { 82530fdc8d8SChris Lattner } 82630fdc8d8SChris Lattner 82730fdc8d8SChris Lattner bool 828a7015092SGreg Clayton Execute (Args& command, 82930fdc8d8SChris Lattner CommandReturnObject &result) 83030fdc8d8SChris Lattner { 831a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 83230fdc8d8SChris Lattner if (process == NULL) 83330fdc8d8SChris Lattner { 83430fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 83530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 83630fdc8d8SChris Lattner return false; 83730fdc8d8SChris Lattner } 83830fdc8d8SChris Lattner 839*5d7be2e6SCaroline Tice result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID()); 84030fdc8d8SChris Lattner Error error (process->Detach()); 84130fdc8d8SChris Lattner if (error.Success()) 84230fdc8d8SChris Lattner { 84330fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 84430fdc8d8SChris Lattner } 84530fdc8d8SChris Lattner else 84630fdc8d8SChris Lattner { 84730fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 84830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 84930fdc8d8SChris Lattner return false; 85030fdc8d8SChris Lattner } 85130fdc8d8SChris Lattner return result.Succeeded(); 85230fdc8d8SChris Lattner } 85330fdc8d8SChris Lattner }; 85430fdc8d8SChris Lattner 85530fdc8d8SChris Lattner //------------------------------------------------------------------------- 85630fdc8d8SChris Lattner // CommandObjectProcessSignal 85730fdc8d8SChris Lattner //------------------------------------------------------------------------- 85830fdc8d8SChris Lattner 85930fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 86030fdc8d8SChris Lattner { 86130fdc8d8SChris Lattner public: 86230fdc8d8SChris Lattner 863a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 864a7015092SGreg Clayton CommandObject (interpreter, 865a7015092SGreg Clayton "process signal", 866e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 867405fe67fSCaroline Tice NULL) 86830fdc8d8SChris Lattner { 869405fe67fSCaroline Tice CommandArgumentEntry arg; 870405fe67fSCaroline Tice CommandArgumentData signal_arg; 871405fe67fSCaroline Tice 872405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 873c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 874405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 875405fe67fSCaroline Tice 876405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 877405fe67fSCaroline Tice arg.push_back (signal_arg); 878405fe67fSCaroline Tice 879405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 880405fe67fSCaroline Tice m_arguments.push_back (arg); 88130fdc8d8SChris Lattner } 88230fdc8d8SChris Lattner 88330fdc8d8SChris Lattner ~CommandObjectProcessSignal () 88430fdc8d8SChris Lattner { 88530fdc8d8SChris Lattner } 88630fdc8d8SChris Lattner 88730fdc8d8SChris Lattner bool 888a7015092SGreg Clayton Execute (Args& command, 88930fdc8d8SChris Lattner CommandReturnObject &result) 89030fdc8d8SChris Lattner { 891a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 89230fdc8d8SChris Lattner if (process == NULL) 89330fdc8d8SChris Lattner { 89430fdc8d8SChris Lattner result.AppendError ("no process to signal"); 89530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 89630fdc8d8SChris Lattner return false; 89730fdc8d8SChris Lattner } 89830fdc8d8SChris Lattner 89930fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 90030fdc8d8SChris Lattner { 901237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 902237cd906SGreg Clayton 903237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 904237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 905237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 906237cd906SGreg Clayton else 907237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 908237cd906SGreg Clayton 909237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 91030fdc8d8SChris Lattner { 91130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 91230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 91330fdc8d8SChris Lattner } 91430fdc8d8SChris Lattner else 91530fdc8d8SChris Lattner { 91630fdc8d8SChris Lattner Error error (process->Signal (signo)); 91730fdc8d8SChris Lattner if (error.Success()) 91830fdc8d8SChris Lattner { 91930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 92030fdc8d8SChris Lattner } 92130fdc8d8SChris Lattner else 92230fdc8d8SChris Lattner { 92330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 92430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 92530fdc8d8SChris Lattner } 92630fdc8d8SChris Lattner } 92730fdc8d8SChris Lattner } 92830fdc8d8SChris Lattner else 92930fdc8d8SChris Lattner { 93030fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 93130fdc8d8SChris Lattner m_cmd_syntax.c_str()); 93230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 93330fdc8d8SChris Lattner } 93430fdc8d8SChris Lattner return result.Succeeded(); 93530fdc8d8SChris Lattner } 93630fdc8d8SChris Lattner }; 93730fdc8d8SChris Lattner 93830fdc8d8SChris Lattner 93930fdc8d8SChris Lattner //------------------------------------------------------------------------- 94030fdc8d8SChris Lattner // CommandObjectProcessInterrupt 94130fdc8d8SChris Lattner //------------------------------------------------------------------------- 94230fdc8d8SChris Lattner 94330fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 94430fdc8d8SChris Lattner { 94530fdc8d8SChris Lattner public: 94630fdc8d8SChris Lattner 94730fdc8d8SChris Lattner 948a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 949a7015092SGreg Clayton CommandObject (interpreter, 950a7015092SGreg Clayton "process interrupt", 951e3d26315SCaroline Tice "Interrupt the current process being debugged.", 95230fdc8d8SChris Lattner "process interrupt", 95330fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 95430fdc8d8SChris Lattner { 95530fdc8d8SChris Lattner } 95630fdc8d8SChris Lattner 95730fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 95830fdc8d8SChris Lattner { 95930fdc8d8SChris Lattner } 96030fdc8d8SChris Lattner 96130fdc8d8SChris Lattner bool 962a7015092SGreg Clayton Execute (Args& command, 96330fdc8d8SChris Lattner CommandReturnObject &result) 96430fdc8d8SChris Lattner { 965a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 96630fdc8d8SChris Lattner if (process == NULL) 96730fdc8d8SChris Lattner { 96830fdc8d8SChris Lattner result.AppendError ("no process to halt"); 96930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 97030fdc8d8SChris Lattner return false; 97130fdc8d8SChris Lattner } 97230fdc8d8SChris Lattner 97330fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 97430fdc8d8SChris Lattner { 97530fdc8d8SChris Lattner Error error(process->Halt ()); 97630fdc8d8SChris Lattner if (error.Success()) 97730fdc8d8SChris Lattner { 97830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 97930fdc8d8SChris Lattner 98030fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 98130fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 98230fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 98330fdc8d8SChris Lattner } 98430fdc8d8SChris Lattner else 98530fdc8d8SChris Lattner { 98630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 98730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 98830fdc8d8SChris Lattner } 98930fdc8d8SChris Lattner } 99030fdc8d8SChris Lattner else 99130fdc8d8SChris Lattner { 99230fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 99330fdc8d8SChris Lattner m_cmd_name.c_str(), 99430fdc8d8SChris Lattner m_cmd_syntax.c_str()); 99530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 99630fdc8d8SChris Lattner } 99730fdc8d8SChris Lattner return result.Succeeded(); 99830fdc8d8SChris Lattner } 99930fdc8d8SChris Lattner }; 100030fdc8d8SChris Lattner 100130fdc8d8SChris Lattner //------------------------------------------------------------------------- 100230fdc8d8SChris Lattner // CommandObjectProcessKill 100330fdc8d8SChris Lattner //------------------------------------------------------------------------- 100430fdc8d8SChris Lattner 100530fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 100630fdc8d8SChris Lattner { 100730fdc8d8SChris Lattner public: 100830fdc8d8SChris Lattner 1009a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1010a7015092SGreg Clayton CommandObject (interpreter, 1011a7015092SGreg Clayton "process kill", 1012e3d26315SCaroline Tice "Terminate the current process being debugged.", 101330fdc8d8SChris Lattner "process kill", 101430fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 101530fdc8d8SChris Lattner { 101630fdc8d8SChris Lattner } 101730fdc8d8SChris Lattner 101830fdc8d8SChris Lattner ~CommandObjectProcessKill () 101930fdc8d8SChris Lattner { 102030fdc8d8SChris Lattner } 102130fdc8d8SChris Lattner 102230fdc8d8SChris Lattner bool 1023a7015092SGreg Clayton Execute (Args& command, 102430fdc8d8SChris Lattner CommandReturnObject &result) 102530fdc8d8SChris Lattner { 1026a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 102730fdc8d8SChris Lattner if (process == NULL) 102830fdc8d8SChris Lattner { 102930fdc8d8SChris Lattner result.AppendError ("no process to kill"); 103030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 103130fdc8d8SChris Lattner return false; 103230fdc8d8SChris Lattner } 103330fdc8d8SChris Lattner 103430fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 103530fdc8d8SChris Lattner { 103630fdc8d8SChris Lattner Error error (process->Destroy()); 103730fdc8d8SChris Lattner if (error.Success()) 103830fdc8d8SChris Lattner { 103930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 104030fdc8d8SChris Lattner } 104130fdc8d8SChris Lattner else 104230fdc8d8SChris Lattner { 104330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 104430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 104530fdc8d8SChris Lattner } 104630fdc8d8SChris Lattner } 104730fdc8d8SChris Lattner else 104830fdc8d8SChris Lattner { 104930fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 105030fdc8d8SChris Lattner m_cmd_name.c_str(), 105130fdc8d8SChris Lattner m_cmd_syntax.c_str()); 105230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 105330fdc8d8SChris Lattner } 105430fdc8d8SChris Lattner return result.Succeeded(); 105530fdc8d8SChris Lattner } 105630fdc8d8SChris Lattner }; 105730fdc8d8SChris Lattner 105830fdc8d8SChris Lattner //------------------------------------------------------------------------- 10594b9bea87SJim Ingham // CommandObjectProcessStatus 10604b9bea87SJim Ingham //------------------------------------------------------------------------- 10614b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 10624b9bea87SJim Ingham { 10634b9bea87SJim Ingham public: 1064a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1065a7015092SGreg Clayton CommandObject (interpreter, 1066a7015092SGreg Clayton "process status", 1067e3d26315SCaroline Tice "Show the current status and location of executing process.", 1068e3d26315SCaroline Tice "process status", 10694b9bea87SJim Ingham 0) 10704b9bea87SJim Ingham { 10714b9bea87SJim Ingham } 10724b9bea87SJim Ingham 10734b9bea87SJim Ingham ~CommandObjectProcessStatus() 10744b9bea87SJim Ingham { 10754b9bea87SJim Ingham } 10764b9bea87SJim Ingham 10774b9bea87SJim Ingham 10784b9bea87SJim Ingham bool 10794b9bea87SJim Ingham Execute 10804b9bea87SJim Ingham ( 10814b9bea87SJim Ingham Args& command, 10824b9bea87SJim Ingham CommandReturnObject &result 10834b9bea87SJim Ingham ) 10844b9bea87SJim Ingham { 10854b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 10864b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1087a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 10884b9bea87SJim Ingham if (exe_ctx.process) 10894b9bea87SJim Ingham { 10904b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 10914b9bea87SJim Ingham if (StateIsStoppedState(state)) 10924b9bea87SJim Ingham { 10934b9bea87SJim Ingham if (state == eStateExited) 10944b9bea87SJim Ingham { 10954b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 10964b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 10974b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 10984b9bea87SJim Ingham exe_ctx.process->GetID(), 10994b9bea87SJim Ingham exit_status, 11004b9bea87SJim Ingham exit_status, 11014b9bea87SJim Ingham exit_description ? exit_description : ""); 11024b9bea87SJim Ingham } 11034b9bea87SJim Ingham else 11044b9bea87SJim Ingham { 11054b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 11064b9bea87SJim Ingham if (exe_ctx.thread == NULL) 11074b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 11084b9bea87SJim Ingham if (exe_ctx.thread != NULL) 11094b9bea87SJim Ingham { 1110a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 11114b9bea87SJim Ingham } 11124b9bea87SJim Ingham else 11134b9bea87SJim Ingham { 11144b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 11154b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 11164b9bea87SJim Ingham } 11174b9bea87SJim Ingham } 11184b9bea87SJim Ingham } 11194b9bea87SJim Ingham else 11204b9bea87SJim Ingham { 11214b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 11224b9bea87SJim Ingham exe_ctx.process->GetID()); 11234b9bea87SJim Ingham } 11244b9bea87SJim Ingham } 11254b9bea87SJim Ingham else 11264b9bea87SJim Ingham { 11274b9bea87SJim Ingham result.AppendError ("No current location or status available."); 11284b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 11294b9bea87SJim Ingham } 11304b9bea87SJim Ingham return result.Succeeded(); 11314b9bea87SJim Ingham } 11324b9bea87SJim Ingham }; 11334b9bea87SJim Ingham 11344b9bea87SJim Ingham //------------------------------------------------------------------------- 113535731357SCaroline Tice // CommandObjectProcessHandle 113635731357SCaroline Tice //------------------------------------------------------------------------- 113735731357SCaroline Tice 113835731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 113935731357SCaroline Tice { 114035731357SCaroline Tice public: 114135731357SCaroline Tice 114235731357SCaroline Tice class CommandOptions : public Options 114335731357SCaroline Tice { 114435731357SCaroline Tice public: 114535731357SCaroline Tice 114635731357SCaroline Tice CommandOptions () : 114735731357SCaroline Tice Options () 114835731357SCaroline Tice { 114935731357SCaroline Tice ResetOptionValues (); 115035731357SCaroline Tice } 115135731357SCaroline Tice 115235731357SCaroline Tice ~CommandOptions () 115335731357SCaroline Tice { 115435731357SCaroline Tice } 115535731357SCaroline Tice 115635731357SCaroline Tice Error 115735731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 115835731357SCaroline Tice { 115935731357SCaroline Tice Error error; 116035731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 116135731357SCaroline Tice 116235731357SCaroline Tice switch (short_option) 116335731357SCaroline Tice { 116435731357SCaroline Tice case 's': 116535731357SCaroline Tice stop = option_arg; 116635731357SCaroline Tice break; 116735731357SCaroline Tice case 'n': 116835731357SCaroline Tice notify = option_arg; 116935731357SCaroline Tice break; 117035731357SCaroline Tice case 'p': 117135731357SCaroline Tice pass = option_arg; 117235731357SCaroline Tice break; 117335731357SCaroline Tice default: 117435731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 117535731357SCaroline Tice break; 117635731357SCaroline Tice } 117735731357SCaroline Tice return error; 117835731357SCaroline Tice } 117935731357SCaroline Tice 118035731357SCaroline Tice void 118135731357SCaroline Tice ResetOptionValues () 118235731357SCaroline Tice { 118335731357SCaroline Tice Options::ResetOptionValues(); 118435731357SCaroline Tice stop.clear(); 118535731357SCaroline Tice notify.clear(); 118635731357SCaroline Tice pass.clear(); 118735731357SCaroline Tice } 118835731357SCaroline Tice 118935731357SCaroline Tice const lldb::OptionDefinition* 119035731357SCaroline Tice GetDefinitions () 119135731357SCaroline Tice { 119235731357SCaroline Tice return g_option_table; 119335731357SCaroline Tice } 119435731357SCaroline Tice 119535731357SCaroline Tice // Options table: Required for subclasses of Options. 119635731357SCaroline Tice 119735731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 119835731357SCaroline Tice 119935731357SCaroline Tice // Instance variables to hold the values for command options. 120035731357SCaroline Tice 120135731357SCaroline Tice std::string stop; 120235731357SCaroline Tice std::string notify; 120335731357SCaroline Tice std::string pass; 120435731357SCaroline Tice }; 120535731357SCaroline Tice 120635731357SCaroline Tice 120735731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 120835731357SCaroline Tice CommandObject (interpreter, 120935731357SCaroline Tice "process handle", 121010ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 121135731357SCaroline Tice NULL) 121235731357SCaroline Tice { 121310ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 121435731357SCaroline Tice CommandArgumentEntry arg; 1215c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 121635731357SCaroline Tice 1217c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1218c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 121935731357SCaroline Tice 1220c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 122135731357SCaroline Tice 122235731357SCaroline Tice m_arguments.push_back (arg); 122335731357SCaroline Tice } 122435731357SCaroline Tice 122535731357SCaroline Tice ~CommandObjectProcessHandle () 122635731357SCaroline Tice { 122735731357SCaroline Tice } 122835731357SCaroline Tice 122935731357SCaroline Tice Options * 123035731357SCaroline Tice GetOptions () 123135731357SCaroline Tice { 123235731357SCaroline Tice return &m_options; 123335731357SCaroline Tice } 123435731357SCaroline Tice 123535731357SCaroline Tice bool 123610ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 123735731357SCaroline Tice { 123835731357SCaroline Tice bool okay = true; 123935731357SCaroline Tice 124010ad7993SCaroline Tice bool success = false; 124110ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 124210ad7993SCaroline Tice 124310ad7993SCaroline Tice if (success && tmp_value) 124410ad7993SCaroline Tice real_value = 1; 124510ad7993SCaroline Tice else if (success && !tmp_value) 124610ad7993SCaroline Tice real_value = 0; 124735731357SCaroline Tice else 124835731357SCaroline Tice { 124935731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 125010ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 125110ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 125235731357SCaroline Tice okay = false; 125335731357SCaroline Tice } 125435731357SCaroline Tice 125535731357SCaroline Tice return okay; 125635731357SCaroline Tice } 125735731357SCaroline Tice 125810ad7993SCaroline Tice void 125910ad7993SCaroline Tice PrintSignalHeader (Stream &str) 126010ad7993SCaroline Tice { 126110ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 126210ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 126310ad7993SCaroline Tice } 126410ad7993SCaroline Tice 126510ad7993SCaroline Tice void 126610ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 126710ad7993SCaroline Tice { 126810ad7993SCaroline Tice bool stop; 126910ad7993SCaroline Tice bool suppress; 127010ad7993SCaroline Tice bool notify; 127110ad7993SCaroline Tice 127210ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 127310ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 127410ad7993SCaroline Tice { 127510ad7993SCaroline Tice bool pass = !suppress; 127610ad7993SCaroline Tice str.Printf ("%s %s %s", 127710ad7993SCaroline Tice (pass ? "true " : "false"), 127810ad7993SCaroline Tice (stop ? "true " : "false"), 127910ad7993SCaroline Tice (notify ? "true " : "false")); 128010ad7993SCaroline Tice } 128110ad7993SCaroline Tice str.Printf ("\n"); 128210ad7993SCaroline Tice } 128310ad7993SCaroline Tice 128410ad7993SCaroline Tice void 128510ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 128610ad7993SCaroline Tice { 128710ad7993SCaroline Tice PrintSignalHeader (str); 128810ad7993SCaroline Tice 128910ad7993SCaroline Tice if (num_valid_signals > 0) 129010ad7993SCaroline Tice { 129110ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 129210ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 129310ad7993SCaroline Tice { 129410ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 129510ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 129610ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 129710ad7993SCaroline Tice } 129810ad7993SCaroline Tice } 129910ad7993SCaroline Tice else // Print info for ALL signals 130010ad7993SCaroline Tice { 130110ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 130210ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 130310ad7993SCaroline Tice { 130410ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 130510ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 130610ad7993SCaroline Tice } 130710ad7993SCaroline Tice } 130810ad7993SCaroline Tice } 130910ad7993SCaroline Tice 131035731357SCaroline Tice bool 131135731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 131235731357SCaroline Tice { 131335731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 131435731357SCaroline Tice 131535731357SCaroline Tice if (!target_sp) 131635731357SCaroline Tice { 131735731357SCaroline Tice result.AppendError ("No current target;" 131835731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 131935731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 132035731357SCaroline Tice return false; 132135731357SCaroline Tice } 132235731357SCaroline Tice 132335731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 132435731357SCaroline Tice 132535731357SCaroline Tice if (!process_sp) 132635731357SCaroline Tice { 132735731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 132835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 132935731357SCaroline Tice return false; 133035731357SCaroline Tice } 133135731357SCaroline Tice 133235731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 133335731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 133435731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 133535731357SCaroline Tice 133635731357SCaroline Tice if (! m_options.stop.empty() 133710ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 133835731357SCaroline Tice { 133935731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 134035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 134135731357SCaroline Tice return false; 134235731357SCaroline Tice } 134335731357SCaroline Tice 134435731357SCaroline Tice if (! m_options.notify.empty() 134510ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 134635731357SCaroline Tice { 134735731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 134835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 134935731357SCaroline Tice return false; 135035731357SCaroline Tice } 135135731357SCaroline Tice 135235731357SCaroline Tice if (! m_options.pass.empty() 135310ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 135435731357SCaroline Tice { 135535731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 135635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 135735731357SCaroline Tice return false; 135835731357SCaroline Tice } 135935731357SCaroline Tice 136035731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 136135731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 136235731357SCaroline Tice int num_signals_set = 0; 136335731357SCaroline Tice 136410ad7993SCaroline Tice if (num_args > 0) 136510ad7993SCaroline Tice { 136635731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 136735731357SCaroline Tice { 136835731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 136935731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 137035731357SCaroline Tice { 137110ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 137235731357SCaroline Tice // the value is either 0 or 1. 137335731357SCaroline Tice if (stop_action != -1) 137435731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 137535731357SCaroline Tice if (pass_action != -1) 137635731357SCaroline Tice { 137710ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 137810ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 137935731357SCaroline Tice } 138035731357SCaroline Tice if (notify_action != -1) 138135731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 138235731357SCaroline Tice ++num_signals_set; 138335731357SCaroline Tice } 138435731357SCaroline Tice else 138535731357SCaroline Tice { 138635731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 138735731357SCaroline Tice } 138835731357SCaroline Tice } 138910ad7993SCaroline Tice } 139010ad7993SCaroline Tice else 139110ad7993SCaroline Tice { 139210ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 139310ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 139410ad7993SCaroline Tice { 139510ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 139610ad7993SCaroline Tice { 139710ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 139810ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 139910ad7993SCaroline Tice { 140010ad7993SCaroline Tice if (notify_action != -1) 140110ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 140210ad7993SCaroline Tice if (stop_action != -1) 140310ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 140410ad7993SCaroline Tice if (pass_action != -1) 140510ad7993SCaroline Tice { 140610ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 140710ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 140810ad7993SCaroline Tice } 140910ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 141010ad7993SCaroline Tice } 141110ad7993SCaroline Tice } 141210ad7993SCaroline Tice } 141310ad7993SCaroline Tice } 141410ad7993SCaroline Tice 141510ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 141635731357SCaroline Tice 141735731357SCaroline Tice if (num_signals_set > 0) 141835731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 141935731357SCaroline Tice else 142035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 142135731357SCaroline Tice 142235731357SCaroline Tice return result.Succeeded(); 142335731357SCaroline Tice } 142435731357SCaroline Tice 142535731357SCaroline Tice protected: 142635731357SCaroline Tice 142735731357SCaroline Tice CommandOptions m_options; 142835731357SCaroline Tice }; 142935731357SCaroline Tice 143035731357SCaroline Tice lldb::OptionDefinition 143135731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 143235731357SCaroline Tice { 143335731357SCaroline 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." }, 143435731357SCaroline 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." }, 143535731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 143635731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 143735731357SCaroline Tice }; 143835731357SCaroline Tice 143935731357SCaroline Tice //------------------------------------------------------------------------- 144030fdc8d8SChris Lattner // CommandObjectMultiwordProcess 144130fdc8d8SChris Lattner //------------------------------------------------------------------------- 144230fdc8d8SChris Lattner 14436611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1444a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1445a7015092SGreg Clayton "process", 144630fdc8d8SChris Lattner "A set of commands for operating on a process.", 144730fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 144830fdc8d8SChris Lattner { 1449a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1450a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1451a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1452a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1453a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 145435731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1455a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1456a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1457a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 145830fdc8d8SChris Lattner } 145930fdc8d8SChris Lattner 146030fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 146130fdc8d8SChris Lattner { 146230fdc8d8SChris Lattner } 146330fdc8d8SChris Lattner 1464