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; 6530fdc8d8SChris Lattner default: 6630fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 6730fdc8d8SChris Lattner break; 6830fdc8d8SChris Lattner 6930fdc8d8SChris Lattner } 7030fdc8d8SChris Lattner return error; 7130fdc8d8SChris Lattner } 7230fdc8d8SChris Lattner 7330fdc8d8SChris Lattner void 7430fdc8d8SChris Lattner ResetOptionValues () 7530fdc8d8SChris Lattner { 7630fdc8d8SChris Lattner Options::ResetOptionValues(); 7730fdc8d8SChris Lattner stop_at_entry = false; 7830fdc8d8SChris Lattner stdin_path.clear(); 7930fdc8d8SChris Lattner stdout_path.clear(); 8030fdc8d8SChris Lattner stderr_path.clear(); 8130fdc8d8SChris Lattner plugin_name.clear(); 8230fdc8d8SChris Lattner } 8330fdc8d8SChris Lattner 8430fdc8d8SChris Lattner const lldb::OptionDefinition* 8530fdc8d8SChris Lattner GetDefinitions () 8630fdc8d8SChris Lattner { 8730fdc8d8SChris Lattner return g_option_table; 8830fdc8d8SChris Lattner } 8930fdc8d8SChris Lattner 9030fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 9130fdc8d8SChris Lattner 9230fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 9330fdc8d8SChris Lattner 9430fdc8d8SChris Lattner // Instance variables to hold the values for command options. 9530fdc8d8SChris Lattner 9630fdc8d8SChris Lattner bool stop_at_entry; 9730fdc8d8SChris Lattner std::string stderr_path; 9830fdc8d8SChris Lattner std::string stdin_path; 9930fdc8d8SChris Lattner std::string stdout_path; 10030fdc8d8SChris Lattner std::string plugin_name; 10130fdc8d8SChris Lattner 10230fdc8d8SChris Lattner }; 10330fdc8d8SChris Lattner 104a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 105a7015092SGreg Clayton CommandObject (interpreter, 106a7015092SGreg Clayton "process launch", 107e3d26315SCaroline Tice "Launch the executable in the debugger.", 108405fe67fSCaroline Tice NULL) 10930fdc8d8SChris Lattner { 110405fe67fSCaroline Tice CommandArgumentEntry arg; 111405fe67fSCaroline Tice CommandArgumentData run_args_arg; 112405fe67fSCaroline Tice 113405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 114405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 115405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 116405fe67fSCaroline Tice 117405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 118405fe67fSCaroline Tice arg.push_back (run_args_arg); 119405fe67fSCaroline Tice 120405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 121405fe67fSCaroline Tice m_arguments.push_back (arg); 12230fdc8d8SChris Lattner } 12330fdc8d8SChris Lattner 12430fdc8d8SChris Lattner 12530fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 12630fdc8d8SChris Lattner { 12730fdc8d8SChris Lattner } 12830fdc8d8SChris Lattner 12930fdc8d8SChris Lattner Options * 13030fdc8d8SChris Lattner GetOptions () 13130fdc8d8SChris Lattner { 13230fdc8d8SChris Lattner return &m_options; 13330fdc8d8SChris Lattner } 13430fdc8d8SChris Lattner 13530fdc8d8SChris Lattner bool 13605faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 13730fdc8d8SChris Lattner { 138a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 13930fdc8d8SChris Lattner 14030fdc8d8SChris Lattner if (target == NULL) 14130fdc8d8SChris Lattner { 14230fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 14330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 14430fdc8d8SChris Lattner return false; 14530fdc8d8SChris Lattner } 14630fdc8d8SChris Lattner 14730fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 14830fdc8d8SChris Lattner char filename[PATH_MAX]; 14930fdc8d8SChris Lattner Module *exe_module = target->GetExecutableModule().get(); 15030fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 15130fdc8d8SChris Lattner 152a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 153a7015092SGreg Clayton if (process && process->IsAlive()) 15430fdc8d8SChris Lattner { 15530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", 15630fdc8d8SChris Lattner process->GetID()); 15730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 15830fdc8d8SChris Lattner return false; 15930fdc8d8SChris Lattner } 16030fdc8d8SChris Lattner 16130fdc8d8SChris Lattner const char *plugin_name; 16230fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 16330fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 16430fdc8d8SChris Lattner else 16530fdc8d8SChris Lattner plugin_name = NULL; 16630fdc8d8SChris Lattner 167a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 16830fdc8d8SChris Lattner 169a7015092SGreg Clayton if (process == NULL) 1703df9a8dfSCaroline Tice { 171a7015092SGreg Clayton result.AppendErrorWithFormat ("Failed to find a process plugin for executable"); 172a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 173a7015092SGreg Clayton return false; 1743df9a8dfSCaroline Tice } 1753df9a8dfSCaroline Tice 176a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 177a7015092SGreg Clayton // might have been set using the "run-args" set variable. 17830fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 17930fdc8d8SChris Lattner { 180a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 181a7015092SGreg Clayton launch_args = process->GetRunArguments(); 18230fdc8d8SChris Lattner } 18330fdc8d8SChris Lattner 184a7015092SGreg Clayton Args environment; 18530fdc8d8SChris Lattner 186a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 187a7015092SGreg Clayton 188a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 189a7015092SGreg Clayton 190a7015092SGreg Clayton if (process->GetDisableASLR()) 191a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 192a7015092SGreg Clayton 19330fdc8d8SChris Lattner const char *archname = exe_module->GetArchitecture().AsCString(); 19430fdc8d8SChris Lattner 19530fdc8d8SChris Lattner const char * stdin_path = NULL; 19630fdc8d8SChris Lattner const char * stdout_path = NULL; 19730fdc8d8SChris Lattner const char * stderr_path = NULL; 19830fdc8d8SChris Lattner 199a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 200a7015092SGreg Clayton if (m_options.stdin_path.empty() && 20130fdc8d8SChris Lattner m_options.stdout_path.empty() && 202a7015092SGreg Clayton m_options.stderr_path.empty()) 20330fdc8d8SChris Lattner { 204a7015092SGreg Clayton // No standard file handles were given on the command line, check 205a7015092SGreg Clayton // with the process object in case they were give using "set settings" 206a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 207a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 208a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 209a7015092SGreg Clayton } 210a7015092SGreg Clayton else 211a7015092SGreg Clayton { 212a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 213a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 214a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 21530fdc8d8SChris Lattner } 21630fdc8d8SChris Lattner 217a7015092SGreg Clayton if (stdin_path == NULL) 218a7015092SGreg Clayton stdin_path = "/dev/null"; 219a7015092SGreg Clayton if (stdout_path == NULL) 220a7015092SGreg Clayton stdout_path = "/dev/null"; 221a7015092SGreg Clayton if (stderr_path == NULL) 222a7015092SGreg Clayton stderr_path = "/dev/null"; 223a7015092SGreg Clayton 224a7015092SGreg Clayton Error error (process->Launch (launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL, 225a7015092SGreg Clayton environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL, 226f681b94fSGreg Clayton launch_flags, 22730fdc8d8SChris Lattner stdin_path, 22830fdc8d8SChris Lattner stdout_path, 22930fdc8d8SChris Lattner stderr_path)); 23030fdc8d8SChris Lattner 23130fdc8d8SChris Lattner if (error.Success()) 23230fdc8d8SChris Lattner { 23330fdc8d8SChris Lattner result.AppendMessageWithFormat ("Launching '%s' (%s)\n", filename, archname); 23405faeb71SGreg Clayton result.SetDidChangeProcessState (true); 23530fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 23630fdc8d8SChris Lattner { 23705faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 23830fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 23930fdc8d8SChris Lattner 24030fdc8d8SChris Lattner if (state == eStateStopped) 24130fdc8d8SChris Lattner { 24205faeb71SGreg Clayton error = process->Resume(); 24305faeb71SGreg Clayton if (error.Success()) 24405faeb71SGreg Clayton { 24505faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 24630fdc8d8SChris Lattner if (synchronous_execution) 24730fdc8d8SChris Lattner { 24805faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 24930fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 25005faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 25105faeb71SGreg Clayton } 25205faeb71SGreg Clayton else 25305faeb71SGreg Clayton { 25405faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 25505faeb71SGreg Clayton } 25605faeb71SGreg Clayton } 25730fdc8d8SChris Lattner } 25830fdc8d8SChris Lattner } 25930fdc8d8SChris Lattner } 26030fdc8d8SChris Lattner 26130fdc8d8SChris Lattner return result.Succeeded(); 26230fdc8d8SChris Lattner } 26330fdc8d8SChris Lattner 264ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 265ebc09c36SJim Ingham { 266ebc09c36SJim Ingham // No repeat for "process launch"... 267ebc09c36SJim Ingham return ""; 268ebc09c36SJim Ingham } 269ebc09c36SJim Ingham 27030fdc8d8SChris Lattner protected: 27130fdc8d8SChris Lattner 27230fdc8d8SChris Lattner CommandOptions m_options; 27330fdc8d8SChris Lattner }; 27430fdc8d8SChris Lattner 27530fdc8d8SChris Lattner 27630fdc8d8SChris Lattner lldb::OptionDefinition 27730fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 27830fdc8d8SChris Lattner { 279deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 280deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 281deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 282deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 283deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 284deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 28530fdc8d8SChris Lattner }; 28630fdc8d8SChris Lattner 28730fdc8d8SChris Lattner 28830fdc8d8SChris Lattner //------------------------------------------------------------------------- 28930fdc8d8SChris Lattner // CommandObjectProcessAttach 29030fdc8d8SChris Lattner //------------------------------------------------------------------------- 29130fdc8d8SChris Lattner 29230fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 29330fdc8d8SChris Lattner { 29430fdc8d8SChris Lattner public: 29530fdc8d8SChris Lattner 29630fdc8d8SChris Lattner class CommandOptions : public Options 29730fdc8d8SChris Lattner { 29830fdc8d8SChris Lattner public: 29930fdc8d8SChris Lattner 30030fdc8d8SChris Lattner CommandOptions () : 30130fdc8d8SChris Lattner Options() 30230fdc8d8SChris Lattner { 30330fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 30430fdc8d8SChris Lattner ResetOptionValues (); 30530fdc8d8SChris Lattner } 30630fdc8d8SChris Lattner 30730fdc8d8SChris Lattner ~CommandOptions () 30830fdc8d8SChris Lattner { 30930fdc8d8SChris Lattner } 31030fdc8d8SChris Lattner 31130fdc8d8SChris Lattner Error 31230fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 31330fdc8d8SChris Lattner { 31430fdc8d8SChris Lattner Error error; 31530fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 31630fdc8d8SChris Lattner bool success = false; 31730fdc8d8SChris Lattner switch (short_option) 31830fdc8d8SChris Lattner { 31930fdc8d8SChris Lattner case 'p': 32030fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 32130fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 32230fdc8d8SChris Lattner { 32330fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 32430fdc8d8SChris Lattner } 32530fdc8d8SChris Lattner break; 32630fdc8d8SChris Lattner 32730fdc8d8SChris Lattner case 'P': 32830fdc8d8SChris Lattner plugin_name = option_arg; 32930fdc8d8SChris Lattner break; 33030fdc8d8SChris Lattner 33130fdc8d8SChris Lattner case 'n': 33230fdc8d8SChris Lattner name.assign(option_arg); 33330fdc8d8SChris Lattner break; 33430fdc8d8SChris Lattner 33530fdc8d8SChris Lattner case 'w': 33630fdc8d8SChris Lattner waitfor = true; 33730fdc8d8SChris Lattner break; 33830fdc8d8SChris Lattner 33930fdc8d8SChris Lattner default: 34030fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 34130fdc8d8SChris Lattner break; 34230fdc8d8SChris Lattner } 34330fdc8d8SChris Lattner return error; 34430fdc8d8SChris Lattner } 34530fdc8d8SChris Lattner 34630fdc8d8SChris Lattner void 34730fdc8d8SChris Lattner ResetOptionValues () 34830fdc8d8SChris Lattner { 34930fdc8d8SChris Lattner Options::ResetOptionValues(); 35030fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 35130fdc8d8SChris Lattner name.clear(); 35230fdc8d8SChris Lattner waitfor = false; 35330fdc8d8SChris Lattner } 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner const lldb::OptionDefinition* 35630fdc8d8SChris Lattner GetDefinitions () 35730fdc8d8SChris Lattner { 35830fdc8d8SChris Lattner return g_option_table; 35930fdc8d8SChris Lattner } 36030fdc8d8SChris Lattner 3615aee162fSJim Ingham virtual bool 362a7015092SGreg Clayton HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 3635aee162fSJim Ingham Args &input, 3645aee162fSJim Ingham int cursor_index, 3655aee162fSJim Ingham int char_pos, 3665aee162fSJim Ingham OptionElementVector &opt_element_vector, 3675aee162fSJim Ingham int opt_element_index, 3685aee162fSJim Ingham int match_start_point, 3695aee162fSJim Ingham int max_return_elements, 3705aee162fSJim Ingham bool &word_complete, 3715aee162fSJim Ingham StringList &matches) 3725aee162fSJim Ingham { 3735aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 3745aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 3755aee162fSJim Ingham 3765aee162fSJim Ingham // We are only completing the name option for now... 3775aee162fSJim Ingham 3785aee162fSJim Ingham const lldb::OptionDefinition *opt_defs = GetDefinitions(); 3795aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 3805aee162fSJim Ingham { 3815aee162fSJim Ingham // Are we in the name? 3825aee162fSJim Ingham 3835aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 3845aee162fSJim Ingham // use the default plugin. 385a7015092SGreg Clayton Process *process = interpeter.GetDebugger().GetExecutionContext().process; 3865aee162fSJim Ingham bool need_to_delete_process = false; 3875aee162fSJim Ingham 3885aee162fSJim Ingham const char *partial_name = NULL; 3895aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 3905aee162fSJim Ingham 3915aee162fSJim Ingham if (process && process->IsAlive()) 3925aee162fSJim Ingham return true; 3935aee162fSJim Ingham 394a7015092SGreg Clayton Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 3955aee162fSJim Ingham if (target == NULL) 3965aee162fSJim Ingham { 3975aee162fSJim Ingham // No target has been set yet, for now do host completion. Otherwise I don't know how we would 3985aee162fSJim Ingham // figure out what the right target to use is... 3995aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4005aee162fSJim Ingham Host::ListProcessesMatchingName (partial_name, matches, pids); 4015aee162fSJim Ingham return true; 4025aee162fSJim Ingham } 4035aee162fSJim Ingham if (!process) 4045aee162fSJim Ingham { 405a7015092SGreg Clayton process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 4065aee162fSJim Ingham need_to_delete_process = true; 4075aee162fSJim Ingham } 4085aee162fSJim Ingham 4095aee162fSJim Ingham if (process) 4105aee162fSJim Ingham { 4115aee162fSJim Ingham matches.Clear(); 4125aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4135aee162fSJim Ingham process->ListProcessesMatchingName (NULL, matches, pids); 4145aee162fSJim Ingham if (need_to_delete_process) 4155aee162fSJim Ingham target->DeleteCurrentProcess(); 4165aee162fSJim Ingham return true; 4175aee162fSJim Ingham } 4185aee162fSJim Ingham } 4195aee162fSJim Ingham 4205aee162fSJim Ingham return false; 4215aee162fSJim Ingham } 4225aee162fSJim Ingham 42330fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 42630fdc8d8SChris Lattner 42730fdc8d8SChris Lattner // Instance variables to hold the values for command options. 42830fdc8d8SChris Lattner 42930fdc8d8SChris Lattner lldb::pid_t pid; 43030fdc8d8SChris Lattner std::string plugin_name; 43130fdc8d8SChris Lattner std::string name; 43230fdc8d8SChris Lattner bool waitfor; 43330fdc8d8SChris Lattner }; 43430fdc8d8SChris Lattner 435a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 436a7015092SGreg Clayton CommandObject (interpreter, 437a7015092SGreg Clayton "process attach", 438e3d26315SCaroline Tice "Attach to a process.", 4395aee162fSJim Ingham "process attach <cmd-options>") 4405aee162fSJim Ingham { 4415aee162fSJim Ingham } 4425aee162fSJim Ingham 4435aee162fSJim Ingham ~CommandObjectProcessAttach () 4445aee162fSJim Ingham { 4455aee162fSJim Ingham } 4465aee162fSJim Ingham 4475aee162fSJim Ingham bool 448a7015092SGreg Clayton Execute (Args& command, 4495aee162fSJim Ingham CommandReturnObject &result) 4505aee162fSJim Ingham { 451a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4525aee162fSJim Ingham 453a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 4545aee162fSJim Ingham if (process) 4555aee162fSJim Ingham { 4565aee162fSJim Ingham if (process->IsAlive()) 4575aee162fSJim Ingham { 4585aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 4595aee162fSJim Ingham process->GetID()); 4605aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 4615aee162fSJim Ingham return false; 4625aee162fSJim Ingham } 4635aee162fSJim Ingham } 4645aee162fSJim Ingham 4655aee162fSJim Ingham if (target == NULL) 4665aee162fSJim Ingham { 4675aee162fSJim Ingham // If there isn't a current target create one. 4685aee162fSJim Ingham TargetSP new_target_sp; 4695aee162fSJim Ingham FileSpec emptyFileSpec; 4705aee162fSJim Ingham ArchSpec emptyArchSpec; 4715aee162fSJim Ingham Error error; 4725aee162fSJim Ingham 473a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 4745aee162fSJim Ingham emptyFileSpec, 4755aee162fSJim Ingham emptyArchSpec, 4765aee162fSJim Ingham NULL, 4775aee162fSJim Ingham false, 4785aee162fSJim Ingham new_target_sp); 4795aee162fSJim Ingham target = new_target_sp.get(); 4805aee162fSJim Ingham if (target == NULL || error.Fail()) 4815aee162fSJim Ingham { 4825aee162fSJim Ingham result.AppendError(error.AsCString("Error creating empty target")); 4835aee162fSJim Ingham return false; 4845aee162fSJim Ingham } 485a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 4865aee162fSJim Ingham } 4875aee162fSJim Ingham 4885aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 4895aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 4905aee162fSJim Ingham 4915aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 4925aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 4935aee162fSJim Ingham 4945aee162fSJim Ingham if (command.GetArgumentCount()) 4955aee162fSJim Ingham { 4965aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 4975aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 4985aee162fSJim Ingham } 4995aee162fSJim Ingham else 5005aee162fSJim Ingham { 5015aee162fSJim Ingham const char *plugin_name = NULL; 5025aee162fSJim Ingham 5035aee162fSJim Ingham if (!m_options.plugin_name.empty()) 5045aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 5055aee162fSJim Ingham 506a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 5075aee162fSJim Ingham 5085aee162fSJim Ingham if (process) 5095aee162fSJim Ingham { 5105aee162fSJim Ingham Error error; 5115aee162fSJim Ingham int attach_pid = m_options.pid; 5125aee162fSJim Ingham 5133a0b9cdfSJim Ingham const char *wait_name = NULL; 5143a0b9cdfSJim Ingham 5155aee162fSJim Ingham if (m_options.name.empty()) 5165aee162fSJim Ingham { 5173a0b9cdfSJim Ingham if (old_exec_module_sp) 5183a0b9cdfSJim Ingham { 5193a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 5203a0b9cdfSJim Ingham } 5215aee162fSJim Ingham } 5225aee162fSJim Ingham else 5235aee162fSJim Ingham { 5243a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 5253a0b9cdfSJim Ingham } 5263a0b9cdfSJim Ingham 5273a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 5283a0b9cdfSJim Ingham if (m_options.waitfor) 5293a0b9cdfSJim Ingham { 5303a0b9cdfSJim Ingham 5313a0b9cdfSJim Ingham if (wait_name == NULL) 5323a0b9cdfSJim Ingham { 5333a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 5343a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 5353a0b9cdfSJim Ingham return false; 5363a0b9cdfSJim Ingham } 5373a0b9cdfSJim Ingham 538a7015092SGreg Clayton m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 5393a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 5405aee162fSJim Ingham if (error.Success()) 5415aee162fSJim Ingham { 5425aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 5435aee162fSJim Ingham } 5445aee162fSJim Ingham else 5455aee162fSJim Ingham { 5465aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 5473a0b9cdfSJim Ingham wait_name, 5485aee162fSJim Ingham error.AsCString()); 5495aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5505aee162fSJim Ingham return false; 5515aee162fSJim Ingham } 5525aee162fSJim Ingham } 5535aee162fSJim Ingham else 5545aee162fSJim Ingham { 5555aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 5565aee162fSJim Ingham // processes with this pid. 5575aee162fSJim Ingham 5583a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 5595aee162fSJim Ingham { 5605aee162fSJim Ingham std::vector<lldb::pid_t> pids; 5615aee162fSJim Ingham StringList matches; 5625aee162fSJim Ingham 5633a0b9cdfSJim Ingham process->ListProcessesMatchingName(wait_name, matches, pids); 5645aee162fSJim Ingham if (matches.GetSize() > 1) 5655aee162fSJim Ingham { 5663a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 5675aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5685aee162fSJim Ingham return false; 5695aee162fSJim Ingham } 5705aee162fSJim Ingham else if (matches.GetSize() == 0) 5715aee162fSJim Ingham { 5723a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 5735aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5745aee162fSJim Ingham return false; 5755aee162fSJim Ingham } 5765aee162fSJim Ingham else 5775aee162fSJim Ingham { 5785aee162fSJim Ingham attach_pid = pids[0]; 5795aee162fSJim Ingham } 5805aee162fSJim Ingham 5815aee162fSJim Ingham } 5825aee162fSJim Ingham 5835aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 5845aee162fSJim Ingham { 5855aee162fSJim Ingham error = process->Attach (attach_pid); 5865aee162fSJim Ingham if (error.Success()) 5875aee162fSJim Ingham { 5885aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 5895aee162fSJim Ingham } 5905aee162fSJim Ingham else 5915aee162fSJim Ingham { 5925aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 5935aee162fSJim Ingham attach_pid, 5945aee162fSJim Ingham error.AsCString()); 5955aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5965aee162fSJim Ingham } 5975aee162fSJim Ingham } 5985aee162fSJim Ingham else 5995aee162fSJim Ingham { 6005aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 6015aee162fSJim Ingham attach_pid, 6025aee162fSJim Ingham error.AsCString()); 6035aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6045aee162fSJim Ingham 6055aee162fSJim Ingham } 6065aee162fSJim Ingham } 6075aee162fSJim Ingham } 6085aee162fSJim Ingham } 6095aee162fSJim Ingham 6105aee162fSJim Ingham if (result.Succeeded()) 6115aee162fSJim Ingham { 6125aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 6135aee162fSJim Ingham if (!old_exec_module_sp) 6145aee162fSJim Ingham { 6155aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6165aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 6175aee162fSJim Ingham 6185aee162fSJim Ingham result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 6195aee162fSJim Ingham new_path); 6205aee162fSJim Ingham } 6215aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 6225aee162fSJim Ingham { 6235aee162fSJim Ingham char old_path[PATH_MAX + 1]; 6245aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6255aee162fSJim Ingham 6265aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 6275aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 6285aee162fSJim Ingham 6295aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6305aee162fSJim Ingham old_path, new_path); 6315aee162fSJim Ingham } 6325aee162fSJim Ingham 6335aee162fSJim Ingham if (!old_arch_spec.IsValid()) 6345aee162fSJim Ingham { 6355aee162fSJim Ingham result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 6365aee162fSJim Ingham } 6375aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 6385aee162fSJim Ingham { 6395aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 6405aee162fSJim Ingham old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 6415aee162fSJim Ingham } 6425aee162fSJim Ingham } 6435aee162fSJim Ingham return result.Succeeded(); 6445aee162fSJim Ingham } 6455aee162fSJim Ingham 6465aee162fSJim Ingham Options * 6475aee162fSJim Ingham GetOptions () 6485aee162fSJim Ingham { 6495aee162fSJim Ingham return &m_options; 6505aee162fSJim Ingham } 6515aee162fSJim Ingham 65230fdc8d8SChris Lattner protected: 65330fdc8d8SChris Lattner 65430fdc8d8SChris Lattner CommandOptions m_options; 65530fdc8d8SChris Lattner }; 65630fdc8d8SChris Lattner 65730fdc8d8SChris Lattner 65830fdc8d8SChris Lattner lldb::OptionDefinition 65930fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 66030fdc8d8SChris Lattner { 661deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 662deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 663deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 664deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 665deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 66630fdc8d8SChris Lattner }; 66730fdc8d8SChris Lattner 66830fdc8d8SChris Lattner //------------------------------------------------------------------------- 66930fdc8d8SChris Lattner // CommandObjectProcessContinue 67030fdc8d8SChris Lattner //------------------------------------------------------------------------- 67130fdc8d8SChris Lattner 67230fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 67330fdc8d8SChris Lattner { 67430fdc8d8SChris Lattner public: 67530fdc8d8SChris Lattner 676a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 677a7015092SGreg Clayton CommandObject (interpreter, 678a7015092SGreg Clayton "process continue", 679e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 68030fdc8d8SChris Lattner "process continue", 68130fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 68230fdc8d8SChris Lattner { 68330fdc8d8SChris Lattner } 68430fdc8d8SChris Lattner 68530fdc8d8SChris Lattner 68630fdc8d8SChris Lattner ~CommandObjectProcessContinue () 68730fdc8d8SChris Lattner { 68830fdc8d8SChris Lattner } 68930fdc8d8SChris Lattner 69030fdc8d8SChris Lattner bool 691a7015092SGreg Clayton Execute (Args& command, 69230fdc8d8SChris Lattner CommandReturnObject &result) 69330fdc8d8SChris Lattner { 694a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 695a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 69630fdc8d8SChris Lattner 69730fdc8d8SChris Lattner if (process == NULL) 69830fdc8d8SChris Lattner { 69930fdc8d8SChris Lattner result.AppendError ("no process to continue"); 70030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 70130fdc8d8SChris Lattner return false; 70230fdc8d8SChris Lattner } 70330fdc8d8SChris Lattner 70430fdc8d8SChris Lattner StateType state = process->GetState(); 70530fdc8d8SChris Lattner if (state == eStateStopped) 70630fdc8d8SChris Lattner { 70730fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 70830fdc8d8SChris Lattner { 70930fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 71030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 71130fdc8d8SChris Lattner return false; 71230fdc8d8SChris Lattner } 71330fdc8d8SChris Lattner 71430fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 71530fdc8d8SChris Lattner 71630fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 71730fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 71830fdc8d8SChris Lattner { 71930fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 72030fdc8d8SChris Lattner } 72130fdc8d8SChris Lattner 72230fdc8d8SChris Lattner Error error(process->Resume()); 72330fdc8d8SChris Lattner if (error.Success()) 72430fdc8d8SChris Lattner { 72530fdc8d8SChris Lattner result.AppendMessageWithFormat ("Resuming process %i\n", process->GetID()); 72630fdc8d8SChris Lattner if (synchronous_execution) 72730fdc8d8SChris Lattner { 728b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 72930fdc8d8SChris Lattner 73030fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 73130fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 73230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 73330fdc8d8SChris Lattner } 73430fdc8d8SChris Lattner else 73530fdc8d8SChris Lattner { 73630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 73730fdc8d8SChris Lattner } 73830fdc8d8SChris Lattner } 73930fdc8d8SChris Lattner else 74030fdc8d8SChris Lattner { 74130fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 74230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 74330fdc8d8SChris Lattner } 74430fdc8d8SChris Lattner } 74530fdc8d8SChris Lattner else 74630fdc8d8SChris Lattner { 74730fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 74830fdc8d8SChris Lattner StateAsCString(state)); 74930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 75030fdc8d8SChris Lattner } 75130fdc8d8SChris Lattner return result.Succeeded(); 75230fdc8d8SChris Lattner } 75330fdc8d8SChris Lattner }; 75430fdc8d8SChris Lattner 75530fdc8d8SChris Lattner //------------------------------------------------------------------------- 75630fdc8d8SChris Lattner // CommandObjectProcessDetach 75730fdc8d8SChris Lattner //------------------------------------------------------------------------- 75830fdc8d8SChris Lattner 75930fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 76030fdc8d8SChris Lattner { 76130fdc8d8SChris Lattner public: 76230fdc8d8SChris Lattner 763a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 764a7015092SGreg Clayton CommandObject (interpreter, 765a7015092SGreg Clayton "process detach", 766e3d26315SCaroline Tice "Detach from the current process being debugged.", 76730fdc8d8SChris Lattner "process detach", 76830fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 76930fdc8d8SChris Lattner { 77030fdc8d8SChris Lattner } 77130fdc8d8SChris Lattner 77230fdc8d8SChris Lattner ~CommandObjectProcessDetach () 77330fdc8d8SChris Lattner { 77430fdc8d8SChris Lattner } 77530fdc8d8SChris Lattner 77630fdc8d8SChris Lattner bool 777a7015092SGreg Clayton Execute (Args& command, 77830fdc8d8SChris Lattner CommandReturnObject &result) 77930fdc8d8SChris Lattner { 780a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 78130fdc8d8SChris Lattner if (process == NULL) 78230fdc8d8SChris Lattner { 78330fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 78430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78530fdc8d8SChris Lattner return false; 78630fdc8d8SChris Lattner } 78730fdc8d8SChris Lattner 78830fdc8d8SChris Lattner Error error (process->Detach()); 78930fdc8d8SChris Lattner if (error.Success()) 79030fdc8d8SChris Lattner { 79130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 79230fdc8d8SChris Lattner } 79330fdc8d8SChris Lattner else 79430fdc8d8SChris Lattner { 79530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 79630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 79730fdc8d8SChris Lattner return false; 79830fdc8d8SChris Lattner } 79930fdc8d8SChris Lattner return result.Succeeded(); 80030fdc8d8SChris Lattner } 80130fdc8d8SChris Lattner }; 80230fdc8d8SChris Lattner 80330fdc8d8SChris Lattner //------------------------------------------------------------------------- 80430fdc8d8SChris Lattner // CommandObjectProcessSignal 80530fdc8d8SChris Lattner //------------------------------------------------------------------------- 80630fdc8d8SChris Lattner 80730fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 80830fdc8d8SChris Lattner { 80930fdc8d8SChris Lattner public: 81030fdc8d8SChris Lattner 811a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 812a7015092SGreg Clayton CommandObject (interpreter, 813a7015092SGreg Clayton "process signal", 814e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 815405fe67fSCaroline Tice NULL) 81630fdc8d8SChris Lattner { 817405fe67fSCaroline Tice CommandArgumentEntry arg; 818405fe67fSCaroline Tice CommandArgumentData signal_arg; 819405fe67fSCaroline Tice 820405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 821405fe67fSCaroline Tice signal_arg.arg_type = eArgTypeUnixSignalNumber; 822405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 823405fe67fSCaroline Tice 824405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 825405fe67fSCaroline Tice arg.push_back (signal_arg); 826405fe67fSCaroline Tice 827405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 828405fe67fSCaroline Tice m_arguments.push_back (arg); 82930fdc8d8SChris Lattner } 83030fdc8d8SChris Lattner 83130fdc8d8SChris Lattner ~CommandObjectProcessSignal () 83230fdc8d8SChris Lattner { 83330fdc8d8SChris Lattner } 83430fdc8d8SChris Lattner 83530fdc8d8SChris Lattner bool 836a7015092SGreg Clayton Execute (Args& command, 83730fdc8d8SChris Lattner CommandReturnObject &result) 83830fdc8d8SChris Lattner { 839a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 84030fdc8d8SChris Lattner if (process == NULL) 84130fdc8d8SChris Lattner { 84230fdc8d8SChris Lattner result.AppendError ("no process to signal"); 84330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 84430fdc8d8SChris Lattner return false; 84530fdc8d8SChris Lattner } 84630fdc8d8SChris Lattner 84730fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 84830fdc8d8SChris Lattner { 849237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 850237cd906SGreg Clayton 851237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 852237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 853237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 854237cd906SGreg Clayton else 855237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 856237cd906SGreg Clayton 857237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 85830fdc8d8SChris Lattner { 85930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 86030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 86130fdc8d8SChris Lattner } 86230fdc8d8SChris Lattner else 86330fdc8d8SChris Lattner { 86430fdc8d8SChris Lattner Error error (process->Signal (signo)); 86530fdc8d8SChris Lattner if (error.Success()) 86630fdc8d8SChris Lattner { 86730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 86830fdc8d8SChris Lattner } 86930fdc8d8SChris Lattner else 87030fdc8d8SChris Lattner { 87130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 87230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 87330fdc8d8SChris Lattner } 87430fdc8d8SChris Lattner } 87530fdc8d8SChris Lattner } 87630fdc8d8SChris Lattner else 87730fdc8d8SChris Lattner { 87830fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 87930fdc8d8SChris Lattner m_cmd_syntax.c_str()); 88030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 88130fdc8d8SChris Lattner } 88230fdc8d8SChris Lattner return result.Succeeded(); 88330fdc8d8SChris Lattner } 88430fdc8d8SChris Lattner }; 88530fdc8d8SChris Lattner 88630fdc8d8SChris Lattner 88730fdc8d8SChris Lattner //------------------------------------------------------------------------- 88830fdc8d8SChris Lattner // CommandObjectProcessInterrupt 88930fdc8d8SChris Lattner //------------------------------------------------------------------------- 89030fdc8d8SChris Lattner 89130fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 89230fdc8d8SChris Lattner { 89330fdc8d8SChris Lattner public: 89430fdc8d8SChris Lattner 89530fdc8d8SChris Lattner 896a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 897a7015092SGreg Clayton CommandObject (interpreter, 898a7015092SGreg Clayton "process interrupt", 899e3d26315SCaroline Tice "Interrupt the current process being debugged.", 90030fdc8d8SChris Lattner "process interrupt", 90130fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 90230fdc8d8SChris Lattner { 90330fdc8d8SChris Lattner } 90430fdc8d8SChris Lattner 90530fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 90630fdc8d8SChris Lattner { 90730fdc8d8SChris Lattner } 90830fdc8d8SChris Lattner 90930fdc8d8SChris Lattner bool 910a7015092SGreg Clayton Execute (Args& command, 91130fdc8d8SChris Lattner CommandReturnObject &result) 91230fdc8d8SChris Lattner { 913a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 91430fdc8d8SChris Lattner if (process == NULL) 91530fdc8d8SChris Lattner { 91630fdc8d8SChris Lattner result.AppendError ("no process to halt"); 91730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 91830fdc8d8SChris Lattner return false; 91930fdc8d8SChris Lattner } 92030fdc8d8SChris Lattner 92130fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 92230fdc8d8SChris Lattner { 92330fdc8d8SChris Lattner Error error(process->Halt ()); 92430fdc8d8SChris Lattner if (error.Success()) 92530fdc8d8SChris Lattner { 92630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 92730fdc8d8SChris Lattner 92830fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 92930fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 93030fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 93130fdc8d8SChris Lattner } 93230fdc8d8SChris Lattner else 93330fdc8d8SChris Lattner { 93430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 93530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 93630fdc8d8SChris Lattner } 93730fdc8d8SChris Lattner } 93830fdc8d8SChris Lattner else 93930fdc8d8SChris Lattner { 94030fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 94130fdc8d8SChris Lattner m_cmd_name.c_str(), 94230fdc8d8SChris Lattner m_cmd_syntax.c_str()); 94330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 94430fdc8d8SChris Lattner } 94530fdc8d8SChris Lattner return result.Succeeded(); 94630fdc8d8SChris Lattner } 94730fdc8d8SChris Lattner }; 94830fdc8d8SChris Lattner 94930fdc8d8SChris Lattner //------------------------------------------------------------------------- 95030fdc8d8SChris Lattner // CommandObjectProcessKill 95130fdc8d8SChris Lattner //------------------------------------------------------------------------- 95230fdc8d8SChris Lattner 95330fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 95430fdc8d8SChris Lattner { 95530fdc8d8SChris Lattner public: 95630fdc8d8SChris Lattner 957a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 958a7015092SGreg Clayton CommandObject (interpreter, 959a7015092SGreg Clayton "process kill", 960e3d26315SCaroline Tice "Terminate the current process being debugged.", 96130fdc8d8SChris Lattner "process kill", 96230fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 96330fdc8d8SChris Lattner { 96430fdc8d8SChris Lattner } 96530fdc8d8SChris Lattner 96630fdc8d8SChris Lattner ~CommandObjectProcessKill () 96730fdc8d8SChris Lattner { 96830fdc8d8SChris Lattner } 96930fdc8d8SChris Lattner 97030fdc8d8SChris Lattner bool 971a7015092SGreg Clayton Execute (Args& command, 97230fdc8d8SChris Lattner CommandReturnObject &result) 97330fdc8d8SChris Lattner { 974a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 97530fdc8d8SChris Lattner if (process == NULL) 97630fdc8d8SChris Lattner { 97730fdc8d8SChris Lattner result.AppendError ("no process to kill"); 97830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 97930fdc8d8SChris Lattner return false; 98030fdc8d8SChris Lattner } 98130fdc8d8SChris Lattner 98230fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 98330fdc8d8SChris Lattner { 98430fdc8d8SChris Lattner Error error (process->Destroy()); 98530fdc8d8SChris Lattner if (error.Success()) 98630fdc8d8SChris Lattner { 98730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 98830fdc8d8SChris Lattner } 98930fdc8d8SChris Lattner else 99030fdc8d8SChris Lattner { 99130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 99230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 99330fdc8d8SChris Lattner } 99430fdc8d8SChris Lattner } 99530fdc8d8SChris Lattner else 99630fdc8d8SChris Lattner { 99730fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 99830fdc8d8SChris Lattner m_cmd_name.c_str(), 99930fdc8d8SChris Lattner m_cmd_syntax.c_str()); 100030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 100130fdc8d8SChris Lattner } 100230fdc8d8SChris Lattner return result.Succeeded(); 100330fdc8d8SChris Lattner } 100430fdc8d8SChris Lattner }; 100530fdc8d8SChris Lattner 100630fdc8d8SChris Lattner //------------------------------------------------------------------------- 10074b9bea87SJim Ingham // CommandObjectProcessStatus 10084b9bea87SJim Ingham //------------------------------------------------------------------------- 10094b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 10104b9bea87SJim Ingham { 10114b9bea87SJim Ingham public: 1012a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1013a7015092SGreg Clayton CommandObject (interpreter, 1014a7015092SGreg Clayton "process status", 1015e3d26315SCaroline Tice "Show the current status and location of executing process.", 1016e3d26315SCaroline Tice "process status", 10174b9bea87SJim Ingham 0) 10184b9bea87SJim Ingham { 10194b9bea87SJim Ingham } 10204b9bea87SJim Ingham 10214b9bea87SJim Ingham ~CommandObjectProcessStatus() 10224b9bea87SJim Ingham { 10234b9bea87SJim Ingham } 10244b9bea87SJim Ingham 10254b9bea87SJim Ingham 10264b9bea87SJim Ingham bool 10274b9bea87SJim Ingham Execute 10284b9bea87SJim Ingham ( 10294b9bea87SJim Ingham Args& command, 10304b9bea87SJim Ingham CommandReturnObject &result 10314b9bea87SJim Ingham ) 10324b9bea87SJim Ingham { 10334b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 10344b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1035a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 10364b9bea87SJim Ingham if (exe_ctx.process) 10374b9bea87SJim Ingham { 10384b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 10394b9bea87SJim Ingham if (StateIsStoppedState(state)) 10404b9bea87SJim Ingham { 10414b9bea87SJim Ingham if (state == eStateExited) 10424b9bea87SJim Ingham { 10434b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 10444b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 10454b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 10464b9bea87SJim Ingham exe_ctx.process->GetID(), 10474b9bea87SJim Ingham exit_status, 10484b9bea87SJim Ingham exit_status, 10494b9bea87SJim Ingham exit_description ? exit_description : ""); 10504b9bea87SJim Ingham } 10514b9bea87SJim Ingham else 10524b9bea87SJim Ingham { 10534b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 10544b9bea87SJim Ingham if (exe_ctx.thread == NULL) 10554b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 10564b9bea87SJim Ingham if (exe_ctx.thread != NULL) 10574b9bea87SJim Ingham { 1058a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 10594b9bea87SJim Ingham } 10604b9bea87SJim Ingham else 10614b9bea87SJim Ingham { 10624b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 10634b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 10644b9bea87SJim Ingham } 10654b9bea87SJim Ingham } 10664b9bea87SJim Ingham } 10674b9bea87SJim Ingham else 10684b9bea87SJim Ingham { 10694b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 10704b9bea87SJim Ingham exe_ctx.process->GetID()); 10714b9bea87SJim Ingham } 10724b9bea87SJim Ingham } 10734b9bea87SJim Ingham else 10744b9bea87SJim Ingham { 10754b9bea87SJim Ingham result.AppendError ("No current location or status available."); 10764b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 10774b9bea87SJim Ingham } 10784b9bea87SJim Ingham return result.Succeeded(); 10794b9bea87SJim Ingham } 10804b9bea87SJim Ingham }; 10814b9bea87SJim Ingham 10824b9bea87SJim Ingham //------------------------------------------------------------------------- 108335731357SCaroline Tice // CommandObjectProcessHandle 108435731357SCaroline Tice //------------------------------------------------------------------------- 108535731357SCaroline Tice 108635731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 108735731357SCaroline Tice { 108835731357SCaroline Tice public: 108935731357SCaroline Tice 109035731357SCaroline Tice class CommandOptions : public Options 109135731357SCaroline Tice { 109235731357SCaroline Tice public: 109335731357SCaroline Tice 109435731357SCaroline Tice CommandOptions () : 109535731357SCaroline Tice Options () 109635731357SCaroline Tice { 109735731357SCaroline Tice ResetOptionValues (); 109835731357SCaroline Tice } 109935731357SCaroline Tice 110035731357SCaroline Tice ~CommandOptions () 110135731357SCaroline Tice { 110235731357SCaroline Tice } 110335731357SCaroline Tice 110435731357SCaroline Tice Error 110535731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 110635731357SCaroline Tice { 110735731357SCaroline Tice Error error; 110835731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 110935731357SCaroline Tice 111035731357SCaroline Tice switch (short_option) 111135731357SCaroline Tice { 111235731357SCaroline Tice case 's': 111335731357SCaroline Tice stop = option_arg; 111435731357SCaroline Tice break; 111535731357SCaroline Tice case 'n': 111635731357SCaroline Tice notify = option_arg; 111735731357SCaroline Tice break; 111835731357SCaroline Tice case 'p': 111935731357SCaroline Tice pass = option_arg; 112035731357SCaroline Tice break; 112135731357SCaroline Tice default: 112235731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 112335731357SCaroline Tice break; 112435731357SCaroline Tice } 112535731357SCaroline Tice return error; 112635731357SCaroline Tice } 112735731357SCaroline Tice 112835731357SCaroline Tice void 112935731357SCaroline Tice ResetOptionValues () 113035731357SCaroline Tice { 113135731357SCaroline Tice Options::ResetOptionValues(); 113235731357SCaroline Tice stop.clear(); 113335731357SCaroline Tice notify.clear(); 113435731357SCaroline Tice pass.clear(); 113535731357SCaroline Tice } 113635731357SCaroline Tice 113735731357SCaroline Tice const lldb::OptionDefinition* 113835731357SCaroline Tice GetDefinitions () 113935731357SCaroline Tice { 114035731357SCaroline Tice return g_option_table; 114135731357SCaroline Tice } 114235731357SCaroline Tice 114335731357SCaroline Tice // Options table: Required for subclasses of Options. 114435731357SCaroline Tice 114535731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 114635731357SCaroline Tice 114735731357SCaroline Tice // Instance variables to hold the values for command options. 114835731357SCaroline Tice 114935731357SCaroline Tice std::string stop; 115035731357SCaroline Tice std::string notify; 115135731357SCaroline Tice std::string pass; 115235731357SCaroline Tice }; 115335731357SCaroline Tice 115435731357SCaroline Tice 115535731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 115635731357SCaroline Tice CommandObject (interpreter, 115735731357SCaroline Tice "process handle", 1158*10ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 115935731357SCaroline Tice NULL) 116035731357SCaroline Tice { 1161*10ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 116235731357SCaroline Tice CommandArgumentEntry arg; 116335731357SCaroline Tice CommandArgumentData signal_name_arg; 116435731357SCaroline Tice 116535731357SCaroline Tice signal_name_arg.arg_type = eArgTypeSignalName; 1166*10ad7993SCaroline Tice signal_name_arg.arg_repetition = eArgRepeatStar; 116735731357SCaroline Tice 116835731357SCaroline Tice arg.push_back (signal_name_arg); 116935731357SCaroline Tice 117035731357SCaroline Tice m_arguments.push_back (arg); 117135731357SCaroline Tice } 117235731357SCaroline Tice 117335731357SCaroline Tice ~CommandObjectProcessHandle () 117435731357SCaroline Tice { 117535731357SCaroline Tice } 117635731357SCaroline Tice 117735731357SCaroline Tice Options * 117835731357SCaroline Tice GetOptions () 117935731357SCaroline Tice { 118035731357SCaroline Tice return &m_options; 118135731357SCaroline Tice } 118235731357SCaroline Tice 118335731357SCaroline Tice bool 1184*10ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 118535731357SCaroline Tice { 118635731357SCaroline Tice bool okay = true; 118735731357SCaroline Tice 1188*10ad7993SCaroline Tice bool success = false; 1189*10ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 1190*10ad7993SCaroline Tice 1191*10ad7993SCaroline Tice if (success && tmp_value) 1192*10ad7993SCaroline Tice real_value = 1; 1193*10ad7993SCaroline Tice else if (success && !tmp_value) 1194*10ad7993SCaroline Tice real_value = 0; 119535731357SCaroline Tice else 119635731357SCaroline Tice { 119735731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 1198*10ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 1199*10ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 120035731357SCaroline Tice okay = false; 120135731357SCaroline Tice } 120235731357SCaroline Tice 120335731357SCaroline Tice return okay; 120435731357SCaroline Tice } 120535731357SCaroline Tice 1206*10ad7993SCaroline Tice void 1207*10ad7993SCaroline Tice PrintSignalHeader (Stream &str) 1208*10ad7993SCaroline Tice { 1209*10ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 1210*10ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 1211*10ad7993SCaroline Tice } 1212*10ad7993SCaroline Tice 1213*10ad7993SCaroline Tice void 1214*10ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 1215*10ad7993SCaroline Tice { 1216*10ad7993SCaroline Tice bool stop; 1217*10ad7993SCaroline Tice bool suppress; 1218*10ad7993SCaroline Tice bool notify; 1219*10ad7993SCaroline Tice 1220*10ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 1221*10ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 1222*10ad7993SCaroline Tice { 1223*10ad7993SCaroline Tice bool pass = !suppress; 1224*10ad7993SCaroline Tice str.Printf ("%s %s %s", 1225*10ad7993SCaroline Tice (pass ? "true " : "false"), 1226*10ad7993SCaroline Tice (stop ? "true " : "false"), 1227*10ad7993SCaroline Tice (notify ? "true " : "false")); 1228*10ad7993SCaroline Tice } 1229*10ad7993SCaroline Tice str.Printf ("\n"); 1230*10ad7993SCaroline Tice } 1231*10ad7993SCaroline Tice 1232*10ad7993SCaroline Tice void 1233*10ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 1234*10ad7993SCaroline Tice { 1235*10ad7993SCaroline Tice PrintSignalHeader (str); 1236*10ad7993SCaroline Tice 1237*10ad7993SCaroline Tice if (num_valid_signals > 0) 1238*10ad7993SCaroline Tice { 1239*10ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 1240*10ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 1241*10ad7993SCaroline Tice { 1242*10ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 1243*10ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1244*10ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 1245*10ad7993SCaroline Tice } 1246*10ad7993SCaroline Tice } 1247*10ad7993SCaroline Tice else // Print info for ALL signals 1248*10ad7993SCaroline Tice { 1249*10ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 1250*10ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1251*10ad7993SCaroline Tice { 1252*10ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 1253*10ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 1254*10ad7993SCaroline Tice } 1255*10ad7993SCaroline Tice } 1256*10ad7993SCaroline Tice } 1257*10ad7993SCaroline Tice 125835731357SCaroline Tice bool 125935731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 126035731357SCaroline Tice { 126135731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 126235731357SCaroline Tice 126335731357SCaroline Tice if (!target_sp) 126435731357SCaroline Tice { 126535731357SCaroline Tice result.AppendError ("No current target;" 126635731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 126735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 126835731357SCaroline Tice return false; 126935731357SCaroline Tice } 127035731357SCaroline Tice 127135731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 127235731357SCaroline Tice 127335731357SCaroline Tice if (!process_sp) 127435731357SCaroline Tice { 127535731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 127635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 127735731357SCaroline Tice return false; 127835731357SCaroline Tice } 127935731357SCaroline Tice 128035731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 128135731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 128235731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 128335731357SCaroline Tice 128435731357SCaroline Tice if (! m_options.stop.empty() 1285*10ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 128635731357SCaroline Tice { 128735731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 128835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 128935731357SCaroline Tice return false; 129035731357SCaroline Tice } 129135731357SCaroline Tice 129235731357SCaroline Tice if (! m_options.notify.empty() 1293*10ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 129435731357SCaroline Tice { 129535731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 129635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 129735731357SCaroline Tice return false; 129835731357SCaroline Tice } 129935731357SCaroline Tice 130035731357SCaroline Tice if (! m_options.pass.empty() 1301*10ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 130235731357SCaroline Tice { 130335731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 130435731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 130535731357SCaroline Tice return false; 130635731357SCaroline Tice } 130735731357SCaroline Tice 130835731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 130935731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 131035731357SCaroline Tice int num_signals_set = 0; 131135731357SCaroline Tice 1312*10ad7993SCaroline Tice if (num_args > 0) 1313*10ad7993SCaroline Tice { 131435731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 131535731357SCaroline Tice { 131635731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 131735731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 131835731357SCaroline Tice { 1319*10ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 132035731357SCaroline Tice // the value is either 0 or 1. 132135731357SCaroline Tice if (stop_action != -1) 132235731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 132335731357SCaroline Tice if (pass_action != -1) 132435731357SCaroline Tice { 1325*10ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 1326*10ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 132735731357SCaroline Tice } 132835731357SCaroline Tice if (notify_action != -1) 132935731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 133035731357SCaroline Tice ++num_signals_set; 133135731357SCaroline Tice } 133235731357SCaroline Tice else 133335731357SCaroline Tice { 133435731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 133535731357SCaroline Tice } 133635731357SCaroline Tice } 1337*10ad7993SCaroline Tice } 1338*10ad7993SCaroline Tice else 1339*10ad7993SCaroline Tice { 1340*10ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 1341*10ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 1342*10ad7993SCaroline Tice { 1343*10ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 1344*10ad7993SCaroline Tice { 1345*10ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 1346*10ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1347*10ad7993SCaroline Tice { 1348*10ad7993SCaroline Tice if (notify_action != -1) 1349*10ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 1350*10ad7993SCaroline Tice if (stop_action != -1) 1351*10ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 1352*10ad7993SCaroline Tice if (pass_action != -1) 1353*10ad7993SCaroline Tice { 1354*10ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 1355*10ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 1356*10ad7993SCaroline Tice } 1357*10ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 1358*10ad7993SCaroline Tice } 1359*10ad7993SCaroline Tice } 1360*10ad7993SCaroline Tice } 1361*10ad7993SCaroline Tice } 1362*10ad7993SCaroline Tice 1363*10ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 136435731357SCaroline Tice 136535731357SCaroline Tice if (num_signals_set > 0) 136635731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 136735731357SCaroline Tice else 136835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 136935731357SCaroline Tice 137035731357SCaroline Tice return result.Succeeded(); 137135731357SCaroline Tice } 137235731357SCaroline Tice 137335731357SCaroline Tice protected: 137435731357SCaroline Tice 137535731357SCaroline Tice CommandOptions m_options; 137635731357SCaroline Tice }; 137735731357SCaroline Tice 137835731357SCaroline Tice lldb::OptionDefinition 137935731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 138035731357SCaroline Tice { 138135731357SCaroline 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." }, 138235731357SCaroline 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." }, 138335731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 138435731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 138535731357SCaroline Tice }; 138635731357SCaroline Tice 138735731357SCaroline Tice //------------------------------------------------------------------------- 138830fdc8d8SChris Lattner // CommandObjectMultiwordProcess 138930fdc8d8SChris Lattner //------------------------------------------------------------------------- 139030fdc8d8SChris Lattner 13916611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1392a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1393a7015092SGreg Clayton "process", 139430fdc8d8SChris Lattner "A set of commands for operating on a process.", 139530fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 139630fdc8d8SChris Lattner { 1397a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1398a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1399a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1400a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1401a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 140235731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1403a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1404a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1405a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 140630fdc8d8SChris Lattner } 140730fdc8d8SChris Lattner 140830fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 140930fdc8d8SChris Lattner { 141030fdc8d8SChris Lattner } 141130fdc8d8SChris Lattner 1412