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 8395d7be2e6SCaroline 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 //------------------------------------------------------------------------- 856*8f343b09SGreg Clayton // CommandObjectProcessLoad 857*8f343b09SGreg Clayton //------------------------------------------------------------------------- 858*8f343b09SGreg Clayton 859*8f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject 860*8f343b09SGreg Clayton { 861*8f343b09SGreg Clayton public: 862*8f343b09SGreg Clayton 863*8f343b09SGreg Clayton CommandObjectProcessLoad (CommandInterpreter &interpreter) : 864*8f343b09SGreg Clayton CommandObject (interpreter, 865*8f343b09SGreg Clayton "process load", 866*8f343b09SGreg Clayton "Load a shared library into the current process.", 867*8f343b09SGreg Clayton "process load <filename> [<filename> ...]", 868*8f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 869*8f343b09SGreg Clayton { 870*8f343b09SGreg Clayton } 871*8f343b09SGreg Clayton 872*8f343b09SGreg Clayton ~CommandObjectProcessLoad () 873*8f343b09SGreg Clayton { 874*8f343b09SGreg Clayton } 875*8f343b09SGreg Clayton 876*8f343b09SGreg Clayton bool 877*8f343b09SGreg Clayton Execute (Args& command, 878*8f343b09SGreg Clayton CommandReturnObject &result) 879*8f343b09SGreg Clayton { 880*8f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 881*8f343b09SGreg Clayton if (process == NULL) 882*8f343b09SGreg Clayton { 883*8f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 884*8f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 885*8f343b09SGreg Clayton return false; 886*8f343b09SGreg Clayton } 887*8f343b09SGreg Clayton 888*8f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 889*8f343b09SGreg Clayton 890*8f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 891*8f343b09SGreg Clayton { 892*8f343b09SGreg Clayton Error error; 893*8f343b09SGreg Clayton const char *image_path = command.GetArgumentAtIndex(i); 894*8f343b09SGreg Clayton FileSpec image_spec (image_path, false); 895*8f343b09SGreg Clayton uint32_t image_token = process->LoadImage(image_spec, error); 896*8f343b09SGreg Clayton if (image_token != LLDB_INVALID_IMAGE_TOKEN) 897*8f343b09SGreg Clayton { 898*8f343b09SGreg Clayton result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 899*8f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 900*8f343b09SGreg Clayton } 901*8f343b09SGreg Clayton else 902*8f343b09SGreg Clayton { 903*8f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 904*8f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 905*8f343b09SGreg Clayton } 906*8f343b09SGreg Clayton } 907*8f343b09SGreg Clayton return result.Succeeded(); 908*8f343b09SGreg Clayton } 909*8f343b09SGreg Clayton }; 910*8f343b09SGreg Clayton 911*8f343b09SGreg Clayton 912*8f343b09SGreg Clayton //------------------------------------------------------------------------- 913*8f343b09SGreg Clayton // CommandObjectProcessUnload 914*8f343b09SGreg Clayton //------------------------------------------------------------------------- 915*8f343b09SGreg Clayton 916*8f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject 917*8f343b09SGreg Clayton { 918*8f343b09SGreg Clayton public: 919*8f343b09SGreg Clayton 920*8f343b09SGreg Clayton CommandObjectProcessUnload (CommandInterpreter &interpreter) : 921*8f343b09SGreg Clayton CommandObject (interpreter, 922*8f343b09SGreg Clayton "process unload", 923*8f343b09SGreg Clayton "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 924*8f343b09SGreg Clayton "process unload <index>", 925*8f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 926*8f343b09SGreg Clayton { 927*8f343b09SGreg Clayton } 928*8f343b09SGreg Clayton 929*8f343b09SGreg Clayton ~CommandObjectProcessUnload () 930*8f343b09SGreg Clayton { 931*8f343b09SGreg Clayton } 932*8f343b09SGreg Clayton 933*8f343b09SGreg Clayton bool 934*8f343b09SGreg Clayton Execute (Args& command, 935*8f343b09SGreg Clayton CommandReturnObject &result) 936*8f343b09SGreg Clayton { 937*8f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 938*8f343b09SGreg Clayton if (process == NULL) 939*8f343b09SGreg Clayton { 940*8f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 941*8f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 942*8f343b09SGreg Clayton return false; 943*8f343b09SGreg Clayton } 944*8f343b09SGreg Clayton 945*8f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 946*8f343b09SGreg Clayton 947*8f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 948*8f343b09SGreg Clayton { 949*8f343b09SGreg Clayton const char *image_token_cstr = command.GetArgumentAtIndex(i); 950*8f343b09SGreg Clayton uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 951*8f343b09SGreg Clayton if (image_token == LLDB_INVALID_IMAGE_TOKEN) 952*8f343b09SGreg Clayton { 953*8f343b09SGreg Clayton result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 954*8f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 955*8f343b09SGreg Clayton break; 956*8f343b09SGreg Clayton } 957*8f343b09SGreg Clayton else 958*8f343b09SGreg Clayton { 959*8f343b09SGreg Clayton Error error (process->UnloadImage(image_token)); 960*8f343b09SGreg Clayton if (error.Success()) 961*8f343b09SGreg Clayton { 962*8f343b09SGreg Clayton result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 963*8f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 964*8f343b09SGreg Clayton } 965*8f343b09SGreg Clayton else 966*8f343b09SGreg Clayton { 967*8f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 968*8f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 969*8f343b09SGreg Clayton break; 970*8f343b09SGreg Clayton } 971*8f343b09SGreg Clayton } 972*8f343b09SGreg Clayton } 973*8f343b09SGreg Clayton return result.Succeeded(); 974*8f343b09SGreg Clayton } 975*8f343b09SGreg Clayton }; 976*8f343b09SGreg Clayton 977*8f343b09SGreg Clayton //------------------------------------------------------------------------- 97830fdc8d8SChris Lattner // CommandObjectProcessSignal 97930fdc8d8SChris Lattner //------------------------------------------------------------------------- 98030fdc8d8SChris Lattner 98130fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 98230fdc8d8SChris Lattner { 98330fdc8d8SChris Lattner public: 98430fdc8d8SChris Lattner 985a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 986a7015092SGreg Clayton CommandObject (interpreter, 987a7015092SGreg Clayton "process signal", 988e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 989405fe67fSCaroline Tice NULL) 99030fdc8d8SChris Lattner { 991405fe67fSCaroline Tice CommandArgumentEntry arg; 992405fe67fSCaroline Tice CommandArgumentData signal_arg; 993405fe67fSCaroline Tice 994405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 995c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 996405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 997405fe67fSCaroline Tice 998405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 999405fe67fSCaroline Tice arg.push_back (signal_arg); 1000405fe67fSCaroline Tice 1001405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1002405fe67fSCaroline Tice m_arguments.push_back (arg); 100330fdc8d8SChris Lattner } 100430fdc8d8SChris Lattner 100530fdc8d8SChris Lattner ~CommandObjectProcessSignal () 100630fdc8d8SChris Lattner { 100730fdc8d8SChris Lattner } 100830fdc8d8SChris Lattner 100930fdc8d8SChris Lattner bool 1010a7015092SGreg Clayton Execute (Args& command, 101130fdc8d8SChris Lattner CommandReturnObject &result) 101230fdc8d8SChris Lattner { 1013a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 101430fdc8d8SChris Lattner if (process == NULL) 101530fdc8d8SChris Lattner { 101630fdc8d8SChris Lattner result.AppendError ("no process to signal"); 101730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 101830fdc8d8SChris Lattner return false; 101930fdc8d8SChris Lattner } 102030fdc8d8SChris Lattner 102130fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 102230fdc8d8SChris Lattner { 1023237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1024237cd906SGreg Clayton 1025237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1026237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 1027237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1028237cd906SGreg Clayton else 1029237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 1030237cd906SGreg Clayton 1031237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 103230fdc8d8SChris Lattner { 103330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 103430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 103530fdc8d8SChris Lattner } 103630fdc8d8SChris Lattner else 103730fdc8d8SChris Lattner { 103830fdc8d8SChris Lattner Error error (process->Signal (signo)); 103930fdc8d8SChris Lattner if (error.Success()) 104030fdc8d8SChris Lattner { 104130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 104230fdc8d8SChris Lattner } 104330fdc8d8SChris Lattner else 104430fdc8d8SChris Lattner { 104530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 104630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 104730fdc8d8SChris Lattner } 104830fdc8d8SChris Lattner } 104930fdc8d8SChris Lattner } 105030fdc8d8SChris Lattner else 105130fdc8d8SChris Lattner { 105230fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 105330fdc8d8SChris Lattner m_cmd_syntax.c_str()); 105430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 105530fdc8d8SChris Lattner } 105630fdc8d8SChris Lattner return result.Succeeded(); 105730fdc8d8SChris Lattner } 105830fdc8d8SChris Lattner }; 105930fdc8d8SChris Lattner 106030fdc8d8SChris Lattner 106130fdc8d8SChris Lattner //------------------------------------------------------------------------- 106230fdc8d8SChris Lattner // CommandObjectProcessInterrupt 106330fdc8d8SChris Lattner //------------------------------------------------------------------------- 106430fdc8d8SChris Lattner 106530fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 106630fdc8d8SChris Lattner { 106730fdc8d8SChris Lattner public: 106830fdc8d8SChris Lattner 106930fdc8d8SChris Lattner 1070a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 1071a7015092SGreg Clayton CommandObject (interpreter, 1072a7015092SGreg Clayton "process interrupt", 1073e3d26315SCaroline Tice "Interrupt the current process being debugged.", 107430fdc8d8SChris Lattner "process interrupt", 107530fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 107630fdc8d8SChris Lattner { 107730fdc8d8SChris Lattner } 107830fdc8d8SChris Lattner 107930fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 108030fdc8d8SChris Lattner { 108130fdc8d8SChris Lattner } 108230fdc8d8SChris Lattner 108330fdc8d8SChris Lattner bool 1084a7015092SGreg Clayton Execute (Args& command, 108530fdc8d8SChris Lattner CommandReturnObject &result) 108630fdc8d8SChris Lattner { 1087a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 108830fdc8d8SChris Lattner if (process == NULL) 108930fdc8d8SChris Lattner { 109030fdc8d8SChris Lattner result.AppendError ("no process to halt"); 109130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 109230fdc8d8SChris Lattner return false; 109330fdc8d8SChris Lattner } 109430fdc8d8SChris Lattner 109530fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 109630fdc8d8SChris Lattner { 109730fdc8d8SChris Lattner Error error(process->Halt ()); 109830fdc8d8SChris Lattner if (error.Success()) 109930fdc8d8SChris Lattner { 110030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 110130fdc8d8SChris Lattner 110230fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 110330fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 110430fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 110530fdc8d8SChris Lattner } 110630fdc8d8SChris Lattner else 110730fdc8d8SChris Lattner { 110830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 110930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 111030fdc8d8SChris Lattner } 111130fdc8d8SChris Lattner } 111230fdc8d8SChris Lattner else 111330fdc8d8SChris Lattner { 111430fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 111530fdc8d8SChris Lattner m_cmd_name.c_str(), 111630fdc8d8SChris Lattner m_cmd_syntax.c_str()); 111730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 111830fdc8d8SChris Lattner } 111930fdc8d8SChris Lattner return result.Succeeded(); 112030fdc8d8SChris Lattner } 112130fdc8d8SChris Lattner }; 112230fdc8d8SChris Lattner 112330fdc8d8SChris Lattner //------------------------------------------------------------------------- 112430fdc8d8SChris Lattner // CommandObjectProcessKill 112530fdc8d8SChris Lattner //------------------------------------------------------------------------- 112630fdc8d8SChris Lattner 112730fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 112830fdc8d8SChris Lattner { 112930fdc8d8SChris Lattner public: 113030fdc8d8SChris Lattner 1131a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1132a7015092SGreg Clayton CommandObject (interpreter, 1133a7015092SGreg Clayton "process kill", 1134e3d26315SCaroline Tice "Terminate the current process being debugged.", 113530fdc8d8SChris Lattner "process kill", 113630fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 113730fdc8d8SChris Lattner { 113830fdc8d8SChris Lattner } 113930fdc8d8SChris Lattner 114030fdc8d8SChris Lattner ~CommandObjectProcessKill () 114130fdc8d8SChris Lattner { 114230fdc8d8SChris Lattner } 114330fdc8d8SChris Lattner 114430fdc8d8SChris Lattner bool 1145a7015092SGreg Clayton Execute (Args& command, 114630fdc8d8SChris Lattner CommandReturnObject &result) 114730fdc8d8SChris Lattner { 1148a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 114930fdc8d8SChris Lattner if (process == NULL) 115030fdc8d8SChris Lattner { 115130fdc8d8SChris Lattner result.AppendError ("no process to kill"); 115230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 115330fdc8d8SChris Lattner return false; 115430fdc8d8SChris Lattner } 115530fdc8d8SChris Lattner 115630fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 115730fdc8d8SChris Lattner { 115830fdc8d8SChris Lattner Error error (process->Destroy()); 115930fdc8d8SChris Lattner if (error.Success()) 116030fdc8d8SChris Lattner { 116130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 116230fdc8d8SChris Lattner } 116330fdc8d8SChris Lattner else 116430fdc8d8SChris Lattner { 116530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 116630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 116730fdc8d8SChris Lattner } 116830fdc8d8SChris Lattner } 116930fdc8d8SChris Lattner else 117030fdc8d8SChris Lattner { 117130fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 117230fdc8d8SChris Lattner m_cmd_name.c_str(), 117330fdc8d8SChris Lattner m_cmd_syntax.c_str()); 117430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 117530fdc8d8SChris Lattner } 117630fdc8d8SChris Lattner return result.Succeeded(); 117730fdc8d8SChris Lattner } 117830fdc8d8SChris Lattner }; 117930fdc8d8SChris Lattner 118030fdc8d8SChris Lattner //------------------------------------------------------------------------- 11814b9bea87SJim Ingham // CommandObjectProcessStatus 11824b9bea87SJim Ingham //------------------------------------------------------------------------- 11834b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 11844b9bea87SJim Ingham { 11854b9bea87SJim Ingham public: 1186a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1187a7015092SGreg Clayton CommandObject (interpreter, 1188a7015092SGreg Clayton "process status", 1189e3d26315SCaroline Tice "Show the current status and location of executing process.", 1190e3d26315SCaroline Tice "process status", 11914b9bea87SJim Ingham 0) 11924b9bea87SJim Ingham { 11934b9bea87SJim Ingham } 11944b9bea87SJim Ingham 11954b9bea87SJim Ingham ~CommandObjectProcessStatus() 11964b9bea87SJim Ingham { 11974b9bea87SJim Ingham } 11984b9bea87SJim Ingham 11994b9bea87SJim Ingham 12004b9bea87SJim Ingham bool 12014b9bea87SJim Ingham Execute 12024b9bea87SJim Ingham ( 12034b9bea87SJim Ingham Args& command, 12044b9bea87SJim Ingham CommandReturnObject &result 12054b9bea87SJim Ingham ) 12064b9bea87SJim Ingham { 12074b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 12084b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1209a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 12104b9bea87SJim Ingham if (exe_ctx.process) 12114b9bea87SJim Ingham { 12124b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 12134b9bea87SJim Ingham if (StateIsStoppedState(state)) 12144b9bea87SJim Ingham { 12154b9bea87SJim Ingham if (state == eStateExited) 12164b9bea87SJim Ingham { 12174b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 12184b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 12194b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 12204b9bea87SJim Ingham exe_ctx.process->GetID(), 12214b9bea87SJim Ingham exit_status, 12224b9bea87SJim Ingham exit_status, 12234b9bea87SJim Ingham exit_description ? exit_description : ""); 12244b9bea87SJim Ingham } 12254b9bea87SJim Ingham else 12264b9bea87SJim Ingham { 12274b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 12284b9bea87SJim Ingham if (exe_ctx.thread == NULL) 12294b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 12304b9bea87SJim Ingham if (exe_ctx.thread != NULL) 12314b9bea87SJim Ingham { 1232a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 12334b9bea87SJim Ingham } 12344b9bea87SJim Ingham else 12354b9bea87SJim Ingham { 12364b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 12374b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 12384b9bea87SJim Ingham } 12394b9bea87SJim Ingham } 12404b9bea87SJim Ingham } 12414b9bea87SJim Ingham else 12424b9bea87SJim Ingham { 12434b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 12444b9bea87SJim Ingham exe_ctx.process->GetID()); 12454b9bea87SJim Ingham } 12464b9bea87SJim Ingham } 12474b9bea87SJim Ingham else 12484b9bea87SJim Ingham { 12494b9bea87SJim Ingham result.AppendError ("No current location or status available."); 12504b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 12514b9bea87SJim Ingham } 12524b9bea87SJim Ingham return result.Succeeded(); 12534b9bea87SJim Ingham } 12544b9bea87SJim Ingham }; 12554b9bea87SJim Ingham 12564b9bea87SJim Ingham //------------------------------------------------------------------------- 125735731357SCaroline Tice // CommandObjectProcessHandle 125835731357SCaroline Tice //------------------------------------------------------------------------- 125935731357SCaroline Tice 126035731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 126135731357SCaroline Tice { 126235731357SCaroline Tice public: 126335731357SCaroline Tice 126435731357SCaroline Tice class CommandOptions : public Options 126535731357SCaroline Tice { 126635731357SCaroline Tice public: 126735731357SCaroline Tice 126835731357SCaroline Tice CommandOptions () : 126935731357SCaroline Tice Options () 127035731357SCaroline Tice { 127135731357SCaroline Tice ResetOptionValues (); 127235731357SCaroline Tice } 127335731357SCaroline Tice 127435731357SCaroline Tice ~CommandOptions () 127535731357SCaroline Tice { 127635731357SCaroline Tice } 127735731357SCaroline Tice 127835731357SCaroline Tice Error 127935731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 128035731357SCaroline Tice { 128135731357SCaroline Tice Error error; 128235731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 128335731357SCaroline Tice 128435731357SCaroline Tice switch (short_option) 128535731357SCaroline Tice { 128635731357SCaroline Tice case 's': 128735731357SCaroline Tice stop = option_arg; 128835731357SCaroline Tice break; 128935731357SCaroline Tice case 'n': 129035731357SCaroline Tice notify = option_arg; 129135731357SCaroline Tice break; 129235731357SCaroline Tice case 'p': 129335731357SCaroline Tice pass = option_arg; 129435731357SCaroline Tice break; 129535731357SCaroline Tice default: 129635731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 129735731357SCaroline Tice break; 129835731357SCaroline Tice } 129935731357SCaroline Tice return error; 130035731357SCaroline Tice } 130135731357SCaroline Tice 130235731357SCaroline Tice void 130335731357SCaroline Tice ResetOptionValues () 130435731357SCaroline Tice { 130535731357SCaroline Tice Options::ResetOptionValues(); 130635731357SCaroline Tice stop.clear(); 130735731357SCaroline Tice notify.clear(); 130835731357SCaroline Tice pass.clear(); 130935731357SCaroline Tice } 131035731357SCaroline Tice 131135731357SCaroline Tice const lldb::OptionDefinition* 131235731357SCaroline Tice GetDefinitions () 131335731357SCaroline Tice { 131435731357SCaroline Tice return g_option_table; 131535731357SCaroline Tice } 131635731357SCaroline Tice 131735731357SCaroline Tice // Options table: Required for subclasses of Options. 131835731357SCaroline Tice 131935731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 132035731357SCaroline Tice 132135731357SCaroline Tice // Instance variables to hold the values for command options. 132235731357SCaroline Tice 132335731357SCaroline Tice std::string stop; 132435731357SCaroline Tice std::string notify; 132535731357SCaroline Tice std::string pass; 132635731357SCaroline Tice }; 132735731357SCaroline Tice 132835731357SCaroline Tice 132935731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 133035731357SCaroline Tice CommandObject (interpreter, 133135731357SCaroline Tice "process handle", 133210ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 133335731357SCaroline Tice NULL) 133435731357SCaroline Tice { 133510ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 133635731357SCaroline Tice CommandArgumentEntry arg; 1337c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 133835731357SCaroline Tice 1339c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1340c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 134135731357SCaroline Tice 1342c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 134335731357SCaroline Tice 134435731357SCaroline Tice m_arguments.push_back (arg); 134535731357SCaroline Tice } 134635731357SCaroline Tice 134735731357SCaroline Tice ~CommandObjectProcessHandle () 134835731357SCaroline Tice { 134935731357SCaroline Tice } 135035731357SCaroline Tice 135135731357SCaroline Tice Options * 135235731357SCaroline Tice GetOptions () 135335731357SCaroline Tice { 135435731357SCaroline Tice return &m_options; 135535731357SCaroline Tice } 135635731357SCaroline Tice 135735731357SCaroline Tice bool 135810ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 135935731357SCaroline Tice { 136035731357SCaroline Tice bool okay = true; 136135731357SCaroline Tice 136210ad7993SCaroline Tice bool success = false; 136310ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 136410ad7993SCaroline Tice 136510ad7993SCaroline Tice if (success && tmp_value) 136610ad7993SCaroline Tice real_value = 1; 136710ad7993SCaroline Tice else if (success && !tmp_value) 136810ad7993SCaroline Tice real_value = 0; 136935731357SCaroline Tice else 137035731357SCaroline Tice { 137135731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 137210ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 137310ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 137435731357SCaroline Tice okay = false; 137535731357SCaroline Tice } 137635731357SCaroline Tice 137735731357SCaroline Tice return okay; 137835731357SCaroline Tice } 137935731357SCaroline Tice 138010ad7993SCaroline Tice void 138110ad7993SCaroline Tice PrintSignalHeader (Stream &str) 138210ad7993SCaroline Tice { 138310ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 138410ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 138510ad7993SCaroline Tice } 138610ad7993SCaroline Tice 138710ad7993SCaroline Tice void 138810ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 138910ad7993SCaroline Tice { 139010ad7993SCaroline Tice bool stop; 139110ad7993SCaroline Tice bool suppress; 139210ad7993SCaroline Tice bool notify; 139310ad7993SCaroline Tice 139410ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 139510ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 139610ad7993SCaroline Tice { 139710ad7993SCaroline Tice bool pass = !suppress; 139810ad7993SCaroline Tice str.Printf ("%s %s %s", 139910ad7993SCaroline Tice (pass ? "true " : "false"), 140010ad7993SCaroline Tice (stop ? "true " : "false"), 140110ad7993SCaroline Tice (notify ? "true " : "false")); 140210ad7993SCaroline Tice } 140310ad7993SCaroline Tice str.Printf ("\n"); 140410ad7993SCaroline Tice } 140510ad7993SCaroline Tice 140610ad7993SCaroline Tice void 140710ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 140810ad7993SCaroline Tice { 140910ad7993SCaroline Tice PrintSignalHeader (str); 141010ad7993SCaroline Tice 141110ad7993SCaroline Tice if (num_valid_signals > 0) 141210ad7993SCaroline Tice { 141310ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 141410ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 141510ad7993SCaroline Tice { 141610ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 141710ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 141810ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 141910ad7993SCaroline Tice } 142010ad7993SCaroline Tice } 142110ad7993SCaroline Tice else // Print info for ALL signals 142210ad7993SCaroline Tice { 142310ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 142410ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 142510ad7993SCaroline Tice { 142610ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 142710ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 142810ad7993SCaroline Tice } 142910ad7993SCaroline Tice } 143010ad7993SCaroline Tice } 143110ad7993SCaroline Tice 143235731357SCaroline Tice bool 143335731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 143435731357SCaroline Tice { 143535731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 143635731357SCaroline Tice 143735731357SCaroline Tice if (!target_sp) 143835731357SCaroline Tice { 143935731357SCaroline Tice result.AppendError ("No current target;" 144035731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 144135731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 144235731357SCaroline Tice return false; 144335731357SCaroline Tice } 144435731357SCaroline Tice 144535731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 144635731357SCaroline Tice 144735731357SCaroline Tice if (!process_sp) 144835731357SCaroline Tice { 144935731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 145035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 145135731357SCaroline Tice return false; 145235731357SCaroline Tice } 145335731357SCaroline Tice 145435731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 145535731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 145635731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 145735731357SCaroline Tice 145835731357SCaroline Tice if (! m_options.stop.empty() 145910ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 146035731357SCaroline Tice { 146135731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 146235731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 146335731357SCaroline Tice return false; 146435731357SCaroline Tice } 146535731357SCaroline Tice 146635731357SCaroline Tice if (! m_options.notify.empty() 146710ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 146835731357SCaroline Tice { 146935731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 147035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 147135731357SCaroline Tice return false; 147235731357SCaroline Tice } 147335731357SCaroline Tice 147435731357SCaroline Tice if (! m_options.pass.empty() 147510ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 147635731357SCaroline Tice { 147735731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 147835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 147935731357SCaroline Tice return false; 148035731357SCaroline Tice } 148135731357SCaroline Tice 148235731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 148335731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 148435731357SCaroline Tice int num_signals_set = 0; 148535731357SCaroline Tice 148610ad7993SCaroline Tice if (num_args > 0) 148710ad7993SCaroline Tice { 148835731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 148935731357SCaroline Tice { 149035731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 149135731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 149235731357SCaroline Tice { 149310ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 149435731357SCaroline Tice // the value is either 0 or 1. 149535731357SCaroline Tice if (stop_action != -1) 149635731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 149735731357SCaroline Tice if (pass_action != -1) 149835731357SCaroline Tice { 149910ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 150010ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 150135731357SCaroline Tice } 150235731357SCaroline Tice if (notify_action != -1) 150335731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 150435731357SCaroline Tice ++num_signals_set; 150535731357SCaroline Tice } 150635731357SCaroline Tice else 150735731357SCaroline Tice { 150835731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 150935731357SCaroline Tice } 151035731357SCaroline Tice } 151110ad7993SCaroline Tice } 151210ad7993SCaroline Tice else 151310ad7993SCaroline Tice { 151410ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 151510ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 151610ad7993SCaroline Tice { 151710ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 151810ad7993SCaroline Tice { 151910ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 152010ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 152110ad7993SCaroline Tice { 152210ad7993SCaroline Tice if (notify_action != -1) 152310ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 152410ad7993SCaroline Tice if (stop_action != -1) 152510ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 152610ad7993SCaroline Tice if (pass_action != -1) 152710ad7993SCaroline Tice { 152810ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 152910ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 153010ad7993SCaroline Tice } 153110ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 153210ad7993SCaroline Tice } 153310ad7993SCaroline Tice } 153410ad7993SCaroline Tice } 153510ad7993SCaroline Tice } 153610ad7993SCaroline Tice 153710ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 153835731357SCaroline Tice 153935731357SCaroline Tice if (num_signals_set > 0) 154035731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 154135731357SCaroline Tice else 154235731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 154335731357SCaroline Tice 154435731357SCaroline Tice return result.Succeeded(); 154535731357SCaroline Tice } 154635731357SCaroline Tice 154735731357SCaroline Tice protected: 154835731357SCaroline Tice 154935731357SCaroline Tice CommandOptions m_options; 155035731357SCaroline Tice }; 155135731357SCaroline Tice 155235731357SCaroline Tice lldb::OptionDefinition 155335731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 155435731357SCaroline Tice { 155535731357SCaroline 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." }, 155635731357SCaroline 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." }, 155735731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 155835731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 155935731357SCaroline Tice }; 156035731357SCaroline Tice 156135731357SCaroline Tice //------------------------------------------------------------------------- 156230fdc8d8SChris Lattner // CommandObjectMultiwordProcess 156330fdc8d8SChris Lattner //------------------------------------------------------------------------- 156430fdc8d8SChris Lattner 15656611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1566a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1567a7015092SGreg Clayton "process", 156830fdc8d8SChris Lattner "A set of commands for operating on a process.", 156930fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 157030fdc8d8SChris Lattner { 1571a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1572a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1573a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1574a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1575*8f343b09SGreg Clayton LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 1576*8f343b09SGreg Clayton LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1577a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 157835731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1579a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1580a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1581a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 158230fdc8d8SChris Lattner } 158330fdc8d8SChris Lattner 158430fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 158530fdc8d8SChris Lattner { 158630fdc8d8SChris Lattner } 158730fdc8d8SChris Lattner 1588