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; 6519388cfcSGreg Clayton case 't': in_new_tty = true; break; 6630fdc8d8SChris Lattner default: 6730fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 6830fdc8d8SChris Lattner break; 6930fdc8d8SChris Lattner 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner return error; 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 7430fdc8d8SChris Lattner void 7530fdc8d8SChris Lattner ResetOptionValues () 7630fdc8d8SChris Lattner { 7730fdc8d8SChris Lattner Options::ResetOptionValues(); 7830fdc8d8SChris Lattner stop_at_entry = false; 7919388cfcSGreg Clayton in_new_tty = false; 8030fdc8d8SChris Lattner stdin_path.clear(); 8130fdc8d8SChris Lattner stdout_path.clear(); 8230fdc8d8SChris Lattner stderr_path.clear(); 8330fdc8d8SChris Lattner plugin_name.clear(); 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner 8630fdc8d8SChris Lattner const lldb::OptionDefinition* 8730fdc8d8SChris Lattner GetDefinitions () 8830fdc8d8SChris Lattner { 8930fdc8d8SChris Lattner return g_option_table; 9030fdc8d8SChris Lattner } 9130fdc8d8SChris Lattner 9230fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 9330fdc8d8SChris Lattner 9430fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 9530fdc8d8SChris Lattner 9630fdc8d8SChris Lattner // Instance variables to hold the values for command options. 9730fdc8d8SChris Lattner 9830fdc8d8SChris Lattner bool stop_at_entry; 9919388cfcSGreg Clayton bool in_new_tty; 10030fdc8d8SChris Lattner std::string stderr_path; 10130fdc8d8SChris Lattner std::string stdin_path; 10230fdc8d8SChris Lattner std::string stdout_path; 10330fdc8d8SChris Lattner std::string plugin_name; 10430fdc8d8SChris Lattner 10530fdc8d8SChris Lattner }; 10630fdc8d8SChris Lattner 107a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 108a7015092SGreg Clayton CommandObject (interpreter, 109a7015092SGreg Clayton "process launch", 110e3d26315SCaroline Tice "Launch the executable in the debugger.", 111405fe67fSCaroline Tice NULL) 11230fdc8d8SChris Lattner { 113405fe67fSCaroline Tice CommandArgumentEntry arg; 114405fe67fSCaroline Tice CommandArgumentData run_args_arg; 115405fe67fSCaroline Tice 116405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 117405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 118405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 119405fe67fSCaroline Tice 120405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 121405fe67fSCaroline Tice arg.push_back (run_args_arg); 122405fe67fSCaroline Tice 123405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 124405fe67fSCaroline Tice m_arguments.push_back (arg); 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner 12730fdc8d8SChris Lattner 12830fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 12930fdc8d8SChris Lattner { 13030fdc8d8SChris Lattner } 13130fdc8d8SChris Lattner 13230fdc8d8SChris Lattner Options * 13330fdc8d8SChris Lattner GetOptions () 13430fdc8d8SChris Lattner { 13530fdc8d8SChris Lattner return &m_options; 13630fdc8d8SChris Lattner } 13730fdc8d8SChris Lattner 13830fdc8d8SChris Lattner bool 13905faeb71SGreg Clayton Execute (Args& launch_args, CommandReturnObject &result) 14030fdc8d8SChris Lattner { 141a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 14230fdc8d8SChris Lattner 14330fdc8d8SChris Lattner if (target == NULL) 14430fdc8d8SChris Lattner { 14530fdc8d8SChris Lattner result.AppendError ("invalid target, set executable file using 'file' command"); 14630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 14730fdc8d8SChris Lattner return false; 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner 15030fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 15130fdc8d8SChris Lattner char filename[PATH_MAX]; 15219388cfcSGreg Clayton const Module *exe_module = target->GetExecutableModule().get(); 15330fdc8d8SChris Lattner exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 15430fdc8d8SChris Lattner 155a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 156a7015092SGreg Clayton if (process && 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 const char *plugin_name; 16530fdc8d8SChris Lattner if (!m_options.plugin_name.empty()) 16630fdc8d8SChris Lattner plugin_name = m_options.plugin_name.c_str(); 16730fdc8d8SChris Lattner else 16830fdc8d8SChris Lattner plugin_name = NULL; 16930fdc8d8SChris Lattner 170a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 17130fdc8d8SChris Lattner 172a7015092SGreg Clayton if (process == NULL) 1733df9a8dfSCaroline Tice { 17443a8c39bSCaroline Tice result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 175a7015092SGreg Clayton result.SetStatus (eReturnStatusFailed); 176a7015092SGreg Clayton return false; 1773df9a8dfSCaroline Tice } 1783df9a8dfSCaroline Tice 179a7015092SGreg Clayton // If no launch args were given on the command line, then use any that 180a7015092SGreg Clayton // might have been set using the "run-args" set variable. 18130fdc8d8SChris Lattner if (launch_args.GetArgumentCount() == 0) 18230fdc8d8SChris Lattner { 183a7015092SGreg Clayton if (process->GetRunArguments().GetArgumentCount() > 0) 184a7015092SGreg Clayton launch_args = process->GetRunArguments(); 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner 18719388cfcSGreg Clayton if (m_options.in_new_tty) 18819388cfcSGreg Clayton { 18919388cfcSGreg Clayton char exec_file_path[PATH_MAX]; 19019388cfcSGreg Clayton if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 19119388cfcSGreg Clayton { 19219388cfcSGreg Clayton launch_args.InsertArgumentAtIndex(0, exec_file_path); 19319388cfcSGreg Clayton } 19419388cfcSGreg Clayton else 19519388cfcSGreg Clayton { 19619388cfcSGreg Clayton result.AppendError("invalid executable"); 19719388cfcSGreg Clayton result.SetStatus (eReturnStatusFailed); 19819388cfcSGreg Clayton return false; 19919388cfcSGreg Clayton } 20019388cfcSGreg Clayton } 20119388cfcSGreg Clayton 202a7015092SGreg Clayton Args environment; 20330fdc8d8SChris Lattner 204a7015092SGreg Clayton process->GetEnvironmentAsArgs (environment); 205a7015092SGreg Clayton 206a7015092SGreg Clayton uint32_t launch_flags = eLaunchFlagNone; 207a7015092SGreg Clayton 208a7015092SGreg Clayton if (process->GetDisableASLR()) 209a7015092SGreg Clayton launch_flags |= eLaunchFlagDisableASLR; 210a7015092SGreg Clayton 21119388cfcSGreg Clayton const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 21219388cfcSGreg Clayton const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 21330fdc8d8SChris Lattner 21419388cfcSGreg Clayton Error error; 21519388cfcSGreg Clayton 21619388cfcSGreg Clayton if (m_options.in_new_tty) 21719388cfcSGreg Clayton { 21819388cfcSGreg Clayton 21919388cfcSGreg Clayton lldb::pid_t terminal_pid = Host::LaunchInNewTerminal (inferior_argv, 22019388cfcSGreg Clayton inferior_envp, 22119388cfcSGreg Clayton &exe_module->GetArchitecture(), 22219388cfcSGreg Clayton true, 22319388cfcSGreg Clayton process->GetDisableASLR()); 22419388cfcSGreg Clayton 22519388cfcSGreg Clayton // Let the app get launched and stopped... 22619388cfcSGreg Clayton const char *process_name = exe_module->GetFileSpec().GetFilename().AsCString("<invalid>"); 22719388cfcSGreg Clayton 22819388cfcSGreg Clayton if (terminal_pid == LLDB_INVALID_PROCESS_ID) 22919388cfcSGreg Clayton { 23019388cfcSGreg Clayton error.SetErrorStringWithFormat ("failed to launch '%s' in new terminal", process_name); 23119388cfcSGreg Clayton } 23219388cfcSGreg Clayton else 23319388cfcSGreg Clayton { 23419388cfcSGreg Clayton for (int i=0; i<20; i++) 23519388cfcSGreg Clayton { 23619388cfcSGreg Clayton usleep (250000); 23719388cfcSGreg Clayton error = process->Attach (process_name, false); 23819388cfcSGreg Clayton if (error.Success()) 23919388cfcSGreg Clayton break; 24019388cfcSGreg Clayton } 24119388cfcSGreg Clayton } 24219388cfcSGreg Clayton } 24319388cfcSGreg Clayton else 24419388cfcSGreg Clayton { 24530fdc8d8SChris Lattner const char * stdin_path = NULL; 24630fdc8d8SChris Lattner const char * stdout_path = NULL; 24730fdc8d8SChris Lattner const char * stderr_path = NULL; 24830fdc8d8SChris Lattner 249a7015092SGreg Clayton // Were any standard input/output/error paths given on the command line? 250a7015092SGreg Clayton if (m_options.stdin_path.empty() && 25130fdc8d8SChris Lattner m_options.stdout_path.empty() && 252a7015092SGreg Clayton m_options.stderr_path.empty()) 25330fdc8d8SChris Lattner { 254a7015092SGreg Clayton // No standard file handles were given on the command line, check 255a7015092SGreg Clayton // with the process object in case they were give using "set settings" 256a7015092SGreg Clayton stdin_path = process->GetStandardInputPath(); 257a7015092SGreg Clayton stdout_path = process->GetStandardOutputPath(); 258a7015092SGreg Clayton stderr_path = process->GetStandardErrorPath(); 259a7015092SGreg Clayton } 260a7015092SGreg Clayton else 261a7015092SGreg Clayton { 262a7015092SGreg Clayton stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 263a7015092SGreg Clayton stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 264a7015092SGreg Clayton stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 26530fdc8d8SChris Lattner } 26630fdc8d8SChris Lattner 267a7015092SGreg Clayton if (stdin_path == NULL) 268a7015092SGreg Clayton stdin_path = "/dev/null"; 269a7015092SGreg Clayton if (stdout_path == NULL) 270a7015092SGreg Clayton stdout_path = "/dev/null"; 271a7015092SGreg Clayton if (stderr_path == NULL) 272a7015092SGreg Clayton stderr_path = "/dev/null"; 273a7015092SGreg Clayton 27419388cfcSGreg Clayton error = process->Launch (inferior_argv, 27519388cfcSGreg Clayton inferior_envp, 276f681b94fSGreg Clayton launch_flags, 27730fdc8d8SChris Lattner stdin_path, 27830fdc8d8SChris Lattner stdout_path, 27919388cfcSGreg Clayton stderr_path); 28019388cfcSGreg Clayton } 28130fdc8d8SChris Lattner 28230fdc8d8SChris Lattner if (error.Success()) 28330fdc8d8SChris Lattner { 28419388cfcSGreg Clayton const char *archname = exe_module->GetArchitecture().AsCString(); 28519388cfcSGreg Clayton 28619388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 28705faeb71SGreg Clayton result.SetDidChangeProcessState (true); 28830fdc8d8SChris Lattner if (m_options.stop_at_entry == false) 28930fdc8d8SChris Lattner { 29005faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 29130fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 29230fdc8d8SChris Lattner 29330fdc8d8SChris Lattner if (state == eStateStopped) 29430fdc8d8SChris Lattner { 29505faeb71SGreg Clayton error = process->Resume(); 29605faeb71SGreg Clayton if (error.Success()) 29705faeb71SGreg Clayton { 29805faeb71SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 29930fdc8d8SChris Lattner if (synchronous_execution) 30030fdc8d8SChris Lattner { 30105faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 30230fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 30305faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 30405faeb71SGreg Clayton } 30505faeb71SGreg Clayton else 30605faeb71SGreg Clayton { 30705faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 30805faeb71SGreg Clayton } 30905faeb71SGreg Clayton } 31030fdc8d8SChris Lattner } 31130fdc8d8SChris Lattner } 31230fdc8d8SChris Lattner } 31330fdc8d8SChris Lattner 31430fdc8d8SChris Lattner return result.Succeeded(); 31530fdc8d8SChris Lattner } 31630fdc8d8SChris Lattner 317ebc09c36SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 318ebc09c36SJim Ingham { 319ebc09c36SJim Ingham // No repeat for "process launch"... 320ebc09c36SJim Ingham return ""; 321ebc09c36SJim Ingham } 322ebc09c36SJim Ingham 32330fdc8d8SChris Lattner protected: 32430fdc8d8SChris Lattner 32530fdc8d8SChris Lattner CommandOptions m_options; 32630fdc8d8SChris Lattner }; 32730fdc8d8SChris Lattner 32830fdc8d8SChris Lattner 32919388cfcSGreg Clayton #define SET1 LLDB_OPT_SET_1 33019388cfcSGreg Clayton #define SET2 LLDB_OPT_SET_2 33119388cfcSGreg Clayton 33230fdc8d8SChris Lattner lldb::OptionDefinition 33330fdc8d8SChris Lattner CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 33430fdc8d8SChris Lattner { 33519388cfcSGreg Clayton { SET1 | SET2, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 33619388cfcSGreg Clayton { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 33719388cfcSGreg Clayton { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 33819388cfcSGreg Clayton { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 33919388cfcSGreg Clayton { SET1 | SET2, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 34019388cfcSGreg Clayton { SET2, false, "tty", 't', no_argument, NULL, 0, eArgTypeNone, "Start the process in a new terminal (tty)."}, 341deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 34230fdc8d8SChris Lattner }; 34330fdc8d8SChris Lattner 34419388cfcSGreg Clayton #undef SET1 34519388cfcSGreg Clayton #undef SET2 34630fdc8d8SChris Lattner 34730fdc8d8SChris Lattner //------------------------------------------------------------------------- 34830fdc8d8SChris Lattner // CommandObjectProcessAttach 34930fdc8d8SChris Lattner //------------------------------------------------------------------------- 35030fdc8d8SChris Lattner 35130fdc8d8SChris Lattner class CommandObjectProcessAttach : public CommandObject 35230fdc8d8SChris Lattner { 35330fdc8d8SChris Lattner public: 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner class CommandOptions : public Options 35630fdc8d8SChris Lattner { 35730fdc8d8SChris Lattner public: 35830fdc8d8SChris Lattner 35930fdc8d8SChris Lattner CommandOptions () : 36030fdc8d8SChris Lattner Options() 36130fdc8d8SChris Lattner { 36230fdc8d8SChris Lattner // Keep default values of all options in one place: ResetOptionValues () 36330fdc8d8SChris Lattner ResetOptionValues (); 36430fdc8d8SChris Lattner } 36530fdc8d8SChris Lattner 36630fdc8d8SChris Lattner ~CommandOptions () 36730fdc8d8SChris Lattner { 36830fdc8d8SChris Lattner } 36930fdc8d8SChris Lattner 37030fdc8d8SChris Lattner Error 37130fdc8d8SChris Lattner SetOptionValue (int option_idx, const char *option_arg) 37230fdc8d8SChris Lattner { 37330fdc8d8SChris Lattner Error error; 37430fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 37530fdc8d8SChris Lattner bool success = false; 37630fdc8d8SChris Lattner switch (short_option) 37730fdc8d8SChris Lattner { 37830fdc8d8SChris Lattner case 'p': 37930fdc8d8SChris Lattner pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 38030fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 38130fdc8d8SChris Lattner { 38230fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 38330fdc8d8SChris Lattner } 38430fdc8d8SChris Lattner break; 38530fdc8d8SChris Lattner 38630fdc8d8SChris Lattner case 'P': 38730fdc8d8SChris Lattner plugin_name = option_arg; 38830fdc8d8SChris Lattner break; 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner case 'n': 39130fdc8d8SChris Lattner name.assign(option_arg); 39230fdc8d8SChris Lattner break; 39330fdc8d8SChris Lattner 39430fdc8d8SChris Lattner case 'w': 39530fdc8d8SChris Lattner waitfor = true; 39630fdc8d8SChris Lattner break; 39730fdc8d8SChris Lattner 39830fdc8d8SChris Lattner default: 39930fdc8d8SChris Lattner error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 40030fdc8d8SChris Lattner break; 40130fdc8d8SChris Lattner } 40230fdc8d8SChris Lattner return error; 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner 40530fdc8d8SChris Lattner void 40630fdc8d8SChris Lattner ResetOptionValues () 40730fdc8d8SChris Lattner { 40830fdc8d8SChris Lattner Options::ResetOptionValues(); 40930fdc8d8SChris Lattner pid = LLDB_INVALID_PROCESS_ID; 41030fdc8d8SChris Lattner name.clear(); 41130fdc8d8SChris Lattner waitfor = false; 41230fdc8d8SChris Lattner } 41330fdc8d8SChris Lattner 41430fdc8d8SChris Lattner const lldb::OptionDefinition* 41530fdc8d8SChris Lattner GetDefinitions () 41630fdc8d8SChris Lattner { 41730fdc8d8SChris Lattner return g_option_table; 41830fdc8d8SChris Lattner } 41930fdc8d8SChris Lattner 4205aee162fSJim Ingham virtual bool 421a7015092SGreg Clayton HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 4225aee162fSJim Ingham Args &input, 4235aee162fSJim Ingham int cursor_index, 4245aee162fSJim Ingham int char_pos, 4255aee162fSJim Ingham OptionElementVector &opt_element_vector, 4265aee162fSJim Ingham int opt_element_index, 4275aee162fSJim Ingham int match_start_point, 4285aee162fSJim Ingham int max_return_elements, 4295aee162fSJim Ingham bool &word_complete, 4305aee162fSJim Ingham StringList &matches) 4315aee162fSJim Ingham { 4325aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4335aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4345aee162fSJim Ingham 4355aee162fSJim Ingham // We are only completing the name option for now... 4365aee162fSJim Ingham 4375aee162fSJim Ingham const lldb::OptionDefinition *opt_defs = GetDefinitions(); 4385aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4395aee162fSJim Ingham { 4405aee162fSJim Ingham // Are we in the name? 4415aee162fSJim Ingham 4425aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4435aee162fSJim Ingham // use the default plugin. 444a7015092SGreg Clayton Process *process = interpeter.GetDebugger().GetExecutionContext().process; 4455aee162fSJim Ingham bool need_to_delete_process = false; 4465aee162fSJim Ingham 4475aee162fSJim Ingham const char *partial_name = NULL; 4485aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4495aee162fSJim Ingham 4505aee162fSJim Ingham if (process && process->IsAlive()) 4515aee162fSJim Ingham return true; 4525aee162fSJim Ingham 453a7015092SGreg Clayton Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 4545aee162fSJim Ingham if (target == NULL) 4555aee162fSJim Ingham { 4565aee162fSJim Ingham // No target has been set yet, for now do host completion. Otherwise I don't know how we would 4575aee162fSJim Ingham // figure out what the right target to use is... 4585aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4595aee162fSJim Ingham Host::ListProcessesMatchingName (partial_name, matches, pids); 4605aee162fSJim Ingham return true; 4615aee162fSJim Ingham } 4625aee162fSJim Ingham if (!process) 4635aee162fSJim Ingham { 464a7015092SGreg Clayton process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 4655aee162fSJim Ingham need_to_delete_process = true; 4665aee162fSJim Ingham } 4675aee162fSJim Ingham 4685aee162fSJim Ingham if (process) 4695aee162fSJim Ingham { 4705aee162fSJim Ingham matches.Clear(); 4715aee162fSJim Ingham std::vector<lldb::pid_t> pids; 4725aee162fSJim Ingham process->ListProcessesMatchingName (NULL, matches, pids); 4735aee162fSJim Ingham if (need_to_delete_process) 4745aee162fSJim Ingham target->DeleteCurrentProcess(); 4755aee162fSJim Ingham return true; 4765aee162fSJim Ingham } 4775aee162fSJim Ingham } 4785aee162fSJim Ingham 4795aee162fSJim Ingham return false; 4805aee162fSJim Ingham } 4815aee162fSJim Ingham 48230fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 48330fdc8d8SChris Lattner 48430fdc8d8SChris Lattner static lldb::OptionDefinition g_option_table[]; 48530fdc8d8SChris Lattner 48630fdc8d8SChris Lattner // Instance variables to hold the values for command options. 48730fdc8d8SChris Lattner 48830fdc8d8SChris Lattner lldb::pid_t pid; 48930fdc8d8SChris Lattner std::string plugin_name; 49030fdc8d8SChris Lattner std::string name; 49130fdc8d8SChris Lattner bool waitfor; 49230fdc8d8SChris Lattner }; 49330fdc8d8SChris Lattner 494a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 495a7015092SGreg Clayton CommandObject (interpreter, 496a7015092SGreg Clayton "process attach", 497e3d26315SCaroline Tice "Attach to a process.", 4985aee162fSJim Ingham "process attach <cmd-options>") 4995aee162fSJim Ingham { 5005aee162fSJim Ingham } 5015aee162fSJim Ingham 5025aee162fSJim Ingham ~CommandObjectProcessAttach () 5035aee162fSJim Ingham { 5045aee162fSJim Ingham } 5055aee162fSJim Ingham 5065aee162fSJim Ingham bool 507a7015092SGreg Clayton Execute (Args& command, 5085aee162fSJim Ingham CommandReturnObject &result) 5095aee162fSJim Ingham { 510a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5115aee162fSJim Ingham 512a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 5135aee162fSJim Ingham if (process) 5145aee162fSJim Ingham { 5155aee162fSJim Ingham if (process->IsAlive()) 5165aee162fSJim Ingham { 5175aee162fSJim Ingham result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 5185aee162fSJim Ingham process->GetID()); 5195aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5205aee162fSJim Ingham return false; 5215aee162fSJim Ingham } 5225aee162fSJim Ingham } 5235aee162fSJim Ingham 5245aee162fSJim Ingham if (target == NULL) 5255aee162fSJim Ingham { 5265aee162fSJim Ingham // If there isn't a current target create one. 5275aee162fSJim Ingham TargetSP new_target_sp; 5285aee162fSJim Ingham FileSpec emptyFileSpec; 5295aee162fSJim Ingham ArchSpec emptyArchSpec; 5305aee162fSJim Ingham Error error; 5315aee162fSJim Ingham 532a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 5335aee162fSJim Ingham emptyFileSpec, 5345aee162fSJim Ingham emptyArchSpec, 5355aee162fSJim Ingham NULL, 5365aee162fSJim Ingham false, 5375aee162fSJim Ingham new_target_sp); 5385aee162fSJim Ingham target = new_target_sp.get(); 5395aee162fSJim Ingham if (target == NULL || error.Fail()) 5405aee162fSJim Ingham { 5415aee162fSJim Ingham result.AppendError(error.AsCString("Error creating empty target")); 5425aee162fSJim Ingham return false; 5435aee162fSJim Ingham } 544a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5455aee162fSJim Ingham } 5465aee162fSJim Ingham 5475aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5485aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5495aee162fSJim Ingham 5505aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5515aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5525aee162fSJim Ingham 5535aee162fSJim Ingham if (command.GetArgumentCount()) 5545aee162fSJim Ingham { 5555aee162fSJim Ingham result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5565aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5575aee162fSJim Ingham } 5585aee162fSJim Ingham else 5595aee162fSJim Ingham { 5605aee162fSJim Ingham const char *plugin_name = NULL; 5615aee162fSJim Ingham 5625aee162fSJim Ingham if (!m_options.plugin_name.empty()) 5635aee162fSJim Ingham plugin_name = m_options.plugin_name.c_str(); 5645aee162fSJim Ingham 565a7015092SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 5665aee162fSJim Ingham 5675aee162fSJim Ingham if (process) 5685aee162fSJim Ingham { 5695aee162fSJim Ingham Error error; 5705aee162fSJim Ingham int attach_pid = m_options.pid; 5715aee162fSJim Ingham 5723a0b9cdfSJim Ingham const char *wait_name = NULL; 5733a0b9cdfSJim Ingham 5745aee162fSJim Ingham if (m_options.name.empty()) 5755aee162fSJim Ingham { 5763a0b9cdfSJim Ingham if (old_exec_module_sp) 5773a0b9cdfSJim Ingham { 5783a0b9cdfSJim Ingham wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 5793a0b9cdfSJim Ingham } 5805aee162fSJim Ingham } 5815aee162fSJim Ingham else 5825aee162fSJim Ingham { 5833a0b9cdfSJim Ingham wait_name = m_options.name.c_str(); 5843a0b9cdfSJim Ingham } 5853a0b9cdfSJim Ingham 5863a0b9cdfSJim Ingham // If we are waiting for a process with this name to show up, do that first. 5873a0b9cdfSJim Ingham if (m_options.waitfor) 5883a0b9cdfSJim Ingham { 5893a0b9cdfSJim Ingham 5903a0b9cdfSJim Ingham if (wait_name == NULL) 5913a0b9cdfSJim Ingham { 5923a0b9cdfSJim Ingham result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 5933a0b9cdfSJim Ingham result.SetStatus (eReturnStatusFailed); 5943a0b9cdfSJim Ingham return false; 5953a0b9cdfSJim Ingham } 5963a0b9cdfSJim Ingham 597a7015092SGreg Clayton m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 5983a0b9cdfSJim Ingham error = process->Attach (wait_name, m_options.waitfor); 5995aee162fSJim Ingham if (error.Success()) 6005aee162fSJim Ingham { 6015aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6025aee162fSJim Ingham } 6035aee162fSJim Ingham else 6045aee162fSJim Ingham { 6055aee162fSJim Ingham result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 6063a0b9cdfSJim Ingham wait_name, 6075aee162fSJim Ingham error.AsCString()); 6085aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6095aee162fSJim Ingham return false; 6105aee162fSJim Ingham } 6115aee162fSJim Ingham } 6125aee162fSJim Ingham else 6135aee162fSJim Ingham { 6145aee162fSJim Ingham // If the process was specified by name look it up, so we can warn if there are multiple 6155aee162fSJim Ingham // processes with this pid. 6165aee162fSJim Ingham 6173a0b9cdfSJim Ingham if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 6185aee162fSJim Ingham { 6195aee162fSJim Ingham std::vector<lldb::pid_t> pids; 6205aee162fSJim Ingham StringList matches; 6215aee162fSJim Ingham 6223a0b9cdfSJim Ingham process->ListProcessesMatchingName(wait_name, matches, pids); 6235aee162fSJim Ingham if (matches.GetSize() > 1) 6245aee162fSJim Ingham { 6253a0b9cdfSJim Ingham result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 6265aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6275aee162fSJim Ingham return false; 6285aee162fSJim Ingham } 6295aee162fSJim Ingham else if (matches.GetSize() == 0) 6305aee162fSJim Ingham { 6313a0b9cdfSJim Ingham result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 6325aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6335aee162fSJim Ingham return false; 6345aee162fSJim Ingham } 6355aee162fSJim Ingham else 6365aee162fSJim Ingham { 6375aee162fSJim Ingham attach_pid = pids[0]; 6385aee162fSJim Ingham } 6395aee162fSJim Ingham 6405aee162fSJim Ingham } 6415aee162fSJim Ingham 6425aee162fSJim Ingham if (attach_pid != LLDB_INVALID_PROCESS_ID) 6435aee162fSJim Ingham { 6445aee162fSJim Ingham error = process->Attach (attach_pid); 6455aee162fSJim Ingham if (error.Success()) 6465aee162fSJim Ingham { 6475aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6485aee162fSJim Ingham } 6495aee162fSJim Ingham else 6505aee162fSJim Ingham { 6515aee162fSJim Ingham result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 6525aee162fSJim Ingham attach_pid, 6535aee162fSJim Ingham error.AsCString()); 6545aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6555aee162fSJim Ingham } 6565aee162fSJim Ingham } 6575aee162fSJim Ingham else 6585aee162fSJim Ingham { 6595aee162fSJim Ingham result.AppendErrorWithFormat ("No PID specified for attach\n", 6605aee162fSJim Ingham attach_pid, 6615aee162fSJim Ingham error.AsCString()); 6625aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6635aee162fSJim Ingham 6645aee162fSJim Ingham } 6655aee162fSJim Ingham } 6665aee162fSJim Ingham } 6675aee162fSJim Ingham } 6685aee162fSJim Ingham 6695aee162fSJim Ingham if (result.Succeeded()) 6705aee162fSJim Ingham { 6715aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 6725aee162fSJim Ingham if (!old_exec_module_sp) 6735aee162fSJim Ingham { 6745aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6755aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 6765aee162fSJim Ingham 6775aee162fSJim Ingham result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 6785aee162fSJim Ingham new_path); 6795aee162fSJim Ingham } 6805aee162fSJim Ingham else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 6815aee162fSJim Ingham { 6825aee162fSJim Ingham char old_path[PATH_MAX + 1]; 6835aee162fSJim Ingham char new_path[PATH_MAX + 1]; 6845aee162fSJim Ingham 6855aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 6865aee162fSJim Ingham target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 6875aee162fSJim Ingham 6885aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6895aee162fSJim Ingham old_path, new_path); 6905aee162fSJim Ingham } 6915aee162fSJim Ingham 6925aee162fSJim Ingham if (!old_arch_spec.IsValid()) 6935aee162fSJim Ingham { 6945aee162fSJim Ingham result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 6955aee162fSJim Ingham } 6965aee162fSJim Ingham else if (old_arch_spec != target->GetArchitecture()) 6975aee162fSJim Ingham { 6985aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 6995aee162fSJim Ingham old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 7005aee162fSJim Ingham } 7015aee162fSJim Ingham } 7025aee162fSJim Ingham return result.Succeeded(); 7035aee162fSJim Ingham } 7045aee162fSJim Ingham 7055aee162fSJim Ingham Options * 7065aee162fSJim Ingham GetOptions () 7075aee162fSJim Ingham { 7085aee162fSJim Ingham return &m_options; 7095aee162fSJim Ingham } 7105aee162fSJim Ingham 71130fdc8d8SChris Lattner protected: 71230fdc8d8SChris Lattner 71330fdc8d8SChris Lattner CommandOptions m_options; 71430fdc8d8SChris Lattner }; 71530fdc8d8SChris Lattner 71630fdc8d8SChris Lattner 71730fdc8d8SChris Lattner lldb::OptionDefinition 71830fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 71930fdc8d8SChris Lattner { 720deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 721deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 722deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 723deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 724deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 72530fdc8d8SChris Lattner }; 72630fdc8d8SChris Lattner 72730fdc8d8SChris Lattner //------------------------------------------------------------------------- 72830fdc8d8SChris Lattner // CommandObjectProcessContinue 72930fdc8d8SChris Lattner //------------------------------------------------------------------------- 73030fdc8d8SChris Lattner 73130fdc8d8SChris Lattner class CommandObjectProcessContinue : public CommandObject 73230fdc8d8SChris Lattner { 73330fdc8d8SChris Lattner public: 73430fdc8d8SChris Lattner 735a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 736a7015092SGreg Clayton CommandObject (interpreter, 737a7015092SGreg Clayton "process continue", 738e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 73930fdc8d8SChris Lattner "process continue", 74030fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 74130fdc8d8SChris Lattner { 74230fdc8d8SChris Lattner } 74330fdc8d8SChris Lattner 74430fdc8d8SChris Lattner 74530fdc8d8SChris Lattner ~CommandObjectProcessContinue () 74630fdc8d8SChris Lattner { 74730fdc8d8SChris Lattner } 74830fdc8d8SChris Lattner 74930fdc8d8SChris Lattner bool 750a7015092SGreg Clayton Execute (Args& command, 75130fdc8d8SChris Lattner CommandReturnObject &result) 75230fdc8d8SChris Lattner { 753a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 754a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 75530fdc8d8SChris Lattner 75630fdc8d8SChris Lattner if (process == NULL) 75730fdc8d8SChris Lattner { 75830fdc8d8SChris Lattner result.AppendError ("no process to continue"); 75930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 76030fdc8d8SChris Lattner return false; 76130fdc8d8SChris Lattner } 76230fdc8d8SChris Lattner 76330fdc8d8SChris Lattner StateType state = process->GetState(); 76430fdc8d8SChris Lattner if (state == eStateStopped) 76530fdc8d8SChris Lattner { 76630fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 76730fdc8d8SChris Lattner { 76830fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 76930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 77030fdc8d8SChris Lattner return false; 77130fdc8d8SChris Lattner } 77230fdc8d8SChris Lattner 77330fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 77430fdc8d8SChris Lattner 77530fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 77630fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 77730fdc8d8SChris Lattner { 77830fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 77930fdc8d8SChris Lattner } 78030fdc8d8SChris Lattner 78130fdc8d8SChris Lattner Error error(process->Resume()); 78230fdc8d8SChris Lattner if (error.Success()) 78330fdc8d8SChris Lattner { 78419388cfcSGreg Clayton result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 78530fdc8d8SChris Lattner if (synchronous_execution) 78630fdc8d8SChris Lattner { 787b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 78830fdc8d8SChris Lattner 78930fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 79030fdc8d8SChris Lattner result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 79130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 79230fdc8d8SChris Lattner } 79330fdc8d8SChris Lattner else 79430fdc8d8SChris Lattner { 79530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 79630fdc8d8SChris Lattner } 79730fdc8d8SChris Lattner } 79830fdc8d8SChris Lattner else 79930fdc8d8SChris Lattner { 80030fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 80130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 80230fdc8d8SChris Lattner } 80330fdc8d8SChris Lattner } 80430fdc8d8SChris Lattner else 80530fdc8d8SChris Lattner { 80630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 80730fdc8d8SChris Lattner StateAsCString(state)); 80830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 80930fdc8d8SChris Lattner } 81030fdc8d8SChris Lattner return result.Succeeded(); 81130fdc8d8SChris Lattner } 81230fdc8d8SChris Lattner }; 81330fdc8d8SChris Lattner 81430fdc8d8SChris Lattner //------------------------------------------------------------------------- 81530fdc8d8SChris Lattner // CommandObjectProcessDetach 81630fdc8d8SChris Lattner //------------------------------------------------------------------------- 81730fdc8d8SChris Lattner 81830fdc8d8SChris Lattner class CommandObjectProcessDetach : public CommandObject 81930fdc8d8SChris Lattner { 82030fdc8d8SChris Lattner public: 82130fdc8d8SChris Lattner 822a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 823a7015092SGreg Clayton CommandObject (interpreter, 824a7015092SGreg Clayton "process detach", 825e3d26315SCaroline Tice "Detach from the current process being debugged.", 82630fdc8d8SChris Lattner "process detach", 82730fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 82830fdc8d8SChris Lattner { 82930fdc8d8SChris Lattner } 83030fdc8d8SChris Lattner 83130fdc8d8SChris Lattner ~CommandObjectProcessDetach () 83230fdc8d8SChris Lattner { 83330fdc8d8SChris Lattner } 83430fdc8d8SChris Lattner 83530fdc8d8SChris Lattner bool 836a7015092SGreg Clayton Execute (Args& command, 83730fdc8d8SChris Lattner CommandReturnObject &result) 83830fdc8d8SChris Lattner { 839a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 84030fdc8d8SChris Lattner if (process == NULL) 84130fdc8d8SChris Lattner { 84230fdc8d8SChris Lattner result.AppendError ("must have a valid process in order to detach"); 84330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 84430fdc8d8SChris Lattner return false; 84530fdc8d8SChris Lattner } 84630fdc8d8SChris Lattner 84730fdc8d8SChris Lattner Error error (process->Detach()); 84830fdc8d8SChris Lattner if (error.Success()) 84930fdc8d8SChris Lattner { 85030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 85130fdc8d8SChris Lattner } 85230fdc8d8SChris Lattner else 85330fdc8d8SChris Lattner { 85430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 85530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 85630fdc8d8SChris Lattner return false; 85730fdc8d8SChris Lattner } 85830fdc8d8SChris Lattner return result.Succeeded(); 85930fdc8d8SChris Lattner } 86030fdc8d8SChris Lattner }; 86130fdc8d8SChris Lattner 86230fdc8d8SChris Lattner //------------------------------------------------------------------------- 86330fdc8d8SChris Lattner // CommandObjectProcessSignal 86430fdc8d8SChris Lattner //------------------------------------------------------------------------- 86530fdc8d8SChris Lattner 86630fdc8d8SChris Lattner class CommandObjectProcessSignal : public CommandObject 86730fdc8d8SChris Lattner { 86830fdc8d8SChris Lattner public: 86930fdc8d8SChris Lattner 870a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 871a7015092SGreg Clayton CommandObject (interpreter, 872a7015092SGreg Clayton "process signal", 873e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 874405fe67fSCaroline Tice NULL) 87530fdc8d8SChris Lattner { 876405fe67fSCaroline Tice CommandArgumentEntry arg; 877405fe67fSCaroline Tice CommandArgumentData signal_arg; 878405fe67fSCaroline Tice 879405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 880*c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 881405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 882405fe67fSCaroline Tice 883405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 884405fe67fSCaroline Tice arg.push_back (signal_arg); 885405fe67fSCaroline Tice 886405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 887405fe67fSCaroline Tice m_arguments.push_back (arg); 88830fdc8d8SChris Lattner } 88930fdc8d8SChris Lattner 89030fdc8d8SChris Lattner ~CommandObjectProcessSignal () 89130fdc8d8SChris Lattner { 89230fdc8d8SChris Lattner } 89330fdc8d8SChris Lattner 89430fdc8d8SChris Lattner bool 895a7015092SGreg Clayton Execute (Args& command, 89630fdc8d8SChris Lattner CommandReturnObject &result) 89730fdc8d8SChris Lattner { 898a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 89930fdc8d8SChris Lattner if (process == NULL) 90030fdc8d8SChris Lattner { 90130fdc8d8SChris Lattner result.AppendError ("no process to signal"); 90230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 90330fdc8d8SChris Lattner return false; 90430fdc8d8SChris Lattner } 90530fdc8d8SChris Lattner 90630fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 90730fdc8d8SChris Lattner { 908237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 909237cd906SGreg Clayton 910237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 911237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 912237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 913237cd906SGreg Clayton else 914237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 915237cd906SGreg Clayton 916237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 91730fdc8d8SChris Lattner { 91830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 91930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 92030fdc8d8SChris Lattner } 92130fdc8d8SChris Lattner else 92230fdc8d8SChris Lattner { 92330fdc8d8SChris Lattner Error error (process->Signal (signo)); 92430fdc8d8SChris Lattner if (error.Success()) 92530fdc8d8SChris Lattner { 92630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 92730fdc8d8SChris Lattner } 92830fdc8d8SChris Lattner else 92930fdc8d8SChris Lattner { 93030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 93130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 93230fdc8d8SChris Lattner } 93330fdc8d8SChris Lattner } 93430fdc8d8SChris Lattner } 93530fdc8d8SChris Lattner else 93630fdc8d8SChris Lattner { 93730fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 93830fdc8d8SChris Lattner m_cmd_syntax.c_str()); 93930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 94030fdc8d8SChris Lattner } 94130fdc8d8SChris Lattner return result.Succeeded(); 94230fdc8d8SChris Lattner } 94330fdc8d8SChris Lattner }; 94430fdc8d8SChris Lattner 94530fdc8d8SChris Lattner 94630fdc8d8SChris Lattner //------------------------------------------------------------------------- 94730fdc8d8SChris Lattner // CommandObjectProcessInterrupt 94830fdc8d8SChris Lattner //------------------------------------------------------------------------- 94930fdc8d8SChris Lattner 95030fdc8d8SChris Lattner class CommandObjectProcessInterrupt : public CommandObject 95130fdc8d8SChris Lattner { 95230fdc8d8SChris Lattner public: 95330fdc8d8SChris Lattner 95430fdc8d8SChris Lattner 955a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 956a7015092SGreg Clayton CommandObject (interpreter, 957a7015092SGreg Clayton "process interrupt", 958e3d26315SCaroline Tice "Interrupt the current process being debugged.", 95930fdc8d8SChris Lattner "process interrupt", 96030fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 96130fdc8d8SChris Lattner { 96230fdc8d8SChris Lattner } 96330fdc8d8SChris Lattner 96430fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 96530fdc8d8SChris Lattner { 96630fdc8d8SChris Lattner } 96730fdc8d8SChris Lattner 96830fdc8d8SChris Lattner bool 969a7015092SGreg Clayton Execute (Args& command, 97030fdc8d8SChris Lattner CommandReturnObject &result) 97130fdc8d8SChris Lattner { 972a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 97330fdc8d8SChris Lattner if (process == NULL) 97430fdc8d8SChris Lattner { 97530fdc8d8SChris Lattner result.AppendError ("no process to halt"); 97630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 97730fdc8d8SChris Lattner return false; 97830fdc8d8SChris Lattner } 97930fdc8d8SChris Lattner 98030fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 98130fdc8d8SChris Lattner { 98230fdc8d8SChris Lattner Error error(process->Halt ()); 98330fdc8d8SChris Lattner if (error.Success()) 98430fdc8d8SChris Lattner { 98530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 98630fdc8d8SChris Lattner 98730fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 98830fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 98930fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 99030fdc8d8SChris Lattner } 99130fdc8d8SChris Lattner else 99230fdc8d8SChris Lattner { 99330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 99430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 99530fdc8d8SChris Lattner } 99630fdc8d8SChris Lattner } 99730fdc8d8SChris Lattner else 99830fdc8d8SChris Lattner { 99930fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 100030fdc8d8SChris Lattner m_cmd_name.c_str(), 100130fdc8d8SChris Lattner m_cmd_syntax.c_str()); 100230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 100330fdc8d8SChris Lattner } 100430fdc8d8SChris Lattner return result.Succeeded(); 100530fdc8d8SChris Lattner } 100630fdc8d8SChris Lattner }; 100730fdc8d8SChris Lattner 100830fdc8d8SChris Lattner //------------------------------------------------------------------------- 100930fdc8d8SChris Lattner // CommandObjectProcessKill 101030fdc8d8SChris Lattner //------------------------------------------------------------------------- 101130fdc8d8SChris Lattner 101230fdc8d8SChris Lattner class CommandObjectProcessKill : public CommandObject 101330fdc8d8SChris Lattner { 101430fdc8d8SChris Lattner public: 101530fdc8d8SChris Lattner 1016a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 1017a7015092SGreg Clayton CommandObject (interpreter, 1018a7015092SGreg Clayton "process kill", 1019e3d26315SCaroline Tice "Terminate the current process being debugged.", 102030fdc8d8SChris Lattner "process kill", 102130fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 102230fdc8d8SChris Lattner { 102330fdc8d8SChris Lattner } 102430fdc8d8SChris Lattner 102530fdc8d8SChris Lattner ~CommandObjectProcessKill () 102630fdc8d8SChris Lattner { 102730fdc8d8SChris Lattner } 102830fdc8d8SChris Lattner 102930fdc8d8SChris Lattner bool 1030a7015092SGreg Clayton Execute (Args& command, 103130fdc8d8SChris Lattner CommandReturnObject &result) 103230fdc8d8SChris Lattner { 1033a7015092SGreg Clayton Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 103430fdc8d8SChris Lattner if (process == NULL) 103530fdc8d8SChris Lattner { 103630fdc8d8SChris Lattner result.AppendError ("no process to kill"); 103730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 103830fdc8d8SChris Lattner return false; 103930fdc8d8SChris Lattner } 104030fdc8d8SChris Lattner 104130fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 104230fdc8d8SChris Lattner { 104330fdc8d8SChris Lattner Error error (process->Destroy()); 104430fdc8d8SChris Lattner if (error.Success()) 104530fdc8d8SChris Lattner { 104630fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 104730fdc8d8SChris Lattner } 104830fdc8d8SChris Lattner else 104930fdc8d8SChris Lattner { 105030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 105130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 105230fdc8d8SChris Lattner } 105330fdc8d8SChris Lattner } 105430fdc8d8SChris Lattner else 105530fdc8d8SChris Lattner { 105630fdc8d8SChris Lattner result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 105730fdc8d8SChris Lattner m_cmd_name.c_str(), 105830fdc8d8SChris Lattner m_cmd_syntax.c_str()); 105930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 106030fdc8d8SChris Lattner } 106130fdc8d8SChris Lattner return result.Succeeded(); 106230fdc8d8SChris Lattner } 106330fdc8d8SChris Lattner }; 106430fdc8d8SChris Lattner 106530fdc8d8SChris Lattner //------------------------------------------------------------------------- 10664b9bea87SJim Ingham // CommandObjectProcessStatus 10674b9bea87SJim Ingham //------------------------------------------------------------------------- 10684b9bea87SJim Ingham class CommandObjectProcessStatus : public CommandObject 10694b9bea87SJim Ingham { 10704b9bea87SJim Ingham public: 1071a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1072a7015092SGreg Clayton CommandObject (interpreter, 1073a7015092SGreg Clayton "process status", 1074e3d26315SCaroline Tice "Show the current status and location of executing process.", 1075e3d26315SCaroline Tice "process status", 10764b9bea87SJim Ingham 0) 10774b9bea87SJim Ingham { 10784b9bea87SJim Ingham } 10794b9bea87SJim Ingham 10804b9bea87SJim Ingham ~CommandObjectProcessStatus() 10814b9bea87SJim Ingham { 10824b9bea87SJim Ingham } 10834b9bea87SJim Ingham 10844b9bea87SJim Ingham 10854b9bea87SJim Ingham bool 10864b9bea87SJim Ingham Execute 10874b9bea87SJim Ingham ( 10884b9bea87SJim Ingham Args& command, 10894b9bea87SJim Ingham CommandReturnObject &result 10904b9bea87SJim Ingham ) 10914b9bea87SJim Ingham { 10924b9bea87SJim Ingham StreamString &output_stream = result.GetOutputStream(); 10934b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1094a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 10954b9bea87SJim Ingham if (exe_ctx.process) 10964b9bea87SJim Ingham { 10974b9bea87SJim Ingham const StateType state = exe_ctx.process->GetState(); 10984b9bea87SJim Ingham if (StateIsStoppedState(state)) 10994b9bea87SJim Ingham { 11004b9bea87SJim Ingham if (state == eStateExited) 11014b9bea87SJim Ingham { 11024b9bea87SJim Ingham int exit_status = exe_ctx.process->GetExitStatus(); 11034b9bea87SJim Ingham const char *exit_description = exe_ctx.process->GetExitDescription(); 11044b9bea87SJim Ingham output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 11054b9bea87SJim Ingham exe_ctx.process->GetID(), 11064b9bea87SJim Ingham exit_status, 11074b9bea87SJim Ingham exit_status, 11084b9bea87SJim Ingham exit_description ? exit_description : ""); 11094b9bea87SJim Ingham } 11104b9bea87SJim Ingham else 11114b9bea87SJim Ingham { 11124b9bea87SJim Ingham output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 11134b9bea87SJim Ingham if (exe_ctx.thread == NULL) 11144b9bea87SJim Ingham exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 11154b9bea87SJim Ingham if (exe_ctx.thread != NULL) 11164b9bea87SJim Ingham { 1117a7015092SGreg Clayton DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 11184b9bea87SJim Ingham } 11194b9bea87SJim Ingham else 11204b9bea87SJim Ingham { 11214b9bea87SJim Ingham result.AppendError ("No valid thread found in current process."); 11224b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 11234b9bea87SJim Ingham } 11244b9bea87SJim Ingham } 11254b9bea87SJim Ingham } 11264b9bea87SJim Ingham else 11274b9bea87SJim Ingham { 11284b9bea87SJim Ingham output_stream.Printf ("Process %d is running.\n", 11294b9bea87SJim Ingham exe_ctx.process->GetID()); 11304b9bea87SJim Ingham } 11314b9bea87SJim Ingham } 11324b9bea87SJim Ingham else 11334b9bea87SJim Ingham { 11344b9bea87SJim Ingham result.AppendError ("No current location or status available."); 11354b9bea87SJim Ingham result.SetStatus (eReturnStatusFailed); 11364b9bea87SJim Ingham } 11374b9bea87SJim Ingham return result.Succeeded(); 11384b9bea87SJim Ingham } 11394b9bea87SJim Ingham }; 11404b9bea87SJim Ingham 11414b9bea87SJim Ingham //------------------------------------------------------------------------- 114235731357SCaroline Tice // CommandObjectProcessHandle 114335731357SCaroline Tice //------------------------------------------------------------------------- 114435731357SCaroline Tice 114535731357SCaroline Tice class CommandObjectProcessHandle : public CommandObject 114635731357SCaroline Tice { 114735731357SCaroline Tice public: 114835731357SCaroline Tice 114935731357SCaroline Tice class CommandOptions : public Options 115035731357SCaroline Tice { 115135731357SCaroline Tice public: 115235731357SCaroline Tice 115335731357SCaroline Tice CommandOptions () : 115435731357SCaroline Tice Options () 115535731357SCaroline Tice { 115635731357SCaroline Tice ResetOptionValues (); 115735731357SCaroline Tice } 115835731357SCaroline Tice 115935731357SCaroline Tice ~CommandOptions () 116035731357SCaroline Tice { 116135731357SCaroline Tice } 116235731357SCaroline Tice 116335731357SCaroline Tice Error 116435731357SCaroline Tice SetOptionValue (int option_idx, const char *option_arg) 116535731357SCaroline Tice { 116635731357SCaroline Tice Error error; 116735731357SCaroline Tice char short_option = (char) m_getopt_table[option_idx].val; 116835731357SCaroline Tice 116935731357SCaroline Tice switch (short_option) 117035731357SCaroline Tice { 117135731357SCaroline Tice case 's': 117235731357SCaroline Tice stop = option_arg; 117335731357SCaroline Tice break; 117435731357SCaroline Tice case 'n': 117535731357SCaroline Tice notify = option_arg; 117635731357SCaroline Tice break; 117735731357SCaroline Tice case 'p': 117835731357SCaroline Tice pass = option_arg; 117935731357SCaroline Tice break; 118035731357SCaroline Tice default: 118135731357SCaroline Tice error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 118235731357SCaroline Tice break; 118335731357SCaroline Tice } 118435731357SCaroline Tice return error; 118535731357SCaroline Tice } 118635731357SCaroline Tice 118735731357SCaroline Tice void 118835731357SCaroline Tice ResetOptionValues () 118935731357SCaroline Tice { 119035731357SCaroline Tice Options::ResetOptionValues(); 119135731357SCaroline Tice stop.clear(); 119235731357SCaroline Tice notify.clear(); 119335731357SCaroline Tice pass.clear(); 119435731357SCaroline Tice } 119535731357SCaroline Tice 119635731357SCaroline Tice const lldb::OptionDefinition* 119735731357SCaroline Tice GetDefinitions () 119835731357SCaroline Tice { 119935731357SCaroline Tice return g_option_table; 120035731357SCaroline Tice } 120135731357SCaroline Tice 120235731357SCaroline Tice // Options table: Required for subclasses of Options. 120335731357SCaroline Tice 120435731357SCaroline Tice static lldb::OptionDefinition g_option_table[]; 120535731357SCaroline Tice 120635731357SCaroline Tice // Instance variables to hold the values for command options. 120735731357SCaroline Tice 120835731357SCaroline Tice std::string stop; 120935731357SCaroline Tice std::string notify; 121035731357SCaroline Tice std::string pass; 121135731357SCaroline Tice }; 121235731357SCaroline Tice 121335731357SCaroline Tice 121435731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 121535731357SCaroline Tice CommandObject (interpreter, 121635731357SCaroline Tice "process handle", 121710ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 121835731357SCaroline Tice NULL) 121935731357SCaroline Tice { 122010ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 122135731357SCaroline Tice CommandArgumentEntry arg; 1222*c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 122335731357SCaroline Tice 1224*c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1225*c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 122635731357SCaroline Tice 1227*c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 122835731357SCaroline Tice 122935731357SCaroline Tice m_arguments.push_back (arg); 123035731357SCaroline Tice } 123135731357SCaroline Tice 123235731357SCaroline Tice ~CommandObjectProcessHandle () 123335731357SCaroline Tice { 123435731357SCaroline Tice } 123535731357SCaroline Tice 123635731357SCaroline Tice Options * 123735731357SCaroline Tice GetOptions () 123835731357SCaroline Tice { 123935731357SCaroline Tice return &m_options; 124035731357SCaroline Tice } 124135731357SCaroline Tice 124235731357SCaroline Tice bool 124310ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 124435731357SCaroline Tice { 124535731357SCaroline Tice bool okay = true; 124635731357SCaroline Tice 124710ad7993SCaroline Tice bool success = false; 124810ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 124910ad7993SCaroline Tice 125010ad7993SCaroline Tice if (success && tmp_value) 125110ad7993SCaroline Tice real_value = 1; 125210ad7993SCaroline Tice else if (success && !tmp_value) 125310ad7993SCaroline Tice real_value = 0; 125435731357SCaroline Tice else 125535731357SCaroline Tice { 125635731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 125710ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 125810ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 125935731357SCaroline Tice okay = false; 126035731357SCaroline Tice } 126135731357SCaroline Tice 126235731357SCaroline Tice return okay; 126335731357SCaroline Tice } 126435731357SCaroline Tice 126510ad7993SCaroline Tice void 126610ad7993SCaroline Tice PrintSignalHeader (Stream &str) 126710ad7993SCaroline Tice { 126810ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 126910ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 127010ad7993SCaroline Tice } 127110ad7993SCaroline Tice 127210ad7993SCaroline Tice void 127310ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 127410ad7993SCaroline Tice { 127510ad7993SCaroline Tice bool stop; 127610ad7993SCaroline Tice bool suppress; 127710ad7993SCaroline Tice bool notify; 127810ad7993SCaroline Tice 127910ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 128010ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 128110ad7993SCaroline Tice { 128210ad7993SCaroline Tice bool pass = !suppress; 128310ad7993SCaroline Tice str.Printf ("%s %s %s", 128410ad7993SCaroline Tice (pass ? "true " : "false"), 128510ad7993SCaroline Tice (stop ? "true " : "false"), 128610ad7993SCaroline Tice (notify ? "true " : "false")); 128710ad7993SCaroline Tice } 128810ad7993SCaroline Tice str.Printf ("\n"); 128910ad7993SCaroline Tice } 129010ad7993SCaroline Tice 129110ad7993SCaroline Tice void 129210ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 129310ad7993SCaroline Tice { 129410ad7993SCaroline Tice PrintSignalHeader (str); 129510ad7993SCaroline Tice 129610ad7993SCaroline Tice if (num_valid_signals > 0) 129710ad7993SCaroline Tice { 129810ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 129910ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 130010ad7993SCaroline Tice { 130110ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 130210ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 130310ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 130410ad7993SCaroline Tice } 130510ad7993SCaroline Tice } 130610ad7993SCaroline Tice else // Print info for ALL signals 130710ad7993SCaroline Tice { 130810ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 130910ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 131010ad7993SCaroline Tice { 131110ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 131210ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 131310ad7993SCaroline Tice } 131410ad7993SCaroline Tice } 131510ad7993SCaroline Tice } 131610ad7993SCaroline Tice 131735731357SCaroline Tice bool 131835731357SCaroline Tice Execute (Args &signal_args, CommandReturnObject &result) 131935731357SCaroline Tice { 132035731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 132135731357SCaroline Tice 132235731357SCaroline Tice if (!target_sp) 132335731357SCaroline Tice { 132435731357SCaroline Tice result.AppendError ("No current target;" 132535731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 132635731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 132735731357SCaroline Tice return false; 132835731357SCaroline Tice } 132935731357SCaroline Tice 133035731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 133135731357SCaroline Tice 133235731357SCaroline Tice if (!process_sp) 133335731357SCaroline Tice { 133435731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 133535731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 133635731357SCaroline Tice return false; 133735731357SCaroline Tice } 133835731357SCaroline Tice 133935731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 134035731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 134135731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 134235731357SCaroline Tice 134335731357SCaroline Tice if (! m_options.stop.empty() 134410ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 134535731357SCaroline Tice { 134635731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 134735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 134835731357SCaroline Tice return false; 134935731357SCaroline Tice } 135035731357SCaroline Tice 135135731357SCaroline Tice if (! m_options.notify.empty() 135210ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 135335731357SCaroline Tice { 135435731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 135535731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 135635731357SCaroline Tice return false; 135735731357SCaroline Tice } 135835731357SCaroline Tice 135935731357SCaroline Tice if (! m_options.pass.empty() 136010ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 136135731357SCaroline Tice { 136235731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 136335731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 136435731357SCaroline Tice return false; 136535731357SCaroline Tice } 136635731357SCaroline Tice 136735731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 136835731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 136935731357SCaroline Tice int num_signals_set = 0; 137035731357SCaroline Tice 137110ad7993SCaroline Tice if (num_args > 0) 137210ad7993SCaroline Tice { 137335731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 137435731357SCaroline Tice { 137535731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 137635731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 137735731357SCaroline Tice { 137810ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 137935731357SCaroline Tice // the value is either 0 or 1. 138035731357SCaroline Tice if (stop_action != -1) 138135731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 138235731357SCaroline Tice if (pass_action != -1) 138335731357SCaroline Tice { 138410ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 138510ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 138635731357SCaroline Tice } 138735731357SCaroline Tice if (notify_action != -1) 138835731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 138935731357SCaroline Tice ++num_signals_set; 139035731357SCaroline Tice } 139135731357SCaroline Tice else 139235731357SCaroline Tice { 139335731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 139435731357SCaroline Tice } 139535731357SCaroline Tice } 139610ad7993SCaroline Tice } 139710ad7993SCaroline Tice else 139810ad7993SCaroline Tice { 139910ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 140010ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 140110ad7993SCaroline Tice { 140210ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 140310ad7993SCaroline Tice { 140410ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 140510ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 140610ad7993SCaroline Tice { 140710ad7993SCaroline Tice if (notify_action != -1) 140810ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 140910ad7993SCaroline Tice if (stop_action != -1) 141010ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 141110ad7993SCaroline Tice if (pass_action != -1) 141210ad7993SCaroline Tice { 141310ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 141410ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 141510ad7993SCaroline Tice } 141610ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 141710ad7993SCaroline Tice } 141810ad7993SCaroline Tice } 141910ad7993SCaroline Tice } 142010ad7993SCaroline Tice } 142110ad7993SCaroline Tice 142210ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 142335731357SCaroline Tice 142435731357SCaroline Tice if (num_signals_set > 0) 142535731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 142635731357SCaroline Tice else 142735731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 142835731357SCaroline Tice 142935731357SCaroline Tice return result.Succeeded(); 143035731357SCaroline Tice } 143135731357SCaroline Tice 143235731357SCaroline Tice protected: 143335731357SCaroline Tice 143435731357SCaroline Tice CommandOptions m_options; 143535731357SCaroline Tice }; 143635731357SCaroline Tice 143735731357SCaroline Tice lldb::OptionDefinition 143835731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 143935731357SCaroline Tice { 144035731357SCaroline 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." }, 144135731357SCaroline 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." }, 144235731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 144335731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 144435731357SCaroline Tice }; 144535731357SCaroline Tice 144635731357SCaroline Tice //------------------------------------------------------------------------- 144730fdc8d8SChris Lattner // CommandObjectMultiwordProcess 144830fdc8d8SChris Lattner //------------------------------------------------------------------------- 144930fdc8d8SChris Lattner 14506611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1451a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1452a7015092SGreg Clayton "process", 145330fdc8d8SChris Lattner "A set of commands for operating on a process.", 145430fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 145530fdc8d8SChris Lattner { 1456a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1457a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1458a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1459a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1460a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 146135731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1462a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1463a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1464a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 146530fdc8d8SChris Lattner } 146630fdc8d8SChris Lattner 146730fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 146830fdc8d8SChris Lattner { 146930fdc8d8SChris Lattner } 147030fdc8d8SChris Lattner 1471