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; 65*f8da8631SCaroline Tice case 'n': no_stdio = true; break; 66913c4fa1SGreg Clayton case 't': 67913c4fa1SGreg Clayton if (option_arg && option_arg[0]) 68913c4fa1SGreg Clayton tty_name.assign (option_arg); 69913c4fa1SGreg Clayton in_new_tty = true; 70913c4fa1SGreg Clayton break; 7130fdc8d8SChris Lattner default: 7230fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 7330fdc8d8SChris Lattner break; 7430fdc8d8SChris Lattner 7530fdc8d8SChris Lattner } 7630fdc8d8SChris Lattner return error; 7730fdc8d8SChris Lattner } 7830fdc8d8SChris Lattner 7930fdc8d8SChris Lattner void 8030fdc8d8SChris Lattner ResetOptionValues () 8130fdc8d8SChris Lattner { 8230fdc8d8SChris Lattner Options::ResetOptionValues(); 8330fdc8d8SChris Lattner stop_at_entry = false; 8419388cfcSGreg Clayton in_new_tty = false; 85913c4fa1SGreg Clayton tty_name.clear(); 8630fdc8d8SChris Lattner stdin_path.clear(); 8730fdc8d8SChris Lattner stdout_path.clear(); 8830fdc8d8SChris Lattner stderr_path.clear(); 8930fdc8d8SChris Lattner plugin_name.clear(); 90*f8da8631SCaroline Tice no_stdio = false; 9130fdc8d8SChris Lattner } 9230fdc8d8SChris Lattner 9330fdc8d8SChris Lattner const lldb::OptionDefinition* 9430fdc8d8SChris Lattner GetDefinitions () 9530fdc8d8SChris Lattner { 9630fdc8d8SChris Lattner return g_option_table; 9730fdc8d8SChris Lattner } 9830fdc8d8SChris Lattner 9930fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 10030fdc8d8SChris Lattner 10130fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 10230fdc8d8SChris Lattner 10330fdc8d8SChris Lattner // Instance variables to hold the values for command options. 10430fdc8d8SChris Lattner 10530fdc8d8SChris Lattner bool stop_at_entry; 10619388cfcSGreg Clayton bool in_new_tty; 107*f8da8631SCaroline Tice bool no_stdio; 108913c4fa1SGreg Clayton std::string tty_name; 10930fdc8d8SChris Lattner std::string stderr_path; 11030fdc8d8SChris Lattner std::string stdin_path; 11130fdc8d8SChris Lattner std::string stdout_path; 11230fdc8d8SChris Lattner std::string plugin_name; 11330fdc8d8SChris Lattner 11430fdc8d8SChris Lattner }; 11530fdc8d8SChris Lattner 116a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 117a7015092SGreg Clayton CommandObject (interpreter, 118a7015092SGreg Clayton "process launch", 119e3d26315SCaroline Tice "Launch the executable in the debugger.", 120405fe67fSCaroline Tice NULL) 12130fdc8d8SChris Lattner { 122405fe67fSCaroline Tice CommandArgumentEntry arg; 123405fe67fSCaroline Tice CommandArgumentData run_args_arg; 124405fe67fSCaroline Tice 125405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 126405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 127405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 128405fe67fSCaroline Tice 129405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 130405fe67fSCaroline Tice arg.push_back (run_args_arg); 131405fe67fSCaroline Tice 132405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 133405fe67fSCaroline Tice m_arguments.push_back (arg); 13430fdc8d8SChris Lattner } 13530fdc8d8SChris Lattner 13630fdc8d8SChris Lattner 13730fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 13830fdc8d8SChris Lattner { 13930fdc8d8SChris Lattner } 14030fdc8d8SChris Lattner 14130fdc8d8SChris Lattner Options * 14230fdc8d8SChris Lattner GetOptions () 14330fdc8d8SChris Lattner { 14430fdc8d8SChris Lattner return &m_options; 14530fdc8d8SChris Lattner } 14630fdc8d8SChris Lattner 14730fdc8d8SChris Lattner bool 14805faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 14930fdc8d8SChris Lattner { 150a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 15130fdc8d8SChris Lattner 15230fdc8d8SChris Lattner if (target == NULL) 15330fdc8d8SChris Lattner { 15430fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 15530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 15630fdc8d8SChris Lattner return false; 15730fdc8d8SChris Lattner } 15830fdc8d8SChris Lattner 15930fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 16030fdc8d8SChris Lattner char filename[PATH_MAX]; 16119388cfcSGreg Clayton const Module *exe_module = target->GetExecutableModule().get(); 16230fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 16330fdc8d8SChris Lattner 164a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 165a7015092SGreg Clayton if (process && process->IsAlive()) 16630fdc8d8SChris Lattner { 16730fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", 16830fdc8d8SChris Lattner process->GetID()); 16930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 17030fdc8d8SChris Lattner return false; 17130fdc8d8SChris Lattner } 17230fdc8d8SChris Lattner 17330fdc8d8SChris Lattner const char *plugin_name; 17430fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 17530fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 17630fdc8d8SChris Lattner else 17730fdc8d8SChris Lattner plugin_name = NULL; 17830fdc8d8SChris Lattner 179a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 18030fdc8d8SChris Lattner 181a7015092SGreg Clayton if (process == NULL) 1823df9a8dfSCaroline Tice { 18343a8c39bSCaroline Tice result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 184a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 185a7015092SGreg Clayton return false; 1863df9a8dfSCaroline Tice } 1873df9a8dfSCaroline Tice 188a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 189a7015092SGreg Clayton // might have been set using the "run-args" set variable. 19030fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 19130fdc8d8SChris Lattner { 192a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 193a7015092SGreg Clayton launch_args = process->GetRunArguments(); 19430fdc8d8SChris Lattner } 19530fdc8d8SChris Lattner 19619388cfcSGreg Clayton if (m_options.in_new_tty) 19719388cfcSGreg Clayton { 19819388cfcSGreg Clayton char exec_file_path[PATH_MAX]; 19919388cfcSGreg Clayton if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 20019388cfcSGreg Clayton { 20119388cfcSGreg Clayton launch_args.InsertArgumentAtIndex(0, exec_file_path); 20219388cfcSGreg Clayton } 20319388cfcSGreg Clayton else 20419388cfcSGreg Clayton { 20519388cfcSGreg Clayton result.AppendError("invalid executable"); 20619388cfcSGreg Clayton result.SetStatus (eReturnStatusFailed); 20719388cfcSGreg Clayton return false; 20819388cfcSGreg Clayton } 20919388cfcSGreg Clayton } 21019388cfcSGreg Clayton 211a7015092SGreg Clayton Args environment; 21230fdc8d8SChris Lattner 213a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 214a7015092SGreg Clayton 215a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 216a7015092SGreg Clayton 217a7015092SGreg Clayton if (process->GetDisableASLR()) 218a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 219a7015092SGreg Clayton 220*f8da8631SCaroline Tice if (m_options.no_stdio) 221*f8da8631SCaroline Tice launch_flags |= eLaunchFlagDisableSTDIO; 222*f8da8631SCaroline Tice else if (!m_options.in_new_tty 223*f8da8631SCaroline Tice && m_options.stdin_path.empty() 224*f8da8631SCaroline Tice && m_options.stdout_path.empty() 225*f8da8631SCaroline Tice && m_options.stderr_path.empty()) 226*f8da8631SCaroline Tice { 227*f8da8631SCaroline Tice // Only use the settings value if the user hasn't specified any options that would override it. 228*f8da8631SCaroline Tice if (process->GetDisableSTDIO()) 229*f8da8631SCaroline Tice launch_flags |= eLaunchFlagDisableSTDIO; 230*f8da8631SCaroline Tice } 231*f8da8631SCaroline Tice 23219388cfcSGreg Clayton const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 23319388cfcSGreg Clayton const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 23430fdc8d8SChris Lattner 23519388cfcSGreg Clayton Error error; 23619388cfcSGreg Clayton 23719388cfcSGreg Clayton if (m_options.in_new_tty) 23819388cfcSGreg Clayton { 23919388cfcSGreg Clayton 240913c4fa1SGreg Clayton lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(), 241913c4fa1SGreg Clayton inferior_argv, 24219388cfcSGreg Clayton inferior_envp, 24319388cfcSGreg Clayton &exe_module->GetArchitecture(), 24419388cfcSGreg Clayton true, 24519388cfcSGreg Clayton process->GetDisableASLR()); 24619388cfcSGreg Clayton 2473fcbed6bSGreg Clayton if (pid != LLDB_INVALID_PROCESS_ID) 2483fcbed6bSGreg Clayton error = process->Attach (pid); 24919388cfcSGreg Clayton } 25019388cfcSGreg Clayton else 25119388cfcSGreg Clayton { 25230fdc8d8SChris Lattner const char * stdin_path = NULL; 25330fdc8d8SChris Lattner const char * stdout_path = NULL; 25430fdc8d8SChris Lattner const char * stderr_path = NULL; 25530fdc8d8SChris Lattner 256a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 257a7015092SGreg Clayton if (m_options.stdin_path.empty() && 25830fdc8d8SChris Lattner m_options.stdout_path.empty() && 259a7015092SGreg Clayton m_options.stderr_path.empty()) 26030fdc8d8SChris Lattner { 261a7015092SGreg Clayton // No standard file handles were given on the command line, check 262a7015092SGreg Clayton // with the process object in case they were give using "set settings" 263a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 264a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 265a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 266a7015092SGreg Clayton } 267a7015092SGreg Clayton else 268a7015092SGreg Clayton { 269a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 270a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 271a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 27230fdc8d8SChris Lattner } 27330fdc8d8SChris Lattner 274a7015092SGreg Clayton if (stdin_path == NULL) 275a7015092SGreg Clayton stdin_path = "/dev/null"; 276a7015092SGreg Clayton if (stdout_path == NULL) 277a7015092SGreg Clayton stdout_path = "/dev/null"; 278a7015092SGreg Clayton if (stderr_path == NULL) 279a7015092SGreg Clayton stderr_path = "/dev/null"; 280a7015092SGreg Clayton 28119388cfcSGreg Clayton error = process->Launch (inferior_argv, 28219388cfcSGreg Clayton inferior_envp, 283f681b94fSGreg Clayton launch_flags, 28430fdc8d8SChris Lattner stdin_path, 28530fdc8d8SChris Lattner stdout_path, 28619388cfcSGreg Clayton stderr_path); 28719388cfcSGreg Clayton } 28830fdc8d8SChris Lattner 28930fdc8d8SChris Lattner if (error.Success()) 29030fdc8d8SChris Lattner { 29119388cfcSGreg Clayton const char *archname = exe_module->GetArchitecture().AsCString(); 29219388cfcSGreg Clayton 29319388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 29405faeb71SGreg Clayton result.SetDidChangeProcessState (true); 29530fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 29630fdc8d8SChris Lattner { 29705faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 29830fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 29930fdc8d8SChris Lattner 30030fdc8d8SChris Lattner if (state == eStateStopped) 30130fdc8d8SChris Lattner { 30205faeb71SGreg Clayton error = process->Resume(); 30305faeb71SGreg Clayton if (error.Success()) 30405faeb71SGreg Clayton { 30505faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 30630fdc8d8SChris Lattner if (synchronous_execution) 30730fdc8d8SChris Lattner { 30805faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 30930fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 31005faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 31105faeb71SGreg Clayton } 31205faeb71SGreg Clayton else 31305faeb71SGreg Clayton { 31405faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 31505faeb71SGreg Clayton } 31605faeb71SGreg Clayton } 31730fdc8d8SChris Lattner } 31830fdc8d8SChris Lattner } 31930fdc8d8SChris Lattner } 32030fdc8d8SChris Lattner 32130fdc8d8SChris Lattner return result.Succeeded(); 32230fdc8d8SChris Lattner } 32330fdc8d8SChris Lattner 324ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 325ebc09c36SJim Ingham { 326ebc09c36SJim Ingham // No repeat for "process launch"... 327ebc09c36SJim Ingham return ""; 328ebc09c36SJim Ingham } 329ebc09c36SJim Ingham 33030fdc8d8SChris Lattner protected: 33130fdc8d8SChris Lattner 33230fdc8d8SChris Lattner CommandOptions m_options; 33330fdc8d8SChris Lattner }; 33430fdc8d8SChris Lattner 33530fdc8d8SChris Lattner 33619388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1 33719388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2 338*f8da8631SCaroline Tice #define SET3 LLDB_OPT_SET_3 33919388cfcSGreg Clayton 34030fdc8d8SChris Lattner lldb::OptionDefinition 34130fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 34230fdc8d8SChris Lattner { 343*f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 34419388cfcSGreg Clayton { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 34519388cfcSGreg Clayton { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 34619388cfcSGreg Clayton { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 347*f8da8631SCaroline Tice { SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 348913c4fa1SGreg Clayton { SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypePath, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."}, 349*f8da8631SCaroline Tice { SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, 350deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 35130fdc8d8SChris Lattner }; 35230fdc8d8SChris Lattner 35319388cfcSGreg Clayton #undef SET1 35419388cfcSGreg Clayton #undef SET2 355*f8da8631SCaroline Tice #undef SET3 35630fdc8d8SChris Lattner 35730fdc8d8SChris Lattner //------------------------------------------------------------------------- 35830fdc8d8SChris Lattner // CommandObjectProcessAttach 35930fdc8d8SChris Lattner //------------------------------------------------------------------------- 36030fdc8d8SChris Lattner 36130fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 36230fdc8d8SChris Lattner { 36330fdc8d8SChris Lattner public: 36430fdc8d8SChris Lattner 36530fdc8d8SChris Lattner class CommandOptions : public Options 36630fdc8d8SChris Lattner { 36730fdc8d8SChris Lattner public: 36830fdc8d8SChris Lattner 36930fdc8d8SChris Lattner CommandOptions () : 37030fdc8d8SChris Lattner Options() 37130fdc8d8SChris Lattner { 37230fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 37330fdc8d8SChris Lattner ResetOptionValues (); 37430fdc8d8SChris Lattner } 37530fdc8d8SChris Lattner 37630fdc8d8SChris Lattner ~CommandOptions () 37730fdc8d8SChris Lattner { 37830fdc8d8SChris Lattner } 37930fdc8d8SChris Lattner 38030fdc8d8SChris Lattner Error 38130fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 38230fdc8d8SChris Lattner { 38330fdc8d8SChris Lattner Error error; 38430fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 38530fdc8d8SChris Lattner bool success = false; 38630fdc8d8SChris Lattner switch (short_option) 38730fdc8d8SChris Lattner { 38830fdc8d8SChris Lattner case 'p': 38930fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 39030fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 39130fdc8d8SChris Lattner { 39230fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner break; 39530fdc8d8SChris Lattner 39630fdc8d8SChris Lattner case 'P': 39730fdc8d8SChris Lattner plugin_name = option_arg; 39830fdc8d8SChris Lattner break; 39930fdc8d8SChris Lattner 40030fdc8d8SChris Lattner case 'n': 40130fdc8d8SChris Lattner name.assign(option_arg); 40230fdc8d8SChris Lattner break; 40330fdc8d8SChris Lattner 40430fdc8d8SChris Lattner case 'w': 40530fdc8d8SChris Lattner waitfor = true; 40630fdc8d8SChris Lattner break; 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner default: 40930fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 41030fdc8d8SChris Lattner break; 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner return error; 41330fdc8d8SChris Lattner } 41430fdc8d8SChris Lattner 41530fdc8d8SChris Lattner void 41630fdc8d8SChris Lattner ResetOptionValues () 41730fdc8d8SChris Lattner { 41830fdc8d8SChris Lattner Options::ResetOptionValues(); 41930fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 42030fdc8d8SChris Lattner name.clear(); 42130fdc8d8SChris Lattner waitfor = false; 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner 42430fdc8d8SChris Lattner const lldb::OptionDefinition* 42530fdc8d8SChris Lattner GetDefinitions () 42630fdc8d8SChris Lattner { 42730fdc8d8SChris Lattner return g_option_table; 42830fdc8d8SChris Lattner } 42930fdc8d8SChris Lattner 4305aee162fSJim Ingham virtual bool 431a7015092SGreg Clayton HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 4325aee162fSJim Ingham Args &input, 4335aee162fSJim Ingham int cursor_index, 4345aee162fSJim Ingham int char_pos, 4355aee162fSJim Ingham OptionElementVector &opt_element_vector, 4365aee162fSJim Ingham int opt_element_index, 4375aee162fSJim Ingham int match_start_point, 4385aee162fSJim Ingham int max_return_elements, 4395aee162fSJim Ingham bool &word_complete, 4405aee162fSJim Ingham StringList &matches) 4415aee162fSJim Ingham { 4425aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4435aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4445aee162fSJim Ingham 4455aee162fSJim Ingham // We are only completing the name option for now... 4465aee162fSJim Ingham 4475aee162fSJim Ingham const lldb::OptionDefinition *opt_defs = GetDefinitions(); 4485aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4495aee162fSJim Ingham { 4505aee162fSJim Ingham // Are we in the name? 4515aee162fSJim Ingham 4525aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4535aee162fSJim Ingham // use the default plugin. 454a7015092SGreg Clayton Process *process = interpeter.GetDebugger().GetExecutionContext().process; 4555aee162fSJim Ingham bool need_to_delete_process = false; 4565aee162fSJim Ingham 4575aee162fSJim Ingham const char *partial_name = NULL; 4585aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4595aee162fSJim Ingham 4605aee162fSJim Ingham if (process && process->IsAlive()) 4615aee162fSJim Ingham return true; 4625aee162fSJim Ingham 463a7015092SGreg Clayton Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 4645aee162fSJim Ingham if (target == NULL) 4655aee162fSJim Ingham { 4665aee162fSJim Ingham // No target has been set yet, for now do host completion. Otherwise I don't know how we would 4675aee162fSJim Ingham // figure out what the right target to use is... 4685aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4695aee162fSJim Ingham Host::ListProcessesMatchingName (partial_name, matches, pids); 4705aee162fSJim Ingham return true; 4715aee162fSJim Ingham } 4725aee162fSJim Ingham if (!process) 4735aee162fSJim Ingham { 474a7015092SGreg Clayton process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 4755aee162fSJim Ingham need_to_delete_process = true; 4765aee162fSJim Ingham } 4775aee162fSJim Ingham 4785aee162fSJim Ingham if (process) 4795aee162fSJim Ingham { 4805aee162fSJim Ingham matches.Clear(); 4815aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4825aee162fSJim Ingham process->ListProcessesMatchingName (NULL, matches, pids); 4835aee162fSJim Ingham if (need_to_delete_process) 4845aee162fSJim Ingham target->DeleteCurrentProcess(); 4855aee162fSJim Ingham return true; 4865aee162fSJim Ingham } 4875aee162fSJim Ingham } 4885aee162fSJim Ingham 4895aee162fSJim Ingham return false; 4905aee162fSJim Ingham } 4915aee162fSJim Ingham 49230fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 49330fdc8d8SChris Lattner 49430fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 49530fdc8d8SChris Lattner 49630fdc8d8SChris Lattner // Instance variables to hold the values for command options. 49730fdc8d8SChris Lattner 49830fdc8d8SChris Lattner lldb::pid_t pid; 49930fdc8d8SChris Lattner std::string plugin_name; 50030fdc8d8SChris Lattner std::string name; 50130fdc8d8SChris Lattner bool waitfor; 50230fdc8d8SChris Lattner }; 50330fdc8d8SChris Lattner 504a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 505a7015092SGreg Clayton CommandObject (interpreter, 506a7015092SGreg Clayton "process attach", 507e3d26315SCaroline Tice "Attach to a process.", 5085aee162fSJim Ingham "process attach <cmd-options>") 5095aee162fSJim Ingham { 5105aee162fSJim Ingham } 5115aee162fSJim Ingham 5125aee162fSJim Ingham ~CommandObjectProcessAttach () 5135aee162fSJim Ingham { 5145aee162fSJim Ingham } 5155aee162fSJim Ingham 5165aee162fSJim Ingham bool 517a7015092SGreg Clayton Execute (Args& command, 5185aee162fSJim Ingham CommandReturnObject &result) 5195aee162fSJim Ingham { 520a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5215aee162fSJim Ingham 522a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 5235aee162fSJim Ingham if (process) 5245aee162fSJim Ingham { 5255aee162fSJim Ingham if (process->IsAlive()) 5265aee162fSJim Ingham { 5275aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 5285aee162fSJim Ingham process->GetID()); 5295aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5305aee162fSJim Ingham return false; 5315aee162fSJim Ingham } 5325aee162fSJim Ingham } 5335aee162fSJim Ingham 5345aee162fSJim Ingham if (target == NULL) 5355aee162fSJim Ingham { 5365aee162fSJim Ingham // If there isn't a current target create one. 5375aee162fSJim Ingham TargetSP new_target_sp; 5385aee162fSJim Ingham FileSpec emptyFileSpec; 5395aee162fSJim Ingham ArchSpec emptyArchSpec; 5405aee162fSJim Ingham Error error; 5415aee162fSJim Ingham 542a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 5435aee162fSJim Ingham emptyFileSpec, 5445aee162fSJim Ingham emptyArchSpec, 5455aee162fSJim Ingham NULL, 5465aee162fSJim Ingham false, 5475aee162fSJim Ingham new_target_sp); 5485aee162fSJim Ingham target = new_target_sp.get(); 5495aee162fSJim Ingham if (target == NULL || error.Fail()) 5505aee162fSJim Ingham { 5515aee162fSJim Ingham result.AppendError(error.AsCString("Error creating empty target")); 5525aee162fSJim Ingham return false; 5535aee162fSJim Ingham } 554a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5555aee162fSJim Ingham } 5565aee162fSJim Ingham 5575aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5585aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5595aee162fSJim Ingham 5605aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5615aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5625aee162fSJim Ingham 5635aee162fSJim Ingham if (command.GetArgumentCount()) 5645aee162fSJim Ingham { 5655aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5665aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5675aee162fSJim Ingham } 5685aee162fSJim Ingham else 5695aee162fSJim Ingham { 5705aee162fSJim Ingham const char *plugin_name = NULL; 5715aee162fSJim Ingham 5725aee162fSJim Ingham if (!m_options.plugin_name.empty()) 5735aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 5745aee162fSJim Ingham 575a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 5765aee162fSJim Ingham 5775aee162fSJim Ingham if (process) 5785aee162fSJim Ingham { 5795aee162fSJim Ingham Error error; 5805aee162fSJim Ingham int attach_pid = m_options.pid; 5815aee162fSJim Ingham 5823a0b9cdfSJim Ingham const char *wait_name = NULL; 5833a0b9cdfSJim Ingham 5845aee162fSJim Ingham if (m_options.name.empty()) 5855aee162fSJim Ingham { 5863a0b9cdfSJim Ingham if (old_exec_module_sp) 5873a0b9cdfSJim Ingham { 5883a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 5893a0b9cdfSJim Ingham } 5905aee162fSJim Ingham } 5915aee162fSJim Ingham else 5925aee162fSJim Ingham { 5933a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 5943a0b9cdfSJim Ingham } 5953a0b9cdfSJim Ingham 5963a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 5973a0b9cdfSJim Ingham if (m_options.waitfor) 5983a0b9cdfSJim Ingham { 5993a0b9cdfSJim Ingham 6003a0b9cdfSJim Ingham if (wait_name == NULL) 6013a0b9cdfSJim Ingham { 6023a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 6033a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 6043a0b9cdfSJim Ingham return false; 6053a0b9cdfSJim Ingham } 6063a0b9cdfSJim Ingham 607a7015092SGreg Clayton m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 6083a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 6095aee162fSJim Ingham if (error.Success()) 6105aee162fSJim Ingham { 6115aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6125aee162fSJim Ingham } 6135aee162fSJim Ingham else 6145aee162fSJim Ingham { 6155aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 6163a0b9cdfSJim Ingham wait_name, 6175aee162fSJim Ingham error.AsCString()); 6185aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6195aee162fSJim Ingham return false; 6205aee162fSJim Ingham } 6215aee162fSJim Ingham } 6225aee162fSJim Ingham else 6235aee162fSJim Ingham { 6245aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 6255aee162fSJim Ingham // processes with this pid. 6265aee162fSJim Ingham 6273a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 6285aee162fSJim Ingham { 6295aee162fSJim Ingham std::vector<lldb::pid_t> pids; 6305aee162fSJim Ingham StringList matches; 6315aee162fSJim Ingham 6323a0b9cdfSJim Ingham process->ListProcessesMatchingName(wait_name, matches, pids); 6335aee162fSJim Ingham if (matches.GetSize() > 1) 6345aee162fSJim Ingham { 6353a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 6365aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6375aee162fSJim Ingham return false; 6385aee162fSJim Ingham } 6395aee162fSJim Ingham else if (matches.GetSize() == 0) 6405aee162fSJim Ingham { 6413a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 6425aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6435aee162fSJim Ingham return false; 6445aee162fSJim Ingham } 6455aee162fSJim Ingham else 6465aee162fSJim Ingham { 6475aee162fSJim Ingham attach_pid = pids[0]; 6485aee162fSJim Ingham } 6495aee162fSJim Ingham 6505aee162fSJim Ingham } 6515aee162fSJim Ingham 6525aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 6535aee162fSJim Ingham { 6545aee162fSJim Ingham error = process->Attach (attach_pid); 6555aee162fSJim Ingham if (error.Success()) 6565aee162fSJim Ingham { 6575aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6585aee162fSJim Ingham } 6595aee162fSJim Ingham else 6605aee162fSJim Ingham { 6615aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 6625aee162fSJim Ingham attach_pid, 6635aee162fSJim Ingham error.AsCString()); 6645aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6655aee162fSJim Ingham } 6665aee162fSJim Ingham } 6675aee162fSJim Ingham else 6685aee162fSJim Ingham { 6695aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 6705aee162fSJim Ingham attach_pid, 6715aee162fSJim Ingham error.AsCString()); 6725aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6735aee162fSJim Ingham 6745aee162fSJim Ingham } 6755aee162fSJim Ingham } 6765aee162fSJim Ingham } 6775aee162fSJim Ingham } 6785aee162fSJim Ingham 6795aee162fSJim Ingham if (result.Succeeded()) 6805aee162fSJim Ingham { 6815aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 6825aee162fSJim Ingham if (!old_exec_module_sp) 6835aee162fSJim Ingham { 6845aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6855aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 6865aee162fSJim Ingham 6875aee162fSJim Ingham result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 6885aee162fSJim Ingham new_path); 6895aee162fSJim Ingham } 6905aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 6915aee162fSJim Ingham { 6925aee162fSJim Ingham char old_path[PATH_MAX + 1]; 6935aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6945aee162fSJim Ingham 6955aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 6965aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 6975aee162fSJim Ingham 6985aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6995aee162fSJim Ingham old_path, new_path); 7005aee162fSJim Ingham } 7015aee162fSJim Ingham 7025aee162fSJim Ingham if (!old_arch_spec.IsValid()) 7035aee162fSJim Ingham { 7045aee162fSJim Ingham result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 7055aee162fSJim Ingham } 7065aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 7075aee162fSJim Ingham { 7085aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 7095aee162fSJim Ingham old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 7105aee162fSJim Ingham } 7115aee162fSJim Ingham } 7125aee162fSJim Ingham return result.Succeeded(); 7135aee162fSJim Ingham } 7145aee162fSJim Ingham 7155aee162fSJim Ingham Options * 7165aee162fSJim Ingham GetOptions () 7175aee162fSJim Ingham { 7185aee162fSJim Ingham return &m_options; 7195aee162fSJim Ingham } 7205aee162fSJim Ingham 72130fdc8d8SChris Lattner protected: 72230fdc8d8SChris Lattner 72330fdc8d8SChris Lattner CommandOptions m_options; 72430fdc8d8SChris Lattner }; 72530fdc8d8SChris Lattner 72630fdc8d8SChris Lattner 72730fdc8d8SChris Lattner lldb::OptionDefinition 72830fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 72930fdc8d8SChris Lattner { 730deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 731deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 732deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 733deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 734deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 73530fdc8d8SChris Lattner }; 73630fdc8d8SChris Lattner 73730fdc8d8SChris Lattner //------------------------------------------------------------------------- 73830fdc8d8SChris Lattner // CommandObjectProcessContinue 73930fdc8d8SChris Lattner //------------------------------------------------------------------------- 74030fdc8d8SChris Lattner 74130fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 74230fdc8d8SChris Lattner { 74330fdc8d8SChris Lattner public: 74430fdc8d8SChris Lattner 745a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 746a7015092SGreg Clayton CommandObject (interpreter, 747a7015092SGreg Clayton "process continue", 748e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 74930fdc8d8SChris Lattner "process continue", 75030fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 75130fdc8d8SChris Lattner { 75230fdc8d8SChris Lattner } 75330fdc8d8SChris Lattner 75430fdc8d8SChris Lattner 75530fdc8d8SChris Lattner ~CommandObjectProcessContinue () 75630fdc8d8SChris Lattner { 75730fdc8d8SChris Lattner } 75830fdc8d8SChris Lattner 75930fdc8d8SChris Lattner bool 760a7015092SGreg Clayton Execute (Args& command, 76130fdc8d8SChris Lattner CommandReturnObject &result) 76230fdc8d8SChris Lattner { 763a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 764a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 76530fdc8d8SChris Lattner 76630fdc8d8SChris Lattner if (process == NULL) 76730fdc8d8SChris Lattner { 76830fdc8d8SChris Lattner result.AppendError ("no process to continue"); 76930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 77030fdc8d8SChris Lattner return false; 77130fdc8d8SChris Lattner } 77230fdc8d8SChris Lattner 77330fdc8d8SChris Lattner StateType state = process->GetState(); 77430fdc8d8SChris Lattner if (state == eStateStopped) 77530fdc8d8SChris Lattner { 77630fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 77730fdc8d8SChris Lattner { 77830fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 77930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 78030fdc8d8SChris Lattner return false; 78130fdc8d8SChris Lattner } 78230fdc8d8SChris Lattner 78330fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 78430fdc8d8SChris Lattner 78530fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 78630fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 78730fdc8d8SChris Lattner { 78830fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 78930fdc8d8SChris Lattner } 79030fdc8d8SChris Lattner 79130fdc8d8SChris Lattner Error error(process->Resume()); 79230fdc8d8SChris Lattner if (error.Success()) 79330fdc8d8SChris Lattner { 79419388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 79530fdc8d8SChris Lattner if (synchronous_execution) 79630fdc8d8SChris Lattner { 797b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 79830fdc8d8SChris Lattner 79930fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 80030fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 80130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 80230fdc8d8SChris Lattner } 80330fdc8d8SChris Lattner else 80430fdc8d8SChris Lattner { 80530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 80630fdc8d8SChris Lattner } 80730fdc8d8SChris Lattner } 80830fdc8d8SChris Lattner else 80930fdc8d8SChris Lattner { 81030fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 81130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 81230fdc8d8SChris Lattner } 81330fdc8d8SChris Lattner } 81430fdc8d8SChris Lattner else 81530fdc8d8SChris Lattner { 81630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 81730fdc8d8SChris Lattner StateAsCString(state)); 81830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 81930fdc8d8SChris Lattner } 82030fdc8d8SChris Lattner return result.Succeeded(); 82130fdc8d8SChris Lattner } 82230fdc8d8SChris Lattner }; 82330fdc8d8SChris Lattner 82430fdc8d8SChris Lattner //------------------------------------------------------------------------- 82530fdc8d8SChris Lattner // CommandObjectProcessDetach 82630fdc8d8SChris Lattner //------------------------------------------------------------------------- 82730fdc8d8SChris Lattner 82830fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 82930fdc8d8SChris Lattner { 83030fdc8d8SChris Lattner public: 83130fdc8d8SChris Lattner 832a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 833a7015092SGreg Clayton CommandObject (interpreter, 834a7015092SGreg Clayton "process detach", 835e3d26315SCaroline Tice "Detach from the current process being debugged.", 83630fdc8d8SChris Lattner "process detach", 83730fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 83830fdc8d8SChris Lattner { 83930fdc8d8SChris Lattner } 84030fdc8d8SChris Lattner 84130fdc8d8SChris Lattner ~CommandObjectProcessDetach () 84230fdc8d8SChris Lattner { 84330fdc8d8SChris Lattner } 84430fdc8d8SChris Lattner 84530fdc8d8SChris Lattner bool 846a7015092SGreg Clayton Execute (Args& command, 84730fdc8d8SChris Lattner CommandReturnObject &result) 84830fdc8d8SChris Lattner { 849a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 85030fdc8d8SChris Lattner if (process == NULL) 85130fdc8d8SChris Lattner { 85230fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 85330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 85430fdc8d8SChris Lattner return false; 85530fdc8d8SChris Lattner } 85630fdc8d8SChris Lattner 8575d7be2e6SCaroline Tice result.AppendMessageWithFormat ("Detaching from process %i\n", process->GetID()); 85830fdc8d8SChris Lattner Error error (process->Detach()); 85930fdc8d8SChris Lattner if (error.Success()) 86030fdc8d8SChris Lattner { 86130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 86230fdc8d8SChris Lattner } 86330fdc8d8SChris Lattner else 86430fdc8d8SChris Lattner { 86530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 86630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 86730fdc8d8SChris Lattner return false; 86830fdc8d8SChris Lattner } 86930fdc8d8SChris Lattner return result.Succeeded(); 87030fdc8d8SChris Lattner } 87130fdc8d8SChris Lattner }; 87230fdc8d8SChris Lattner 87330fdc8d8SChris Lattner //------------------------------------------------------------------------- 8748f343b09SGreg Clayton // CommandObjectProcessLoad 8758f343b09SGreg Clayton //------------------------------------------------------------------------- 8768f343b09SGreg Clayton 8778f343b09SGreg Clayton class CommandObjectProcessLoad : public CommandObject 8788f343b09SGreg Clayton { 8798f343b09SGreg Clayton public: 8808f343b09SGreg Clayton 8818f343b09SGreg Clayton CommandObjectProcessLoad (CommandInterpreter &interpreter) : 8828f343b09SGreg Clayton CommandObject (interpreter, 8838f343b09SGreg Clayton "process load", 8848f343b09SGreg Clayton "Load a shared library into the current process.", 8858f343b09SGreg Clayton "process load <filename> [<filename> ...]", 8868f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 8878f343b09SGreg Clayton { 8888f343b09SGreg Clayton } 8898f343b09SGreg Clayton 8908f343b09SGreg Clayton ~CommandObjectProcessLoad () 8918f343b09SGreg Clayton { 8928f343b09SGreg Clayton } 8938f343b09SGreg Clayton 8948f343b09SGreg Clayton bool 8958f343b09SGreg Clayton Execute (Args& command, 8968f343b09SGreg Clayton CommandReturnObject &result) 8978f343b09SGreg Clayton { 8988f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 8998f343b09SGreg Clayton if (process == NULL) 9008f343b09SGreg Clayton { 9018f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 9028f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9038f343b09SGreg Clayton return false; 9048f343b09SGreg Clayton } 9058f343b09SGreg Clayton 9068f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 9078f343b09SGreg Clayton 9088f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 9098f343b09SGreg Clayton { 9108f343b09SGreg Clayton Error error; 9118f343b09SGreg Clayton const char *image_path = command.GetArgumentAtIndex(i); 9128f343b09SGreg Clayton FileSpec image_spec (image_path, false); 9138f343b09SGreg Clayton uint32_t image_token = process->LoadImage(image_spec, error); 9148f343b09SGreg Clayton if (image_token != LLDB_INVALID_IMAGE_TOKEN) 9158f343b09SGreg Clayton { 9168f343b09SGreg Clayton result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 9178f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 9188f343b09SGreg Clayton } 9198f343b09SGreg Clayton else 9208f343b09SGreg Clayton { 9218f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 9228f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9238f343b09SGreg Clayton } 9248f343b09SGreg Clayton } 9258f343b09SGreg Clayton return result.Succeeded(); 9268f343b09SGreg Clayton } 9278f343b09SGreg Clayton }; 9288f343b09SGreg Clayton 9298f343b09SGreg Clayton 9308f343b09SGreg Clayton //------------------------------------------------------------------------- 9318f343b09SGreg Clayton // CommandObjectProcessUnload 9328f343b09SGreg Clayton //------------------------------------------------------------------------- 9338f343b09SGreg Clayton 9348f343b09SGreg Clayton class CommandObjectProcessUnload : public CommandObject 9358f343b09SGreg Clayton { 9368f343b09SGreg Clayton public: 9378f343b09SGreg Clayton 9388f343b09SGreg Clayton CommandObjectProcessUnload (CommandInterpreter &interpreter) : 9398f343b09SGreg Clayton CommandObject (interpreter, 9408f343b09SGreg Clayton "process unload", 9418f343b09SGreg Clayton "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 9428f343b09SGreg Clayton "process unload <index>", 9438f343b09SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 9448f343b09SGreg Clayton { 9458f343b09SGreg Clayton } 9468f343b09SGreg Clayton 9478f343b09SGreg Clayton ~CommandObjectProcessUnload () 9488f343b09SGreg Clayton { 9498f343b09SGreg Clayton } 9508f343b09SGreg Clayton 9518f343b09SGreg Clayton bool 9528f343b09SGreg Clayton Execute (Args& command, 9538f343b09SGreg Clayton CommandReturnObject &result) 9548f343b09SGreg Clayton { 9558f343b09SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 9568f343b09SGreg Clayton if (process == NULL) 9578f343b09SGreg Clayton { 9588f343b09SGreg Clayton result.AppendError ("must have a valid process in order to load a shared library"); 9598f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9608f343b09SGreg Clayton return false; 9618f343b09SGreg Clayton } 9628f343b09SGreg Clayton 9638f343b09SGreg Clayton const uint32_t argc = command.GetArgumentCount(); 9648f343b09SGreg Clayton 9658f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 9668f343b09SGreg Clayton { 9678f343b09SGreg Clayton const char *image_token_cstr = command.GetArgumentAtIndex(i); 9688f343b09SGreg Clayton uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 9698f343b09SGreg Clayton if (image_token == LLDB_INVALID_IMAGE_TOKEN) 9708f343b09SGreg Clayton { 9718f343b09SGreg Clayton result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 9728f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9738f343b09SGreg Clayton break; 9748f343b09SGreg Clayton } 9758f343b09SGreg Clayton else 9768f343b09SGreg Clayton { 9778f343b09SGreg Clayton Error error (process->UnloadImage(image_token)); 9788f343b09SGreg Clayton if (error.Success()) 9798f343b09SGreg Clayton { 9808f343b09SGreg Clayton result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 9818f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 9828f343b09SGreg Clayton } 9838f343b09SGreg Clayton else 9848f343b09SGreg Clayton { 9858f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 9868f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 9878f343b09SGreg Clayton break; 9888f343b09SGreg Clayton } 9898f343b09SGreg Clayton } 9908f343b09SGreg Clayton } 9918f343b09SGreg Clayton return result.Succeeded(); 9928f343b09SGreg Clayton } 9938f343b09SGreg Clayton }; 9948f343b09SGreg Clayton 9958f343b09SGreg Clayton //------------------------------------------------------------------------- 99630fdc8d8SChris Lattner // CommandObjectProcessSignal 99730fdc8d8SChris Lattner //------------------------------------------------------------------------- 99830fdc8d8SChris Lattner 99930fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 100030fdc8d8SChris Lattner { 100130fdc8d8SChris Lattner public: 100230fdc8d8SChris Lattner 1003a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 1004a7015092SGreg Clayton CommandObject (interpreter, 1005a7015092SGreg Clayton "process signal", 1006e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 1007405fe67fSCaroline Tice NULL) 100830fdc8d8SChris Lattner { 1009405fe67fSCaroline Tice CommandArgumentEntry arg; 1010405fe67fSCaroline Tice CommandArgumentData signal_arg; 1011405fe67fSCaroline Tice 1012405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 1013c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1014405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 1015405fe67fSCaroline Tice 1016405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 1017405fe67fSCaroline Tice arg.push_back (signal_arg); 1018405fe67fSCaroline Tice 1019405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1020405fe67fSCaroline Tice m_arguments.push_back (arg); 102130fdc8d8SChris Lattner } 102230fdc8d8SChris Lattner 102330fdc8d8SChris Lattner ~CommandObjectProcessSignal () 102430fdc8d8SChris Lattner { 102530fdc8d8SChris Lattner } 102630fdc8d8SChris Lattner 102730fdc8d8SChris Lattner bool 1028a7015092SGreg Clayton Execute (Args& command, 102930fdc8d8SChris Lattner CommandReturnObject &result) 103030fdc8d8SChris Lattner { 1031a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 103230fdc8d8SChris Lattner if (process == NULL) 103330fdc8d8SChris Lattner { 103430fdc8d8SChris Lattner result.AppendError ("no process to signal"); 103530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 103630fdc8d8SChris Lattner return false; 103730fdc8d8SChris Lattner } 103830fdc8d8SChris Lattner 103930fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 104030fdc8d8SChris Lattner { 1041237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1042237cd906SGreg Clayton 1043237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1044237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 1045237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1046237cd906SGreg Clayton else 1047237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 1048237cd906SGreg Clayton 1049237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 105030fdc8d8SChris Lattner { 105130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 105230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 105330fdc8d8SChris Lattner } 105430fdc8d8SChris Lattner else 105530fdc8d8SChris Lattner { 105630fdc8d8SChris Lattner Error error (process->Signal (signo)); 105730fdc8d8SChris Lattner if (error.Success()) 105830fdc8d8SChris Lattner { 105930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 106030fdc8d8SChris Lattner } 106130fdc8d8SChris Lattner else 106230fdc8d8SChris Lattner { 106330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 106430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 106530fdc8d8SChris Lattner } 106630fdc8d8SChris Lattner } 106730fdc8d8SChris Lattner } 106830fdc8d8SChris Lattner else 106930fdc8d8SChris Lattner { 107030fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 107130fdc8d8SChris Lattner m_cmd_syntax.c_str()); 107230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 107330fdc8d8SChris Lattner } 107430fdc8d8SChris Lattner return result.Succeeded(); 107530fdc8d8SChris Lattner } 107630fdc8d8SChris Lattner }; 107730fdc8d8SChris Lattner 107830fdc8d8SChris Lattner 107930fdc8d8SChris Lattner //------------------------------------------------------------------------- 108030fdc8d8SChris Lattner // CommandObjectProcessInterrupt 108130fdc8d8SChris Lattner //------------------------------------------------------------------------- 108230fdc8d8SChris Lattner 108330fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 108430fdc8d8SChris Lattner { 108530fdc8d8SChris Lattner public: 108630fdc8d8SChris Lattner 108730fdc8d8SChris Lattner 1088a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 1089a7015092SGreg Clayton CommandObject (interpreter, 1090a7015092SGreg Clayton "process interrupt", 1091e3d26315SCaroline Tice "Interrupt the current process being debugged.", 109230fdc8d8SChris Lattner "process interrupt", 109330fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 109430fdc8d8SChris Lattner { 109530fdc8d8SChris Lattner } 109630fdc8d8SChris Lattner 109730fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 109830fdc8d8SChris Lattner { 109930fdc8d8SChris Lattner } 110030fdc8d8SChris Lattner 110130fdc8d8SChris Lattner bool 1102a7015092SGreg Clayton Execute (Args& command, 110330fdc8d8SChris Lattner CommandReturnObject &result) 110430fdc8d8SChris Lattner { 1105a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 110630fdc8d8SChris Lattner if (process == NULL) 110730fdc8d8SChris Lattner { 110830fdc8d8SChris Lattner result.AppendError ("no process to halt"); 110930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 111030fdc8d8SChris Lattner return false; 111130fdc8d8SChris Lattner } 111230fdc8d8SChris Lattner 111330fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 111430fdc8d8SChris Lattner { 111530fdc8d8SChris Lattner Error error(process->Halt ()); 111630fdc8d8SChris Lattner if (error.Success()) 111730fdc8d8SChris Lattner { 111830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 111930fdc8d8SChris Lattner 112030fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 112130fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 112230fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 112330fdc8d8SChris Lattner } 112430fdc8d8SChris Lattner else 112530fdc8d8SChris Lattner { 112630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 112730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 112830fdc8d8SChris Lattner } 112930fdc8d8SChris Lattner } 113030fdc8d8SChris Lattner else 113130fdc8d8SChris Lattner { 113230fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 113330fdc8d8SChris Lattner m_cmd_name.c_str(), 113430fdc8d8SChris Lattner m_cmd_syntax.c_str()); 113530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 113630fdc8d8SChris Lattner } 113730fdc8d8SChris Lattner return result.Succeeded(); 113830fdc8d8SChris Lattner } 113930fdc8d8SChris Lattner }; 114030fdc8d8SChris Lattner 114130fdc8d8SChris Lattner //------------------------------------------------------------------------- 114230fdc8d8SChris Lattner // CommandObjectProcessKill 114330fdc8d8SChris Lattner //------------------------------------------------------------------------- 114430fdc8d8SChris Lattner 114530fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 114630fdc8d8SChris Lattner { 114730fdc8d8SChris Lattner public: 114830fdc8d8SChris Lattner 1149a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1150a7015092SGreg Clayton CommandObject (interpreter, 1151a7015092SGreg Clayton "process kill", 1152e3d26315SCaroline Tice "Terminate the current process being debugged.", 115330fdc8d8SChris Lattner "process kill", 115430fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 115530fdc8d8SChris Lattner { 115630fdc8d8SChris Lattner } 115730fdc8d8SChris Lattner 115830fdc8d8SChris Lattner ~CommandObjectProcessKill () 115930fdc8d8SChris Lattner { 116030fdc8d8SChris Lattner } 116130fdc8d8SChris Lattner 116230fdc8d8SChris Lattner bool 1163a7015092SGreg Clayton Execute (Args& command, 116430fdc8d8SChris Lattner CommandReturnObject &result) 116530fdc8d8SChris Lattner { 1166a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 116730fdc8d8SChris Lattner if (process == NULL) 116830fdc8d8SChris Lattner { 116930fdc8d8SChris Lattner result.AppendError ("no process to kill"); 117030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 117130fdc8d8SChris Lattner return false; 117230fdc8d8SChris Lattner } 117330fdc8d8SChris Lattner 117430fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 117530fdc8d8SChris Lattner { 117630fdc8d8SChris Lattner Error error (process->Destroy()); 117730fdc8d8SChris Lattner if (error.Success()) 117830fdc8d8SChris Lattner { 117930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 118030fdc8d8SChris Lattner } 118130fdc8d8SChris Lattner else 118230fdc8d8SChris Lattner { 118330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 118430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 118530fdc8d8SChris Lattner } 118630fdc8d8SChris Lattner } 118730fdc8d8SChris Lattner else 118830fdc8d8SChris Lattner { 118930fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 119030fdc8d8SChris Lattner m_cmd_name.c_str(), 119130fdc8d8SChris Lattner m_cmd_syntax.c_str()); 119230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 119330fdc8d8SChris Lattner } 119430fdc8d8SChris Lattner return result.Succeeded(); 119530fdc8d8SChris Lattner } 119630fdc8d8SChris Lattner }; 119730fdc8d8SChris Lattner 119830fdc8d8SChris Lattner //------------------------------------------------------------------------- 11994b9bea87SJim Ingham // CommandObjectProcessStatus 12004b9bea87SJim Ingham //------------------------------------------------------------------------- 12014b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 12024b9bea87SJim Ingham { 12034b9bea87SJim Ingham public: 1204a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1205a7015092SGreg Clayton CommandObject (interpreter, 1206a7015092SGreg Clayton "process status", 1207e3d26315SCaroline Tice "Show the current status and location of executing process.", 1208e3d26315SCaroline Tice "process status", 12094b9bea87SJim Ingham 0) 12104b9bea87SJim Ingham { 12114b9bea87SJim Ingham } 12124b9bea87SJim Ingham 12134b9bea87SJim Ingham ~CommandObjectProcessStatus() 12144b9bea87SJim Ingham { 12154b9bea87SJim Ingham } 12164b9bea87SJim Ingham 12174b9bea87SJim Ingham 12184b9bea87SJim Ingham bool 12194b9bea87SJim Ingham Execute 12204b9bea87SJim Ingham ( 12214b9bea87SJim Ingham Args& command, 12224b9bea87SJim Ingham CommandReturnObject &result 12234b9bea87SJim Ingham ) 12244b9bea87SJim Ingham { 12254b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 12264b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1227a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 12284b9bea87SJim Ingham if (exe_ctx.process) 12294b9bea87SJim Ingham { 12304b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 12314b9bea87SJim Ingham if (StateIsStoppedState(state)) 12324b9bea87SJim Ingham { 12334b9bea87SJim Ingham if (state == eStateExited) 12344b9bea87SJim Ingham { 12354b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 12364b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 12374b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 12384b9bea87SJim Ingham exe_ctx.process->GetID(), 12394b9bea87SJim Ingham exit_status, 12404b9bea87SJim Ingham exit_status, 12414b9bea87SJim Ingham exit_description ? exit_description : ""); 12424b9bea87SJim Ingham } 12434b9bea87SJim Ingham else 12444b9bea87SJim Ingham { 12454b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 12464b9bea87SJim Ingham if (exe_ctx.thread == NULL) 12474b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 12484b9bea87SJim Ingham if (exe_ctx.thread != NULL) 12494b9bea87SJim Ingham { 1250a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 12514b9bea87SJim Ingham } 12524b9bea87SJim Ingham else 12534b9bea87SJim Ingham { 12544b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 12554b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 12564b9bea87SJim Ingham } 12574b9bea87SJim Ingham } 12584b9bea87SJim Ingham } 12594b9bea87SJim Ingham else 12604b9bea87SJim Ingham { 12614b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 12624b9bea87SJim Ingham exe_ctx.process->GetID()); 12634b9bea87SJim Ingham } 12644b9bea87SJim Ingham } 12654b9bea87SJim Ingham else 12664b9bea87SJim Ingham { 12674b9bea87SJim Ingham result.AppendError ("No current location or status available."); 12684b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 12694b9bea87SJim Ingham } 12704b9bea87SJim Ingham return result.Succeeded(); 12714b9bea87SJim Ingham } 12724b9bea87SJim Ingham }; 12734b9bea87SJim Ingham 12744b9bea87SJim Ingham //------------------------------------------------------------------------- 127535731357SCaroline Tice // CommandObjectProcessHandle 127635731357SCaroline Tice //------------------------------------------------------------------------- 127735731357SCaroline Tice 127835731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 127935731357SCaroline Tice { 128035731357SCaroline Tice public: 128135731357SCaroline Tice 128235731357SCaroline Tice class CommandOptions : public Options 128335731357SCaroline Tice { 128435731357SCaroline Tice public: 128535731357SCaroline Tice 128635731357SCaroline Tice CommandOptions () : 128735731357SCaroline Tice Options () 128835731357SCaroline Tice { 128935731357SCaroline Tice ResetOptionValues (); 129035731357SCaroline Tice } 129135731357SCaroline Tice 129235731357SCaroline Tice ~CommandOptions () 129335731357SCaroline Tice { 129435731357SCaroline Tice } 129535731357SCaroline Tice 129635731357SCaroline Tice Error 129735731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 129835731357SCaroline Tice { 129935731357SCaroline Tice Error error; 130035731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 130135731357SCaroline Tice 130235731357SCaroline Tice switch (short_option) 130335731357SCaroline Tice { 130435731357SCaroline Tice case 's': 130535731357SCaroline Tice stop = option_arg; 130635731357SCaroline Tice break; 130735731357SCaroline Tice case 'n': 130835731357SCaroline Tice notify = option_arg; 130935731357SCaroline Tice break; 131035731357SCaroline Tice case 'p': 131135731357SCaroline Tice pass = option_arg; 131235731357SCaroline Tice break; 131335731357SCaroline Tice default: 131435731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 131535731357SCaroline Tice break; 131635731357SCaroline Tice } 131735731357SCaroline Tice return error; 131835731357SCaroline Tice } 131935731357SCaroline Tice 132035731357SCaroline Tice void 132135731357SCaroline Tice ResetOptionValues () 132235731357SCaroline Tice { 132335731357SCaroline Tice Options::ResetOptionValues(); 132435731357SCaroline Tice stop.clear(); 132535731357SCaroline Tice notify.clear(); 132635731357SCaroline Tice pass.clear(); 132735731357SCaroline Tice } 132835731357SCaroline Tice 132935731357SCaroline Tice const lldb::OptionDefinition* 133035731357SCaroline Tice GetDefinitions () 133135731357SCaroline Tice { 133235731357SCaroline Tice return g_option_table; 133335731357SCaroline Tice } 133435731357SCaroline Tice 133535731357SCaroline Tice // Options table: Required for subclasses of Options. 133635731357SCaroline Tice 133735731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 133835731357SCaroline Tice 133935731357SCaroline Tice // Instance variables to hold the values for command options. 134035731357SCaroline Tice 134135731357SCaroline Tice std::string stop; 134235731357SCaroline Tice std::string notify; 134335731357SCaroline Tice std::string pass; 134435731357SCaroline Tice }; 134535731357SCaroline Tice 134635731357SCaroline Tice 134735731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 134835731357SCaroline Tice CommandObject (interpreter, 134935731357SCaroline Tice "process handle", 135010ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 135135731357SCaroline Tice NULL) 135235731357SCaroline Tice { 135310ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 135435731357SCaroline Tice CommandArgumentEntry arg; 1355c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 135635731357SCaroline Tice 1357c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1358c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 135935731357SCaroline Tice 1360c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 136135731357SCaroline Tice 136235731357SCaroline Tice m_arguments.push_back (arg); 136335731357SCaroline Tice } 136435731357SCaroline Tice 136535731357SCaroline Tice ~CommandObjectProcessHandle () 136635731357SCaroline Tice { 136735731357SCaroline Tice } 136835731357SCaroline Tice 136935731357SCaroline Tice Options * 137035731357SCaroline Tice GetOptions () 137135731357SCaroline Tice { 137235731357SCaroline Tice return &m_options; 137335731357SCaroline Tice } 137435731357SCaroline Tice 137535731357SCaroline Tice bool 137610ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 137735731357SCaroline Tice { 137835731357SCaroline Tice bool okay = true; 137935731357SCaroline Tice 138010ad7993SCaroline Tice bool success = false; 138110ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 138210ad7993SCaroline Tice 138310ad7993SCaroline Tice if (success && tmp_value) 138410ad7993SCaroline Tice real_value = 1; 138510ad7993SCaroline Tice else if (success && !tmp_value) 138610ad7993SCaroline Tice real_value = 0; 138735731357SCaroline Tice else 138835731357SCaroline Tice { 138935731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 139010ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 139110ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 139235731357SCaroline Tice okay = false; 139335731357SCaroline Tice } 139435731357SCaroline Tice 139535731357SCaroline Tice return okay; 139635731357SCaroline Tice } 139735731357SCaroline Tice 139810ad7993SCaroline Tice void 139910ad7993SCaroline Tice PrintSignalHeader (Stream &str) 140010ad7993SCaroline Tice { 140110ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 140210ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 140310ad7993SCaroline Tice } 140410ad7993SCaroline Tice 140510ad7993SCaroline Tice void 140610ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 140710ad7993SCaroline Tice { 140810ad7993SCaroline Tice bool stop; 140910ad7993SCaroline Tice bool suppress; 141010ad7993SCaroline Tice bool notify; 141110ad7993SCaroline Tice 141210ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 141310ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 141410ad7993SCaroline Tice { 141510ad7993SCaroline Tice bool pass = !suppress; 141610ad7993SCaroline Tice str.Printf ("%s %s %s", 141710ad7993SCaroline Tice (pass ? "true " : "false"), 141810ad7993SCaroline Tice (stop ? "true " : "false"), 141910ad7993SCaroline Tice (notify ? "true " : "false")); 142010ad7993SCaroline Tice } 142110ad7993SCaroline Tice str.Printf ("\n"); 142210ad7993SCaroline Tice } 142310ad7993SCaroline Tice 142410ad7993SCaroline Tice void 142510ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 142610ad7993SCaroline Tice { 142710ad7993SCaroline Tice PrintSignalHeader (str); 142810ad7993SCaroline Tice 142910ad7993SCaroline Tice if (num_valid_signals > 0) 143010ad7993SCaroline Tice { 143110ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 143210ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 143310ad7993SCaroline Tice { 143410ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 143510ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 143610ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 143710ad7993SCaroline Tice } 143810ad7993SCaroline Tice } 143910ad7993SCaroline Tice else // Print info for ALL signals 144010ad7993SCaroline Tice { 144110ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 144210ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 144310ad7993SCaroline Tice { 144410ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 144510ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 144610ad7993SCaroline Tice } 144710ad7993SCaroline Tice } 144810ad7993SCaroline Tice } 144910ad7993SCaroline Tice 145035731357SCaroline Tice bool 145135731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 145235731357SCaroline Tice { 145335731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 145435731357SCaroline Tice 145535731357SCaroline Tice if (!target_sp) 145635731357SCaroline Tice { 145735731357SCaroline Tice result.AppendError ("No current target;" 145835731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 145935731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 146035731357SCaroline Tice return false; 146135731357SCaroline Tice } 146235731357SCaroline Tice 146335731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 146435731357SCaroline Tice 146535731357SCaroline Tice if (!process_sp) 146635731357SCaroline Tice { 146735731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 146835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 146935731357SCaroline Tice return false; 147035731357SCaroline Tice } 147135731357SCaroline Tice 147235731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 147335731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 147435731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 147535731357SCaroline Tice 147635731357SCaroline Tice if (! m_options.stop.empty() 147710ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 147835731357SCaroline Tice { 147935731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 148035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 148135731357SCaroline Tice return false; 148235731357SCaroline Tice } 148335731357SCaroline Tice 148435731357SCaroline Tice if (! m_options.notify.empty() 148510ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 148635731357SCaroline Tice { 148735731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 148835731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 148935731357SCaroline Tice return false; 149035731357SCaroline Tice } 149135731357SCaroline Tice 149235731357SCaroline Tice if (! m_options.pass.empty() 149310ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 149435731357SCaroline Tice { 149535731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 149635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 149735731357SCaroline Tice return false; 149835731357SCaroline Tice } 149935731357SCaroline Tice 150035731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 150135731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 150235731357SCaroline Tice int num_signals_set = 0; 150335731357SCaroline Tice 150410ad7993SCaroline Tice if (num_args > 0) 150510ad7993SCaroline Tice { 150635731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 150735731357SCaroline Tice { 150835731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 150935731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 151035731357SCaroline Tice { 151110ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 151235731357SCaroline Tice // the value is either 0 or 1. 151335731357SCaroline Tice if (stop_action != -1) 151435731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 151535731357SCaroline Tice if (pass_action != -1) 151635731357SCaroline Tice { 151710ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 151810ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 151935731357SCaroline Tice } 152035731357SCaroline Tice if (notify_action != -1) 152135731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 152235731357SCaroline Tice ++num_signals_set; 152335731357SCaroline Tice } 152435731357SCaroline Tice else 152535731357SCaroline Tice { 152635731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 152735731357SCaroline Tice } 152835731357SCaroline Tice } 152910ad7993SCaroline Tice } 153010ad7993SCaroline Tice else 153110ad7993SCaroline Tice { 153210ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 153310ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 153410ad7993SCaroline Tice { 153510ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 153610ad7993SCaroline Tice { 153710ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 153810ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 153910ad7993SCaroline Tice { 154010ad7993SCaroline Tice if (notify_action != -1) 154110ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 154210ad7993SCaroline Tice if (stop_action != -1) 154310ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 154410ad7993SCaroline Tice if (pass_action != -1) 154510ad7993SCaroline Tice { 154610ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 154710ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 154810ad7993SCaroline Tice } 154910ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 155010ad7993SCaroline Tice } 155110ad7993SCaroline Tice } 155210ad7993SCaroline Tice } 155310ad7993SCaroline Tice } 155410ad7993SCaroline Tice 155510ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 155635731357SCaroline Tice 155735731357SCaroline Tice if (num_signals_set > 0) 155835731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 155935731357SCaroline Tice else 156035731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 156135731357SCaroline Tice 156235731357SCaroline Tice return result.Succeeded(); 156335731357SCaroline Tice } 156435731357SCaroline Tice 156535731357SCaroline Tice protected: 156635731357SCaroline Tice 156735731357SCaroline Tice CommandOptions m_options; 156835731357SCaroline Tice }; 156935731357SCaroline Tice 157035731357SCaroline Tice lldb::OptionDefinition 157135731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 157235731357SCaroline Tice { 157335731357SCaroline 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." }, 157435731357SCaroline 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." }, 157535731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 157635731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 157735731357SCaroline Tice }; 157835731357SCaroline Tice 157935731357SCaroline Tice //------------------------------------------------------------------------- 158030fdc8d8SChris Lattner // CommandObjectMultiwordProcess 158130fdc8d8SChris Lattner //------------------------------------------------------------------------- 158230fdc8d8SChris Lattner 15836611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1584a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1585a7015092SGreg Clayton "process", 158630fdc8d8SChris Lattner "A set of commands for operating on a process.", 158730fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 158830fdc8d8SChris Lattner { 1589a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1590a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1591a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1592a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 15938f343b09SGreg Clayton LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 15948f343b09SGreg Clayton LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1595a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 159635731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1597a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1598a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1599a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 160030fdc8d8SChris Lattner } 160130fdc8d8SChris Lattner 160230fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 160330fdc8d8SChris Lattner { 160430fdc8d8SChris Lattner } 160530fdc8d8SChris Lattner 1606