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" 21*4b9bea87SJim 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 10430fdc8d8SChris Lattner CommandObjectProcessLaunch () : 10530fdc8d8SChris Lattner CommandObject ("process launch", 10630fdc8d8SChris Lattner "Launches the executable in the debugger.", 10730fdc8d8SChris Lattner "process launch [<cmd-options>] [<arguments-for-running-the-program>]") 10830fdc8d8SChris Lattner { 10930fdc8d8SChris Lattner } 11030fdc8d8SChris Lattner 11130fdc8d8SChris Lattner 11230fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 11330fdc8d8SChris Lattner { 11430fdc8d8SChris Lattner } 11530fdc8d8SChris Lattner 11630fdc8d8SChris Lattner Options * 11730fdc8d8SChris Lattner GetOptions () 11830fdc8d8SChris Lattner { 11930fdc8d8SChris Lattner return &m_options; 12030fdc8d8SChris Lattner } 12130fdc8d8SChris Lattner 12230fdc8d8SChris Lattner bool 12330fdc8d8SChris Lattner Execute (Args& launch_args, 12430fdc8d8SChris Lattner CommandContext *context, 12530fdc8d8SChris Lattner CommandInterpreter *interpreter, 12630fdc8d8SChris Lattner CommandReturnObject &result) 12730fdc8d8SChris Lattner { 12830fdc8d8SChris Lattner Target *target = context->GetTarget(); 12930fdc8d8SChris Lattner bool synchronous_execution = interpreter->GetSynchronous (); 13030fdc8d8SChris Lattner // bool launched = false; 13130fdc8d8SChris Lattner // bool stopped_after_launch = false; 13230fdc8d8SChris Lattner 13330fdc8d8SChris Lattner if (target == NULL) 13430fdc8d8SChris Lattner { 13530fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 13630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 13730fdc8d8SChris Lattner return false; 13830fdc8d8SChris Lattner } 13930fdc8d8SChris Lattner 14030fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 14130fdc8d8SChris Lattner Listener *listener = interpreter->GetListener(); 14230fdc8d8SChris Lattner if (listener == NULL) 14330fdc8d8SChris Lattner { 14430fdc8d8SChris Lattner result.AppendError ("operation not allowed through the command interpreter"); 14530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 14630fdc8d8SChris Lattner return false; 14730fdc8d8SChris Lattner } 14830fdc8d8SChris Lattner 14930fdc8d8SChris Lattner char filename[PATH_MAX]; 15030fdc8d8SChris Lattner Module *exe_module = target->GetExecutableModule().get(); 15130fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 15230fdc8d8SChris Lattner 15330fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 15430fdc8d8SChris Lattner if (process) 15530fdc8d8SChris Lattner { 15630fdc8d8SChris Lattner if (process->IsAlive()) 15730fdc8d8SChris Lattner { 15830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", 15930fdc8d8SChris Lattner process->GetID()); 16030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 16130fdc8d8SChris Lattner return false; 16230fdc8d8SChris Lattner } 16330fdc8d8SChris Lattner } 16430fdc8d8SChris Lattner 16530fdc8d8SChris Lattner const char *plugin_name; 16630fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 16730fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 16830fdc8d8SChris Lattner else 16930fdc8d8SChris Lattner plugin_name = NULL; 17030fdc8d8SChris Lattner 17130fdc8d8SChris Lattner process = target->CreateProcess (*listener, plugin_name).get(); 17230fdc8d8SChris Lattner 17330fdc8d8SChris Lattner const Args *environment = interpreter->GetEnvironmentVariables(); 17430fdc8d8SChris Lattner const Args *run_args = interpreter->GetProgramArguments(); 17530fdc8d8SChris Lattner 17630fdc8d8SChris Lattner // There are two possible sources of args to be passed to the process upon launching: Those the user 17730fdc8d8SChris Lattner // typed at the run command (launch_args); or those the user pre-set in the run-args variable (run_args). 17830fdc8d8SChris Lattner 17930fdc8d8SChris Lattner // If launch_args is empty, use run_args. 18030fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 18130fdc8d8SChris Lattner { 18230fdc8d8SChris Lattner if (run_args != NULL) 18330fdc8d8SChris Lattner launch_args.AppendArguments (*run_args); 18430fdc8d8SChris Lattner } 18530fdc8d8SChris Lattner else 18630fdc8d8SChris Lattner { 18730fdc8d8SChris Lattner // launch-args was not empty; use that, AND re-set run-args to contains launch-args values. 18830fdc8d8SChris Lattner StateVariable *run_args_var = interpreter->GetStateVariable ("run-args"); 18930fdc8d8SChris Lattner if (run_args_var != NULL) 19030fdc8d8SChris Lattner { 19130fdc8d8SChris Lattner run_args_var->ArrayClearValues(); 19230fdc8d8SChris Lattner run_args_var->GetArgs().AppendArguments (launch_args); 19330fdc8d8SChris Lattner } 19430fdc8d8SChris Lattner } 19530fdc8d8SChris Lattner 19630fdc8d8SChris Lattner 19730fdc8d8SChris Lattner if (process) 19830fdc8d8SChris Lattner { 19930fdc8d8SChris Lattner const char *archname = exe_module->GetArchitecture().AsCString(); 20030fdc8d8SChris Lattner 20130fdc8d8SChris Lattner const char * stdin_path = NULL; 20230fdc8d8SChris Lattner const char * stdout_path = NULL; 20330fdc8d8SChris Lattner const char * stderr_path = NULL; 20430fdc8d8SChris Lattner 20530fdc8d8SChris Lattner if (!(m_options.stdin_path.empty() && 20630fdc8d8SChris Lattner m_options.stdout_path.empty() && 20730fdc8d8SChris Lattner m_options.stderr_path.empty())) 20830fdc8d8SChris Lattner { 20930fdc8d8SChris Lattner stdin_path = m_options.stdin_path.empty() ? "/dev/null" : m_options.stdin_path.c_str(); 21030fdc8d8SChris Lattner stdout_path = m_options.stdout_path.empty() ? "/dev/null" : m_options.stdout_path.c_str(); 21130fdc8d8SChris Lattner stderr_path = m_options.stderr_path.empty() ? "/dev/null" : m_options.stderr_path.c_str(); 21230fdc8d8SChris Lattner } 21330fdc8d8SChris Lattner 21430fdc8d8SChris Lattner Error error (process->Launch (launch_args.GetConstArgumentVector(), 21530fdc8d8SChris Lattner environment ? environment->GetConstArgumentVector() : NULL, 21630fdc8d8SChris Lattner stdin_path, 21730fdc8d8SChris Lattner stdout_path, 21830fdc8d8SChris Lattner stderr_path)); 21930fdc8d8SChris Lattner 22030fdc8d8SChris Lattner if (error.Success()) 22130fdc8d8SChris Lattner { 22230fdc8d8SChris Lattner result.AppendMessageWithFormat ("Launching '%s' (%s)\n", filename, archname); 22330fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 22430fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 22530fdc8d8SChris Lattner { 22630fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 22730fdc8d8SChris Lattner 22830fdc8d8SChris Lattner if (state == eStateStopped) 22930fdc8d8SChris Lattner { 23030fdc8d8SChris Lattner // Call continue_command. 23130fdc8d8SChris Lattner CommandReturnObject continue_result; 23230fdc8d8SChris Lattner interpreter->HandleCommand("process continue", false, continue_result); 23330fdc8d8SChris Lattner } 23430fdc8d8SChris Lattner 23530fdc8d8SChris Lattner if (synchronous_execution) 23630fdc8d8SChris Lattner { 23730fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 23830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 23930fdc8d8SChris Lattner } 24030fdc8d8SChris Lattner } 24130fdc8d8SChris Lattner } 24230fdc8d8SChris Lattner else 24330fdc8d8SChris Lattner { 24430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process launch failed: %s", 24530fdc8d8SChris Lattner error.AsCString()); 24630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 24730fdc8d8SChris Lattner } 24830fdc8d8SChris Lattner } 24930fdc8d8SChris Lattner else 25030fdc8d8SChris Lattner { 25130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process launch failed: unable to create a process object.\n"); 25230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 25330fdc8d8SChris Lattner return false; 25430fdc8d8SChris Lattner } 25530fdc8d8SChris Lattner 25630fdc8d8SChris Lattner return result.Succeeded(); 25730fdc8d8SChris Lattner } 25830fdc8d8SChris Lattner 25930fdc8d8SChris Lattner protected: 26030fdc8d8SChris Lattner 26130fdc8d8SChris Lattner CommandOptions m_options; 26230fdc8d8SChris Lattner }; 26330fdc8d8SChris Lattner 26430fdc8d8SChris Lattner 26530fdc8d8SChris Lattner lldb::OptionDefinition 26630fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 26730fdc8d8SChris Lattner { 2688651121cSJim Ingham { LLDB_OPT_SET_1, false, "stop-at-entry", 's', no_argument, NULL, 0, NULL, "Stop at the entry point of the program when launching a process."}, 2698651121cSJim Ingham { LLDB_OPT_SET_1, false, "stdin", 'i', required_argument, NULL, 0, "<path>", "Redirect stdin for the process to <path>."}, 2708651121cSJim Ingham { LLDB_OPT_SET_1, false, "stdout", 'o', required_argument, NULL, 0, "<path>", "Redirect stdout for the process to <path>."}, 2718651121cSJim Ingham { LLDB_OPT_SET_1, false, "stderr", 'e', required_argument, NULL, 0, "<path>", "Redirect stderr for the process to <path>."}, 2728651121cSJim Ingham { LLDB_OPT_SET_1, false, "plugin", 'p', required_argument, NULL, 0, "<plugin>", "Name of the process plugin you want to use."}, 27330fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 27430fdc8d8SChris Lattner }; 27530fdc8d8SChris Lattner 27630fdc8d8SChris Lattner 27730fdc8d8SChris Lattner //------------------------------------------------------------------------- 27830fdc8d8SChris Lattner // CommandObjectProcessAttach 27930fdc8d8SChris Lattner //------------------------------------------------------------------------- 28030fdc8d8SChris Lattner 28130fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 28230fdc8d8SChris Lattner { 28330fdc8d8SChris Lattner public: 28430fdc8d8SChris Lattner 28530fdc8d8SChris Lattner CommandObjectProcessAttach () : 28630fdc8d8SChris Lattner CommandObject ("process attach", 28730fdc8d8SChris Lattner "Attaches to a process.", 28830fdc8d8SChris Lattner "process attach <cmd-options>") 28930fdc8d8SChris Lattner { 29030fdc8d8SChris Lattner SetHelpLong("Currently, you must set the executable file before you can attach " 29130fdc8d8SChris Lattner "to a process.\n"); 29230fdc8d8SChris Lattner } 29330fdc8d8SChris Lattner 29430fdc8d8SChris Lattner ~CommandObjectProcessAttach () 29530fdc8d8SChris Lattner { 29630fdc8d8SChris Lattner } 29730fdc8d8SChris Lattner 29830fdc8d8SChris Lattner bool 29930fdc8d8SChris Lattner Execute (Args& command, 30030fdc8d8SChris Lattner CommandContext *context, 30130fdc8d8SChris Lattner CommandInterpreter *interpreter, 30230fdc8d8SChris Lattner CommandReturnObject &result) 30330fdc8d8SChris Lattner { 30430fdc8d8SChris Lattner Target *target = context->GetTarget(); 30530fdc8d8SChris Lattner if (target == NULL) 30630fdc8d8SChris Lattner { 30730fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 30830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 30930fdc8d8SChris Lattner return false; 31030fdc8d8SChris Lattner } 31130fdc8d8SChris Lattner 31230fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 31330fdc8d8SChris Lattner Listener *listener = interpreter->GetListener(); 31430fdc8d8SChris Lattner if (listener == NULL) 31530fdc8d8SChris Lattner { 31630fdc8d8SChris Lattner result.AppendError ("operation not allowed through the command interpreter"); 31730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 31830fdc8d8SChris Lattner return false; 31930fdc8d8SChris Lattner } 32030fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 32130fdc8d8SChris Lattner if (process) 32230fdc8d8SChris Lattner { 32330fdc8d8SChris Lattner if (process->IsAlive()) 32430fdc8d8SChris Lattner { 32530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", process->GetID()); 32630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 32730fdc8d8SChris Lattner return false; 32830fdc8d8SChris Lattner } 32930fdc8d8SChris Lattner } 33030fdc8d8SChris Lattner 33130fdc8d8SChris Lattner if (command.GetArgumentCount()) 33230fdc8d8SChris Lattner { 33330fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 33430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 33530fdc8d8SChris Lattner } 33630fdc8d8SChris Lattner else 33730fdc8d8SChris Lattner { 33830fdc8d8SChris Lattner const char *plugin_name = NULL; 33930fdc8d8SChris Lattner 34030fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 34130fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 34230fdc8d8SChris Lattner 34330fdc8d8SChris Lattner process = target->CreateProcess (*listener, plugin_name).get(); 34430fdc8d8SChris Lattner 34530fdc8d8SChris Lattner if (process) 34630fdc8d8SChris Lattner { 34730fdc8d8SChris Lattner Error error; 34830fdc8d8SChris Lattner int attach_pid = m_options.pid; 34930fdc8d8SChris Lattner 35030fdc8d8SChris Lattner if (attach_pid != LLDB_INVALID_PROCESS_ID) 35130fdc8d8SChris Lattner { 35230fdc8d8SChris Lattner error = process->Attach (attach_pid); 35330fdc8d8SChris Lattner if (error.Success()) 35430fdc8d8SChris Lattner { 35530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 35630fdc8d8SChris Lattner } 35730fdc8d8SChris Lattner else 35830fdc8d8SChris Lattner { 35930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 36030fdc8d8SChris Lattner attach_pid, 36130fdc8d8SChris Lattner error.AsCString()); 36230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 36330fdc8d8SChris Lattner } 36430fdc8d8SChris Lattner } 36530fdc8d8SChris Lattner else if (!m_options.name.empty()) 36630fdc8d8SChris Lattner { 36730fdc8d8SChris Lattner error = process->Attach (m_options.name.c_str(), m_options.waitfor); 36830fdc8d8SChris Lattner if (error.Success()) 36930fdc8d8SChris Lattner { 37030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 37130fdc8d8SChris Lattner } 37230fdc8d8SChris Lattner else 37330fdc8d8SChris Lattner { 37430fdc8d8SChris Lattner if (m_options.waitfor) 37530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 37630fdc8d8SChris Lattner m_options.name.c_str(), 37730fdc8d8SChris Lattner error.AsCString()); 37830fdc8d8SChris Lattner else 37930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to a process named '%s': %s\n", 38030fdc8d8SChris Lattner m_options.name.c_str(), 38130fdc8d8SChris Lattner error.AsCString()); 38230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 38330fdc8d8SChris Lattner } 38430fdc8d8SChris Lattner } 38530fdc8d8SChris Lattner } 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner return result.Succeeded(); 38830fdc8d8SChris Lattner } 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner Options * 39130fdc8d8SChris Lattner GetOptions () 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner return &m_options; 39430fdc8d8SChris Lattner } 39530fdc8d8SChris Lattner 39630fdc8d8SChris Lattner class CommandOptions : public Options 39730fdc8d8SChris Lattner { 39830fdc8d8SChris Lattner public: 39930fdc8d8SChris Lattner 40030fdc8d8SChris Lattner CommandOptions () : 40130fdc8d8SChris Lattner Options() 40230fdc8d8SChris Lattner { 40330fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 40430fdc8d8SChris Lattner ResetOptionValues (); 40530fdc8d8SChris Lattner } 40630fdc8d8SChris Lattner 40730fdc8d8SChris Lattner ~CommandOptions () 40830fdc8d8SChris Lattner { 40930fdc8d8SChris Lattner } 41030fdc8d8SChris Lattner 41130fdc8d8SChris Lattner Error 41230fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 41330fdc8d8SChris Lattner { 41430fdc8d8SChris Lattner Error error; 41530fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 41630fdc8d8SChris Lattner bool success = false; 41730fdc8d8SChris Lattner switch (short_option) 41830fdc8d8SChris Lattner { 41930fdc8d8SChris Lattner case 'p': 42030fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 42130fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 42230fdc8d8SChris Lattner { 42330fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 42430fdc8d8SChris Lattner } 42530fdc8d8SChris Lattner break; 42630fdc8d8SChris Lattner 42730fdc8d8SChris Lattner case 'P': 42830fdc8d8SChris Lattner plugin_name = option_arg; 42930fdc8d8SChris Lattner break; 43030fdc8d8SChris Lattner 43130fdc8d8SChris Lattner case 'n': 43230fdc8d8SChris Lattner name.assign(option_arg); 43330fdc8d8SChris Lattner break; 43430fdc8d8SChris Lattner 43530fdc8d8SChris Lattner case 'w': 43630fdc8d8SChris Lattner waitfor = true; 43730fdc8d8SChris Lattner break; 43830fdc8d8SChris Lattner 43930fdc8d8SChris Lattner default: 44030fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 44130fdc8d8SChris Lattner break; 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner return error; 44430fdc8d8SChris Lattner } 44530fdc8d8SChris Lattner 44630fdc8d8SChris Lattner void 44730fdc8d8SChris Lattner ResetOptionValues () 44830fdc8d8SChris Lattner { 44930fdc8d8SChris Lattner Options::ResetOptionValues(); 45030fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 45130fdc8d8SChris Lattner name.clear(); 45230fdc8d8SChris Lattner waitfor = false; 45330fdc8d8SChris Lattner } 45430fdc8d8SChris Lattner 45530fdc8d8SChris Lattner const lldb::OptionDefinition* 45630fdc8d8SChris Lattner GetDefinitions () 45730fdc8d8SChris Lattner { 45830fdc8d8SChris Lattner return g_option_table; 45930fdc8d8SChris Lattner } 46030fdc8d8SChris Lattner 46130fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 46230fdc8d8SChris Lattner 46330fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 46430fdc8d8SChris Lattner 46530fdc8d8SChris Lattner // Instance variables to hold the values for command options. 46630fdc8d8SChris Lattner 46730fdc8d8SChris Lattner lldb::pid_t pid; 46830fdc8d8SChris Lattner std::string plugin_name; 46930fdc8d8SChris Lattner std::string name; 47030fdc8d8SChris Lattner bool waitfor; 47130fdc8d8SChris Lattner }; 47230fdc8d8SChris Lattner 47330fdc8d8SChris Lattner protected: 47430fdc8d8SChris Lattner 47530fdc8d8SChris Lattner CommandOptions m_options; 47630fdc8d8SChris Lattner }; 47730fdc8d8SChris Lattner 47830fdc8d8SChris Lattner 47930fdc8d8SChris Lattner lldb::OptionDefinition 48030fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 48130fdc8d8SChris Lattner { 4828651121cSJim Ingham { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, "<plugin>", "Name of the process plugin you want to use."}, 4838651121cSJim Ingham { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, "<pid>", "The process ID of an existing process to attach to."}, 4848651121cSJim Ingham { LLDB_OPT_SET_2, true, "name", 'n', required_argument, NULL, 0, "<process-name>", "The name of the process to attach to."}, 4858651121cSJim Ingham { LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, NULL, "Wait for the the process with <process-name> to launch."}, 48630fdc8d8SChris Lattner { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } 48730fdc8d8SChris Lattner }; 48830fdc8d8SChris Lattner 48930fdc8d8SChris Lattner //------------------------------------------------------------------------- 49030fdc8d8SChris Lattner // CommandObjectProcessContinue 49130fdc8d8SChris Lattner //------------------------------------------------------------------------- 49230fdc8d8SChris Lattner 49330fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 49430fdc8d8SChris Lattner { 49530fdc8d8SChris Lattner public: 49630fdc8d8SChris Lattner 49730fdc8d8SChris Lattner CommandObjectProcessContinue () : 49830fdc8d8SChris Lattner CommandObject ("process continue", 49930fdc8d8SChris Lattner "Continues execution all threads in the current process.", 50030fdc8d8SChris Lattner "process continue", 50130fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 50230fdc8d8SChris Lattner { 50330fdc8d8SChris Lattner } 50430fdc8d8SChris Lattner 50530fdc8d8SChris Lattner 50630fdc8d8SChris Lattner ~CommandObjectProcessContinue () 50730fdc8d8SChris Lattner { 50830fdc8d8SChris Lattner } 50930fdc8d8SChris Lattner 51030fdc8d8SChris Lattner bool 51130fdc8d8SChris Lattner Execute (Args& command, 51230fdc8d8SChris Lattner CommandContext *context, 51330fdc8d8SChris Lattner CommandInterpreter *interpreter, 51430fdc8d8SChris Lattner CommandReturnObject &result) 51530fdc8d8SChris Lattner { 51630fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 51730fdc8d8SChris Lattner bool synchronous_execution = interpreter->GetSynchronous (); 51830fdc8d8SChris Lattner 51930fdc8d8SChris Lattner if (process == NULL) 52030fdc8d8SChris Lattner { 52130fdc8d8SChris Lattner result.AppendError ("no process to continue"); 52230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 52330fdc8d8SChris Lattner return false; 52430fdc8d8SChris Lattner } 52530fdc8d8SChris Lattner 52630fdc8d8SChris Lattner StateType state = process->GetState(); 52730fdc8d8SChris Lattner if (state == eStateStopped) 52830fdc8d8SChris Lattner { 52930fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 53030fdc8d8SChris Lattner { 53130fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 53230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 53330fdc8d8SChris Lattner return false; 53430fdc8d8SChris Lattner } 53530fdc8d8SChris Lattner 53630fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 53730fdc8d8SChris Lattner 53830fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 53930fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 54030fdc8d8SChris Lattner { 54130fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 54230fdc8d8SChris Lattner } 54330fdc8d8SChris Lattner 54430fdc8d8SChris Lattner Error error(process->Resume()); 54530fdc8d8SChris Lattner if (error.Success()) 54630fdc8d8SChris Lattner { 54730fdc8d8SChris Lattner result.AppendMessageWithFormat ("Resuming process %i\n", process->GetID()); 54830fdc8d8SChris Lattner if (synchronous_execution) 54930fdc8d8SChris Lattner { 55030fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 55130fdc8d8SChris Lattner 55230fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 55330fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 55430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 55530fdc8d8SChris Lattner } 55630fdc8d8SChris Lattner else 55730fdc8d8SChris Lattner { 55830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 55930fdc8d8SChris Lattner } 56030fdc8d8SChris Lattner } 56130fdc8d8SChris Lattner else 56230fdc8d8SChris Lattner { 56330fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 56430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 56530fdc8d8SChris Lattner } 56630fdc8d8SChris Lattner } 56730fdc8d8SChris Lattner else 56830fdc8d8SChris Lattner { 56930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 57030fdc8d8SChris Lattner StateAsCString(state)); 57130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 57230fdc8d8SChris Lattner } 57330fdc8d8SChris Lattner return result.Succeeded(); 57430fdc8d8SChris Lattner } 57530fdc8d8SChris Lattner }; 57630fdc8d8SChris Lattner 57730fdc8d8SChris Lattner //------------------------------------------------------------------------- 57830fdc8d8SChris Lattner // CommandObjectProcessDetach 57930fdc8d8SChris Lattner //------------------------------------------------------------------------- 58030fdc8d8SChris Lattner 58130fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 58230fdc8d8SChris Lattner { 58330fdc8d8SChris Lattner public: 58430fdc8d8SChris Lattner 58530fdc8d8SChris Lattner CommandObjectProcessDetach () : 58630fdc8d8SChris Lattner CommandObject ("process detach", 58730fdc8d8SChris Lattner "Detaches from the current process being debugged.", 58830fdc8d8SChris Lattner "process detach", 58930fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 59030fdc8d8SChris Lattner { 59130fdc8d8SChris Lattner } 59230fdc8d8SChris Lattner 59330fdc8d8SChris Lattner ~CommandObjectProcessDetach () 59430fdc8d8SChris Lattner { 59530fdc8d8SChris Lattner } 59630fdc8d8SChris Lattner 59730fdc8d8SChris Lattner bool 59830fdc8d8SChris Lattner Execute (Args& command, 59930fdc8d8SChris Lattner CommandContext *context, 60030fdc8d8SChris Lattner CommandInterpreter *interpreter, 60130fdc8d8SChris Lattner CommandReturnObject &result) 60230fdc8d8SChris Lattner { 60330fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 60430fdc8d8SChris Lattner if (process == NULL) 60530fdc8d8SChris Lattner { 60630fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 60730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 60830fdc8d8SChris Lattner return false; 60930fdc8d8SChris Lattner } 61030fdc8d8SChris Lattner 61130fdc8d8SChris Lattner Error error (process->Detach()); 61230fdc8d8SChris Lattner if (error.Success()) 61330fdc8d8SChris Lattner { 61430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 61530fdc8d8SChris Lattner } 61630fdc8d8SChris Lattner else 61730fdc8d8SChris Lattner { 61830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 61930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 62030fdc8d8SChris Lattner return false; 62130fdc8d8SChris Lattner } 62230fdc8d8SChris Lattner return result.Succeeded(); 62330fdc8d8SChris Lattner } 62430fdc8d8SChris Lattner }; 62530fdc8d8SChris Lattner 62630fdc8d8SChris Lattner //------------------------------------------------------------------------- 62730fdc8d8SChris Lattner // CommandObjectProcessSignal 62830fdc8d8SChris Lattner //------------------------------------------------------------------------- 62930fdc8d8SChris Lattner 63030fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 63130fdc8d8SChris Lattner { 63230fdc8d8SChris Lattner public: 63330fdc8d8SChris Lattner 63430fdc8d8SChris Lattner CommandObjectProcessSignal () : 63530fdc8d8SChris Lattner CommandObject ("process signal", 63630fdc8d8SChris Lattner "Sends a UNIX signal to the current process being debugged.", 63730fdc8d8SChris Lattner "process signal <unix-signal-number>") 63830fdc8d8SChris Lattner { 63930fdc8d8SChris Lattner } 64030fdc8d8SChris Lattner 64130fdc8d8SChris Lattner ~CommandObjectProcessSignal () 64230fdc8d8SChris Lattner { 64330fdc8d8SChris Lattner } 64430fdc8d8SChris Lattner 64530fdc8d8SChris Lattner bool 64630fdc8d8SChris Lattner Execute (Args& command, 64730fdc8d8SChris Lattner CommandContext *context, 64830fdc8d8SChris Lattner CommandInterpreter *interpreter, 64930fdc8d8SChris Lattner CommandReturnObject &result) 65030fdc8d8SChris Lattner { 65130fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 65230fdc8d8SChris Lattner if (process == NULL) 65330fdc8d8SChris Lattner { 65430fdc8d8SChris Lattner result.AppendError ("no process to signal"); 65530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 65630fdc8d8SChris Lattner return false; 65730fdc8d8SChris Lattner } 65830fdc8d8SChris Lattner 65930fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 66030fdc8d8SChris Lattner { 66130fdc8d8SChris Lattner int signo = Args::StringToSInt32(command.GetArgumentAtIndex(0), -1, 0); 66230fdc8d8SChris Lattner if (signo == -1) 66330fdc8d8SChris Lattner { 66430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 66530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 66630fdc8d8SChris Lattner } 66730fdc8d8SChris Lattner else 66830fdc8d8SChris Lattner { 66930fdc8d8SChris Lattner Error error (process->Signal (signo)); 67030fdc8d8SChris Lattner if (error.Success()) 67130fdc8d8SChris Lattner { 67230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 67330fdc8d8SChris Lattner } 67430fdc8d8SChris Lattner else 67530fdc8d8SChris Lattner { 67630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 67730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 67830fdc8d8SChris Lattner } 67930fdc8d8SChris Lattner } 68030fdc8d8SChris Lattner } 68130fdc8d8SChris Lattner else 68230fdc8d8SChris Lattner { 68330fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 68430fdc8d8SChris Lattner m_cmd_syntax.c_str()); 68530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 68630fdc8d8SChris Lattner } 68730fdc8d8SChris Lattner return result.Succeeded(); 68830fdc8d8SChris Lattner } 68930fdc8d8SChris Lattner }; 69030fdc8d8SChris Lattner 69130fdc8d8SChris Lattner 69230fdc8d8SChris Lattner //------------------------------------------------------------------------- 69330fdc8d8SChris Lattner // CommandObjectProcessInterrupt 69430fdc8d8SChris Lattner //------------------------------------------------------------------------- 69530fdc8d8SChris Lattner 69630fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 69730fdc8d8SChris Lattner { 69830fdc8d8SChris Lattner public: 69930fdc8d8SChris Lattner 70030fdc8d8SChris Lattner 70130fdc8d8SChris Lattner CommandObjectProcessInterrupt () : 70230fdc8d8SChris Lattner CommandObject ("process interrupt", 70330fdc8d8SChris Lattner "Interrupts the current process being debugged.", 70430fdc8d8SChris Lattner "process interrupt", 70530fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 70630fdc8d8SChris Lattner { 70730fdc8d8SChris Lattner } 70830fdc8d8SChris Lattner 70930fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 71030fdc8d8SChris Lattner { 71130fdc8d8SChris Lattner } 71230fdc8d8SChris Lattner 71330fdc8d8SChris Lattner bool 71430fdc8d8SChris Lattner Execute (Args& command, 71530fdc8d8SChris Lattner CommandContext *context, 71630fdc8d8SChris Lattner CommandInterpreter *interpreter, 71730fdc8d8SChris Lattner CommandReturnObject &result) 71830fdc8d8SChris Lattner { 71930fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 72030fdc8d8SChris Lattner if (process == NULL) 72130fdc8d8SChris Lattner { 72230fdc8d8SChris Lattner result.AppendError ("no process to halt"); 72330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 72430fdc8d8SChris Lattner return false; 72530fdc8d8SChris Lattner } 72630fdc8d8SChris Lattner 72730fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 72830fdc8d8SChris Lattner { 72930fdc8d8SChris Lattner Error error(process->Halt ()); 73030fdc8d8SChris Lattner if (error.Success()) 73130fdc8d8SChris Lattner { 73230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 73330fdc8d8SChris Lattner 73430fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 73530fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 73630fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 73730fdc8d8SChris Lattner } 73830fdc8d8SChris Lattner else 73930fdc8d8SChris Lattner { 74030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 74130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 74230fdc8d8SChris Lattner } 74330fdc8d8SChris Lattner } 74430fdc8d8SChris Lattner else 74530fdc8d8SChris Lattner { 74630fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 74730fdc8d8SChris Lattner m_cmd_name.c_str(), 74830fdc8d8SChris Lattner m_cmd_syntax.c_str()); 74930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 75030fdc8d8SChris Lattner } 75130fdc8d8SChris Lattner return result.Succeeded(); 75230fdc8d8SChris Lattner } 75330fdc8d8SChris Lattner }; 75430fdc8d8SChris Lattner 75530fdc8d8SChris Lattner //------------------------------------------------------------------------- 75630fdc8d8SChris Lattner // CommandObjectProcessKill 75730fdc8d8SChris Lattner //------------------------------------------------------------------------- 75830fdc8d8SChris Lattner 75930fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 76030fdc8d8SChris Lattner { 76130fdc8d8SChris Lattner public: 76230fdc8d8SChris Lattner 76330fdc8d8SChris Lattner CommandObjectProcessKill () : 76430fdc8d8SChris Lattner CommandObject ("process kill", 76530fdc8d8SChris Lattner "Terminates the current process being debugged.", 76630fdc8d8SChris Lattner "process kill", 76730fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 76830fdc8d8SChris Lattner { 76930fdc8d8SChris Lattner } 77030fdc8d8SChris Lattner 77130fdc8d8SChris Lattner ~CommandObjectProcessKill () 77230fdc8d8SChris Lattner { 77330fdc8d8SChris Lattner } 77430fdc8d8SChris Lattner 77530fdc8d8SChris Lattner bool 77630fdc8d8SChris Lattner Execute (Args& command, 77730fdc8d8SChris Lattner CommandContext *context, 77830fdc8d8SChris Lattner CommandInterpreter *interpreter, 77930fdc8d8SChris Lattner CommandReturnObject &result) 78030fdc8d8SChris Lattner { 78130fdc8d8SChris Lattner Process *process = context->GetExecutionContext().process; 78230fdc8d8SChris Lattner if (process == NULL) 78330fdc8d8SChris Lattner { 78430fdc8d8SChris Lattner result.AppendError ("no process to kill"); 78530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78630fdc8d8SChris Lattner return false; 78730fdc8d8SChris Lattner } 78830fdc8d8SChris Lattner 78930fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 79030fdc8d8SChris Lattner { 79130fdc8d8SChris Lattner Error error (process->Destroy()); 79230fdc8d8SChris Lattner if (error.Success()) 79330fdc8d8SChris Lattner { 79430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 79530fdc8d8SChris Lattner } 79630fdc8d8SChris Lattner else 79730fdc8d8SChris Lattner { 79830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 79930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 80030fdc8d8SChris Lattner } 80130fdc8d8SChris Lattner } 80230fdc8d8SChris Lattner else 80330fdc8d8SChris Lattner { 80430fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 80530fdc8d8SChris Lattner m_cmd_name.c_str(), 80630fdc8d8SChris Lattner m_cmd_syntax.c_str()); 80730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 80830fdc8d8SChris Lattner } 80930fdc8d8SChris Lattner return result.Succeeded(); 81030fdc8d8SChris Lattner } 81130fdc8d8SChris Lattner }; 81230fdc8d8SChris Lattner 81330fdc8d8SChris Lattner //------------------------------------------------------------------------- 814*4b9bea87SJim Ingham // CommandObjectProcessStatus 815*4b9bea87SJim Ingham //------------------------------------------------------------------------- 816*4b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 817*4b9bea87SJim Ingham { 818*4b9bea87SJim Ingham public: 819*4b9bea87SJim Ingham CommandObjectProcessStatus () : 820*4b9bea87SJim Ingham CommandObject ("status", 821*4b9bea87SJim Ingham "Shows the current status and location of executing process.", 822*4b9bea87SJim Ingham "status", 823*4b9bea87SJim Ingham 0) 824*4b9bea87SJim Ingham { 825*4b9bea87SJim Ingham } 826*4b9bea87SJim Ingham 827*4b9bea87SJim Ingham ~CommandObjectProcessStatus() 828*4b9bea87SJim Ingham { 829*4b9bea87SJim Ingham } 830*4b9bea87SJim Ingham 831*4b9bea87SJim Ingham 832*4b9bea87SJim Ingham bool 833*4b9bea87SJim Ingham Execute 834*4b9bea87SJim Ingham ( 835*4b9bea87SJim Ingham Args& command, 836*4b9bea87SJim Ingham CommandContext *context, 837*4b9bea87SJim Ingham CommandInterpreter *interpreter, 838*4b9bea87SJim Ingham CommandReturnObject &result 839*4b9bea87SJim Ingham ) 840*4b9bea87SJim Ingham { 841*4b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 842*4b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 843*4b9bea87SJim Ingham ExecutionContext exe_ctx(context->GetExecutionContext()); 844*4b9bea87SJim Ingham if (exe_ctx.process) 845*4b9bea87SJim Ingham { 846*4b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 847*4b9bea87SJim Ingham if (StateIsStoppedState(state)) 848*4b9bea87SJim Ingham { 849*4b9bea87SJim Ingham if (state == eStateExited) 850*4b9bea87SJim Ingham { 851*4b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 852*4b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 853*4b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 854*4b9bea87SJim Ingham exe_ctx.process->GetID(), 855*4b9bea87SJim Ingham exit_status, 856*4b9bea87SJim Ingham exit_status, 857*4b9bea87SJim Ingham exit_description ? exit_description : ""); 858*4b9bea87SJim Ingham } 859*4b9bea87SJim Ingham else 860*4b9bea87SJim Ingham { 861*4b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 862*4b9bea87SJim Ingham if (exe_ctx.thread == NULL) 863*4b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 864*4b9bea87SJim Ingham if (exe_ctx.thread != NULL) 865*4b9bea87SJim Ingham { 866*4b9bea87SJim Ingham DisplayThreadsInfo (interpreter, &exe_ctx, result, true, true); 867*4b9bea87SJim Ingham } 868*4b9bea87SJim Ingham else 869*4b9bea87SJim Ingham { 870*4b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 871*4b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 872*4b9bea87SJim Ingham } 873*4b9bea87SJim Ingham } 874*4b9bea87SJim Ingham } 875*4b9bea87SJim Ingham else 876*4b9bea87SJim Ingham { 877*4b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 878*4b9bea87SJim Ingham exe_ctx.process->GetID()); 879*4b9bea87SJim Ingham } 880*4b9bea87SJim Ingham } 881*4b9bea87SJim Ingham else 882*4b9bea87SJim Ingham { 883*4b9bea87SJim Ingham result.AppendError ("No current location or status available."); 884*4b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 885*4b9bea87SJim Ingham } 886*4b9bea87SJim Ingham return result.Succeeded(); 887*4b9bea87SJim Ingham } 888*4b9bea87SJim Ingham }; 889*4b9bea87SJim Ingham 890*4b9bea87SJim Ingham //------------------------------------------------------------------------- 89130fdc8d8SChris Lattner // CommandObjectMultiwordProcess 89230fdc8d8SChris Lattner //------------------------------------------------------------------------- 89330fdc8d8SChris Lattner 89430fdc8d8SChris Lattner CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter *interpreter) : 89530fdc8d8SChris Lattner CommandObjectMultiword ("process", 89630fdc8d8SChris Lattner "A set of commands for operating on a process.", 89730fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 89830fdc8d8SChris Lattner { 89930fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessAttach ()), "attach", interpreter); 90030fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessLaunch ()), "launch", interpreter); 90130fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessContinue ()), "continue", interpreter); 90230fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessDetach ()), "detach", interpreter); 90330fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessSignal ()), "signal", interpreter); 904*4b9bea87SJim Ingham LoadSubCommand (CommandObjectSP (new CommandObjectProcessStatus ()), "status", interpreter); 90530fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessInterrupt ()), "interrupt", interpreter); 90630fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectProcessKill ()), "kill", interpreter); 90730fdc8d8SChris Lattner } 90830fdc8d8SChris Lattner 90930fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 91030fdc8d8SChris Lattner { 91130fdc8d8SChris Lattner } 91230fdc8d8SChris Lattner 913