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 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner #include "CommandObjectProcess.h" 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner // C Includes 1530fdc8d8SChris Lattner // C++ Includes 1630fdc8d8SChris Lattner // Other libraries and framework includes 1730fdc8d8SChris Lattner // Project includes 180e41084aSJim Ingham #include "lldb/Breakpoint/Breakpoint.h" 190e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 200e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointSite.h" 2130fdc8d8SChris Lattner #include "lldb/Core/State.h" 221f746071SGreg Clayton #include "lldb/Core/Module.h" 237260f620SGreg Clayton #include "lldb/Host/Host.h" 240e41084aSJim Ingham #include "lldb/Interpreter/Args.h" 250e41084aSJim Ingham #include "lldb/Interpreter/Options.h" 2630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 28e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Process.h" 300e41084aSJim Ingham #include "lldb/Target/StopInfo.h" 3130fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3230fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner using namespace lldb; 3530fdc8d8SChris Lattner using namespace lldb_private; 3630fdc8d8SChris Lattner 37dcb1d856SJim Ingham class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed 38dcb1d856SJim Ingham { 39dcb1d856SJim Ingham public: 40dcb1d856SJim Ingham CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter, 41dcb1d856SJim Ingham const char *name, 42dcb1d856SJim Ingham const char *help, 43dcb1d856SJim Ingham const char *syntax, 44dcb1d856SJim Ingham uint32_t flags, 45dcb1d856SJim Ingham const char *new_process_action) : 46dcb1d856SJim Ingham CommandObjectParsed (interpreter, name, help, syntax, flags), 47dcb1d856SJim Ingham m_new_process_action (new_process_action) {} 48dcb1d856SJim Ingham 49dcb1d856SJim Ingham virtual ~CommandObjectProcessLaunchOrAttach () {} 50dcb1d856SJim Ingham protected: 51dcb1d856SJim Ingham bool 52dcb1d856SJim Ingham StopProcessIfNecessary (Process *&process, StateType &state, CommandReturnObject &result) 53dcb1d856SJim Ingham { 54dcb1d856SJim Ingham state = eStateInvalid; 55dcb1d856SJim Ingham if (process) 56dcb1d856SJim Ingham { 57dcb1d856SJim Ingham state = process->GetState(); 58dcb1d856SJim Ingham 59dcb1d856SJim Ingham if (process->IsAlive() && state != eStateConnected) 60dcb1d856SJim Ingham { 61dcb1d856SJim Ingham char message[1024]; 62dcb1d856SJim Ingham if (process->GetState() == eStateAttaching) 63dcb1d856SJim Ingham ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str()); 64dcb1d856SJim Ingham else if (process->GetShouldDetach()) 65dcb1d856SJim Ingham ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str()); 66dcb1d856SJim Ingham else 67dcb1d856SJim Ingham ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str()); 68dcb1d856SJim Ingham 69dcb1d856SJim Ingham if (!m_interpreter.Confirm (message, true)) 70dcb1d856SJim Ingham { 71dcb1d856SJim Ingham result.SetStatus (eReturnStatusFailed); 72dcb1d856SJim Ingham return false; 73dcb1d856SJim Ingham } 74dcb1d856SJim Ingham else 75dcb1d856SJim Ingham { 76dcb1d856SJim Ingham if (process->GetShouldDetach()) 77dcb1d856SJim Ingham { 78*acff8950SJim Ingham bool keep_stopped = false; 79*acff8950SJim Ingham Error detach_error (process->Detach(keep_stopped)); 80dcb1d856SJim Ingham if (detach_error.Success()) 81dcb1d856SJim Ingham { 82dcb1d856SJim Ingham result.SetStatus (eReturnStatusSuccessFinishResult); 83dcb1d856SJim Ingham process = NULL; 84dcb1d856SJim Ingham } 85dcb1d856SJim Ingham else 86dcb1d856SJim Ingham { 87dcb1d856SJim Ingham result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString()); 88dcb1d856SJim Ingham result.SetStatus (eReturnStatusFailed); 89dcb1d856SJim Ingham } 90dcb1d856SJim Ingham } 91dcb1d856SJim Ingham else 92dcb1d856SJim Ingham { 93dcb1d856SJim Ingham Error destroy_error (process->Destroy()); 94dcb1d856SJim Ingham if (destroy_error.Success()) 95dcb1d856SJim Ingham { 96dcb1d856SJim Ingham result.SetStatus (eReturnStatusSuccessFinishResult); 97dcb1d856SJim Ingham process = NULL; 98dcb1d856SJim Ingham } 99dcb1d856SJim Ingham else 100dcb1d856SJim Ingham { 101dcb1d856SJim Ingham result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString()); 102dcb1d856SJim Ingham result.SetStatus (eReturnStatusFailed); 103dcb1d856SJim Ingham } 104dcb1d856SJim Ingham } 105dcb1d856SJim Ingham } 106dcb1d856SJim Ingham } 107dcb1d856SJim Ingham } 108dcb1d856SJim Ingham return result.Succeeded(); 109dcb1d856SJim Ingham } 110dcb1d856SJim Ingham std::string m_new_process_action; 111dcb1d856SJim Ingham }; 11230fdc8d8SChris Lattner //------------------------------------------------------------------------- 11330fdc8d8SChris Lattner // CommandObjectProcessLaunch 11430fdc8d8SChris Lattner //------------------------------------------------------------------------- 1154bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch 116dcb1d856SJim Ingham class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach 11730fdc8d8SChris Lattner { 11830fdc8d8SChris Lattner public: 11930fdc8d8SChris Lattner 120a7015092SGreg Clayton CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 121dcb1d856SJim Ingham CommandObjectProcessLaunchOrAttach (interpreter, 122a7015092SGreg Clayton "process launch", 123e3d26315SCaroline Tice "Launch the executable in the debugger.", 124f9fc609fSGreg Clayton NULL, 125dcb1d856SJim Ingham eFlagRequiresTarget, 126dcb1d856SJim Ingham "restart"), 127eb0103f2SGreg Clayton m_options (interpreter) 12830fdc8d8SChris Lattner { 129405fe67fSCaroline Tice CommandArgumentEntry arg; 130405fe67fSCaroline Tice CommandArgumentData run_args_arg; 131405fe67fSCaroline Tice 132405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 133405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 134405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 135405fe67fSCaroline Tice 136405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 137405fe67fSCaroline Tice arg.push_back (run_args_arg); 138405fe67fSCaroline Tice 139405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 140405fe67fSCaroline Tice m_arguments.push_back (arg); 14130fdc8d8SChris Lattner } 14230fdc8d8SChris Lattner 14330fdc8d8SChris Lattner 14430fdc8d8SChris Lattner ~CommandObjectProcessLaunch () 14530fdc8d8SChris Lattner { 14630fdc8d8SChris Lattner } 14730fdc8d8SChris Lattner 148c7bece56SGreg Clayton virtual int 149e9ce62b6SJim Ingham HandleArgumentCompletion (Args &input, 150e9ce62b6SJim Ingham int &cursor_index, 151e9ce62b6SJim Ingham int &cursor_char_position, 152e9ce62b6SJim Ingham OptionElementVector &opt_element_vector, 153e9ce62b6SJim Ingham int match_start_point, 154e9ce62b6SJim Ingham int max_return_elements, 155e9ce62b6SJim Ingham bool &word_complete, 156e9ce62b6SJim Ingham StringList &matches) 157e9ce62b6SJim Ingham { 158e9ce62b6SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 159e9ce62b6SJim Ingham completion_str.erase (cursor_char_position); 160e9ce62b6SJim Ingham 161e9ce62b6SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 162e9ce62b6SJim Ingham CommandCompletions::eDiskFileCompletion, 163e9ce62b6SJim Ingham completion_str.c_str(), 164e9ce62b6SJim Ingham match_start_point, 165e9ce62b6SJim Ingham max_return_elements, 166e9ce62b6SJim Ingham NULL, 167e9ce62b6SJim Ingham word_complete, 168e9ce62b6SJim Ingham matches); 169e9ce62b6SJim Ingham return matches.GetSize(); 170e9ce62b6SJim Ingham } 171e9ce62b6SJim Ingham 17230fdc8d8SChris Lattner Options * 17330fdc8d8SChris Lattner GetOptions () 17430fdc8d8SChris Lattner { 17530fdc8d8SChris Lattner return &m_options; 17630fdc8d8SChris Lattner } 17730fdc8d8SChris Lattner 1785a988416SJim Ingham virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 1795a988416SJim Ingham { 1805a988416SJim Ingham // No repeat for "process launch"... 1815a988416SJim Ingham return ""; 1825a988416SJim Ingham } 1835a988416SJim Ingham 1845a988416SJim Ingham protected: 18530fdc8d8SChris Lattner bool 1865a988416SJim Ingham DoExecute (Args& launch_args, CommandReturnObject &result) 18730fdc8d8SChris Lattner { 1881d885966SGreg Clayton Debugger &debugger = m_interpreter.GetDebugger(); 1891d885966SGreg Clayton Target *target = debugger.GetSelectedTarget().get(); 1901d885966SGreg Clayton Error error; 19130fdc8d8SChris Lattner // If our listener is NULL, users aren't allows to launch 19230fdc8d8SChris Lattner char filename[PATH_MAX]; 193aa149cbdSGreg Clayton const Module *exe_module = target->GetExecutableModulePointer(); 19471337622SGreg Clayton 19571337622SGreg Clayton if (exe_module == NULL) 19671337622SGreg Clayton { 197effe5c95SGreg Clayton result.AppendError ("no file in target, create a debug target using the 'target create' command"); 19871337622SGreg Clayton result.SetStatus (eReturnStatusFailed); 19971337622SGreg Clayton return false; 20071337622SGreg Clayton } 20171337622SGreg Clayton 20271337622SGreg Clayton StateType state = eStateInvalid; 203f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 20471337622SGreg Clayton 205dcb1d856SJim Ingham if (!StopProcessIfNecessary(process, state, result)) 20630fdc8d8SChris Lattner return false; 20730fdc8d8SChris Lattner 20845392553SGreg Clayton const char *target_settings_argv0 = target->GetArg0(); 20945392553SGreg Clayton 21045392553SGreg Clayton exe_module->GetFileSpec().GetPath (filename, sizeof(filename)); 21145392553SGreg Clayton 21245392553SGreg Clayton if (target_settings_argv0) 21345392553SGreg Clayton { 21445392553SGreg Clayton m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0); 21545392553SGreg Clayton m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false); 21645392553SGreg Clayton } 21745392553SGreg Clayton else 21845392553SGreg Clayton { 21945392553SGreg Clayton m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); 22045392553SGreg Clayton } 22145392553SGreg Clayton 222144f3a9cSGreg Clayton if (launch_args.GetArgumentCount() == 0) 223144f3a9cSGreg Clayton { 22467cc0636SGreg Clayton Args target_setting_args; 22545392553SGreg Clayton if (target->GetRunArguments(target_setting_args)) 22667cc0636SGreg Clayton m_options.launch_info.GetArguments().AppendArguments (target_setting_args); 227144f3a9cSGreg Clayton } 228144f3a9cSGreg Clayton else 22930fdc8d8SChris Lattner { 23045392553SGreg Clayton m_options.launch_info.GetArguments().AppendArguments (launch_args); 23145392553SGreg Clayton 232162b597cSGreg Clayton // Save the arguments for subsequent runs in the current target. 233162b597cSGreg Clayton target->SetRunArguments (launch_args); 234982c9762SGreg Clayton } 2351d885966SGreg Clayton 236144f3a9cSGreg Clayton if (target->GetDisableASLR()) 237144f3a9cSGreg Clayton m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 238144f3a9cSGreg Clayton 239144f3a9cSGreg Clayton if (target->GetDisableSTDIO()) 240144f3a9cSGreg Clayton m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO); 241144f3a9cSGreg Clayton 242144f3a9cSGreg Clayton m_options.launch_info.GetFlags().Set (eLaunchFlagDebug); 243144f3a9cSGreg Clayton 244144f3a9cSGreg Clayton Args environment; 245144f3a9cSGreg Clayton target->GetEnvironmentAsArgs (environment); 246144f3a9cSGreg Clayton if (environment.GetArgumentCount() > 0) 247144f3a9cSGreg Clayton m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment); 248144f3a9cSGreg Clayton 2490161b49cSJim Ingham // Get the value of synchronous execution here. If you wait till after you have started to 2500161b49cSJim Ingham // run, then you could have hit a breakpoint, whose command might switch the value, and 2510161b49cSJim Ingham // then you'll pick up that incorrect value. 2520161b49cSJim Ingham bool synchronous_execution = m_interpreter.GetSynchronous (); 2530161b49cSJim Ingham 254ee95ed50SGreg Clayton // Finalize the file actions, and if none were given, default to opening 255ee95ed50SGreg Clayton // up a pseudo terminal 256ee95ed50SGreg Clayton const bool default_to_use_pty = true; 257ee95ed50SGreg Clayton m_options.launch_info.FinalizeFileActions (target, default_to_use_pty); 2581d885966SGreg Clayton 2591d885966SGreg Clayton if (state == eStateConnected) 2601d885966SGreg Clayton { 2611d885966SGreg Clayton if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)) 2621d885966SGreg Clayton { 2631d885966SGreg Clayton result.AppendWarning("can't launch in tty when launching through a remote connection"); 2641d885966SGreg Clayton m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY); 2651d885966SGreg Clayton } 2661d885966SGreg Clayton } 267dcb1d856SJim Ingham 268144f3a9cSGreg Clayton if (!m_options.launch_info.GetArchitecture().IsValid()) 269c9ed478aSGreg Clayton m_options.launch_info.GetArchitecture() = target->GetArchitecture(); 270c9ed478aSGreg Clayton 271c982b3d6SGreg Clayton PlatformSP platform_sp (target->GetPlatform()); 272c982b3d6SGreg Clayton 273c982b3d6SGreg Clayton if (platform_sp && platform_sp->CanDebugProcess ()) 274c982b3d6SGreg Clayton { 2751d885966SGreg Clayton process = target->GetPlatform()->DebugProcess (m_options.launch_info, 2761d885966SGreg Clayton debugger, 2771d885966SGreg Clayton target, 2781d885966SGreg Clayton debugger.GetListener(), 2791d885966SGreg Clayton error).get(); 280c982b3d6SGreg Clayton } 281c982b3d6SGreg Clayton else 282c982b3d6SGreg Clayton { 283c982b3d6SGreg Clayton const char *plugin_name = m_options.launch_info.GetProcessPluginName(); 284c3776bf2SGreg Clayton process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get(); 285c982b3d6SGreg Clayton if (process) 286c982b3d6SGreg Clayton error = process->Launch (m_options.launch_info); 287c982b3d6SGreg Clayton } 2881d885966SGreg Clayton 2891d885966SGreg Clayton if (process == NULL) 2901d885966SGreg Clayton { 291144f3a9cSGreg Clayton result.SetError (error, "failed to launch or debug process"); 2921d885966SGreg Clayton return false; 2931d885966SGreg Clayton } 294dcb1d856SJim Ingham 29530fdc8d8SChris Lattner 29630fdc8d8SChris Lattner if (error.Success()) 29730fdc8d8SChris Lattner { 29864195a2cSGreg Clayton const char *archname = exe_module->GetArchitecture().GetArchitectureName(); 29919388cfcSGreg Clayton 300d01b2953SDaniel Malea result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname); 30105faeb71SGreg Clayton result.SetDidChangeProcessState (true); 302982c9762SGreg Clayton if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false) 30330fdc8d8SChris Lattner { 30405faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 30530fdc8d8SChris Lattner StateType state = process->WaitForProcessToStop (NULL); 30630fdc8d8SChris Lattner 30730fdc8d8SChris Lattner if (state == eStateStopped) 30830fdc8d8SChris Lattner { 30905faeb71SGreg Clayton error = process->Resume(); 31005faeb71SGreg Clayton if (error.Success()) 31105faeb71SGreg Clayton { 31230fdc8d8SChris Lattner if (synchronous_execution) 31330fdc8d8SChris Lattner { 31405faeb71SGreg Clayton state = process->WaitForProcessToStop (NULL); 3152637f825SGreg Clayton const bool must_be_alive = true; 3162637f825SGreg Clayton if (!StateIsStoppedState(state, must_be_alive)) 317514487e8SGreg Clayton { 318144f3a9cSGreg Clayton result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state)); 319514487e8SGreg Clayton } 32030fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 32105faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 32205faeb71SGreg Clayton } 32305faeb71SGreg Clayton else 32405faeb71SGreg Clayton { 32505faeb71SGreg Clayton result.SetStatus (eReturnStatusSuccessContinuingNoResult); 32605faeb71SGreg Clayton } 32705faeb71SGreg Clayton } 328514487e8SGreg Clayton else 329514487e8SGreg Clayton { 330144f3a9cSGreg Clayton result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString()); 331514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 33230fdc8d8SChris Lattner } 33330fdc8d8SChris Lattner } 334514487e8SGreg Clayton else 335514487e8SGreg Clayton { 336144f3a9cSGreg Clayton result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state)); 337514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 338514487e8SGreg Clayton } 339514487e8SGreg Clayton } 340514487e8SGreg Clayton } 341514487e8SGreg Clayton else 342514487e8SGreg Clayton { 343197bacffSGreg Clayton result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString()); 344514487e8SGreg Clayton result.SetStatus (eReturnStatusFailed); 34530fdc8d8SChris Lattner } 34630fdc8d8SChris Lattner 34730fdc8d8SChris Lattner return result.Succeeded(); 34830fdc8d8SChris Lattner } 34930fdc8d8SChris Lattner 35030fdc8d8SChris Lattner protected: 351982c9762SGreg Clayton ProcessLaunchCommandOptions m_options; 35230fdc8d8SChris Lattner }; 35330fdc8d8SChris Lattner 35430fdc8d8SChris Lattner 355982c9762SGreg Clayton //#define SET1 LLDB_OPT_SET_1 356982c9762SGreg Clayton //#define SET2 LLDB_OPT_SET_2 357982c9762SGreg Clayton //#define SET3 LLDB_OPT_SET_3 358982c9762SGreg Clayton // 359982c9762SGreg Clayton //OptionDefinition 360982c9762SGreg Clayton //CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 361982c9762SGreg Clayton //{ 362982c9762SGreg Clayton //{ 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."}, 3633154255fSSean Callanan //{ SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."}, 3643154255fSSean Callanan //{ SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."}, 3653154255fSSean Callanan //{ SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."}, 366982c9762SGreg Clayton //{ SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 3673154255fSSean Callanan //{ SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypeDirectoryName, "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."}, 368982c9762SGreg Clayton //{ SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, 3693154255fSSean Callanan //{ SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."}, 370982c9762SGreg Clayton //{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 371982c9762SGreg Clayton //}; 372982c9762SGreg Clayton // 373982c9762SGreg Clayton //#undef SET1 374982c9762SGreg Clayton //#undef SET2 375982c9762SGreg Clayton //#undef SET3 37630fdc8d8SChris Lattner 37730fdc8d8SChris Lattner //------------------------------------------------------------------------- 37830fdc8d8SChris Lattner // CommandObjectProcessAttach 37930fdc8d8SChris Lattner //------------------------------------------------------------------------- 380bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach 381dcb1d856SJim Ingham class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach 38230fdc8d8SChris Lattner { 38330fdc8d8SChris Lattner public: 38430fdc8d8SChris Lattner 38530fdc8d8SChris Lattner class CommandOptions : public Options 38630fdc8d8SChris Lattner { 38730fdc8d8SChris Lattner public: 38830fdc8d8SChris Lattner 389eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 390eb0103f2SGreg Clayton Options(interpreter) 39130fdc8d8SChris Lattner { 392f6b8b581SGreg Clayton // Keep default values of all options in one place: OptionParsingStarting () 393f6b8b581SGreg Clayton OptionParsingStarting (); 39430fdc8d8SChris Lattner } 39530fdc8d8SChris Lattner 39630fdc8d8SChris Lattner ~CommandOptions () 39730fdc8d8SChris Lattner { 39830fdc8d8SChris Lattner } 39930fdc8d8SChris Lattner 40030fdc8d8SChris Lattner Error 401f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 40230fdc8d8SChris Lattner { 40330fdc8d8SChris Lattner Error error; 4043bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 40530fdc8d8SChris Lattner bool success = false; 40630fdc8d8SChris Lattner switch (short_option) 40730fdc8d8SChris Lattner { 408a95ce623SJohnny Chen case 'c': 409a95ce623SJohnny Chen attach_info.SetContinueOnceAttached(true); 410a95ce623SJohnny Chen break; 411a95ce623SJohnny Chen 41230fdc8d8SChris Lattner case 'p': 413144f3a9cSGreg Clayton { 414144f3a9cSGreg Clayton lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 41530fdc8d8SChris Lattner if (!success || pid == LLDB_INVALID_PROCESS_ID) 41630fdc8d8SChris Lattner { 41786edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg); 41830fdc8d8SChris Lattner } 419144f3a9cSGreg Clayton else 420144f3a9cSGreg Clayton { 421144f3a9cSGreg Clayton attach_info.SetProcessID (pid); 422144f3a9cSGreg Clayton } 423144f3a9cSGreg Clayton } 42430fdc8d8SChris Lattner break; 42530fdc8d8SChris Lattner 42630fdc8d8SChris Lattner case 'P': 427144f3a9cSGreg Clayton attach_info.SetProcessPluginName (option_arg); 42830fdc8d8SChris Lattner break; 42930fdc8d8SChris Lattner 43030fdc8d8SChris Lattner case 'n': 431144f3a9cSGreg Clayton attach_info.GetExecutableFile().SetFile(option_arg, false); 43230fdc8d8SChris Lattner break; 43330fdc8d8SChris Lattner 43430fdc8d8SChris Lattner case 'w': 435144f3a9cSGreg Clayton attach_info.SetWaitForLaunch(true); 43630fdc8d8SChris Lattner break; 43730fdc8d8SChris Lattner 438cd16df91SJim Ingham case 'i': 439cd16df91SJim Ingham attach_info.SetIgnoreExisting(false); 440cd16df91SJim Ingham break; 441cd16df91SJim Ingham 44230fdc8d8SChris Lattner default: 44386edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 44430fdc8d8SChris Lattner break; 44530fdc8d8SChris Lattner } 44630fdc8d8SChris Lattner return error; 44730fdc8d8SChris Lattner } 44830fdc8d8SChris Lattner 44930fdc8d8SChris Lattner void 450f6b8b581SGreg Clayton OptionParsingStarting () 45130fdc8d8SChris Lattner { 452144f3a9cSGreg Clayton attach_info.Clear(); 45330fdc8d8SChris Lattner } 45430fdc8d8SChris Lattner 455e0d378b3SGreg Clayton const OptionDefinition* 45630fdc8d8SChris Lattner GetDefinitions () 45730fdc8d8SChris Lattner { 45830fdc8d8SChris Lattner return g_option_table; 45930fdc8d8SChris Lattner } 46030fdc8d8SChris Lattner 4615aee162fSJim Ingham virtual bool 462eb0103f2SGreg Clayton HandleOptionArgumentCompletion (Args &input, 4635aee162fSJim Ingham int cursor_index, 4645aee162fSJim Ingham int char_pos, 4655aee162fSJim Ingham OptionElementVector &opt_element_vector, 4665aee162fSJim Ingham int opt_element_index, 4675aee162fSJim Ingham int match_start_point, 4685aee162fSJim Ingham int max_return_elements, 4695aee162fSJim Ingham bool &word_complete, 4705aee162fSJim Ingham StringList &matches) 4715aee162fSJim Ingham { 4725aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 4735aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 4745aee162fSJim Ingham 4755aee162fSJim Ingham // We are only completing the name option for now... 4765aee162fSJim Ingham 477e0d378b3SGreg Clayton const OptionDefinition *opt_defs = GetDefinitions(); 4785aee162fSJim Ingham if (opt_defs[opt_defs_index].short_option == 'n') 4795aee162fSJim Ingham { 4805aee162fSJim Ingham // Are we in the name? 4815aee162fSJim Ingham 4825aee162fSJim Ingham // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 4835aee162fSJim Ingham // use the default plugin. 4845aee162fSJim Ingham 4855aee162fSJim Ingham const char *partial_name = NULL; 4865aee162fSJim Ingham partial_name = input.GetArgumentAtIndex(opt_arg_pos); 4875aee162fSJim Ingham 4888b82f087SGreg Clayton PlatformSP platform_sp (m_interpreter.GetPlatform (true)); 489e996fd30SGreg Clayton if (platform_sp) 4905aee162fSJim Ingham { 4918b82f087SGreg Clayton ProcessInstanceInfoList process_infos; 4928b82f087SGreg Clayton ProcessInstanceInfoMatch match_info; 49332e0a750SGreg Clayton if (partial_name) 49432e0a750SGreg Clayton { 495144f3a9cSGreg Clayton match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false); 49632e0a750SGreg Clayton match_info.SetNameMatchType(eNameMatchStartsWith); 49732e0a750SGreg Clayton } 49832e0a750SGreg Clayton platform_sp->FindProcesses (match_info, process_infos); 499c7bece56SGreg Clayton const size_t num_matches = process_infos.GetSize(); 500e996fd30SGreg Clayton if (num_matches > 0) 501e996fd30SGreg Clayton { 502c7bece56SGreg Clayton for (size_t i=0; i<num_matches; ++i) 503e996fd30SGreg Clayton { 504e996fd30SGreg Clayton matches.AppendString (process_infos.GetProcessNameAtIndex(i), 505e996fd30SGreg Clayton process_infos.GetProcessNameLengthAtIndex(i)); 5065aee162fSJim Ingham } 5075aee162fSJim Ingham } 5085aee162fSJim Ingham } 5095aee162fSJim Ingham } 5105aee162fSJim Ingham 5115aee162fSJim Ingham return false; 5125aee162fSJim Ingham } 5135aee162fSJim Ingham 51430fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 51530fdc8d8SChris Lattner 516e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 51730fdc8d8SChris Lattner 51830fdc8d8SChris Lattner // Instance variables to hold the values for command options. 51930fdc8d8SChris Lattner 520144f3a9cSGreg Clayton ProcessAttachInfo attach_info; 52130fdc8d8SChris Lattner }; 52230fdc8d8SChris Lattner 523a7015092SGreg Clayton CommandObjectProcessAttach (CommandInterpreter &interpreter) : 524dcb1d856SJim Ingham CommandObjectProcessLaunchOrAttach (interpreter, 525a7015092SGreg Clayton "process attach", 526e3d26315SCaroline Tice "Attach to a process.", 527dcb1d856SJim Ingham "process attach <cmd-options>", 528dcb1d856SJim Ingham 0, 529dcb1d856SJim Ingham "attach"), 530eb0103f2SGreg Clayton m_options (interpreter) 5315aee162fSJim Ingham { 5325aee162fSJim Ingham } 5335aee162fSJim Ingham 5345aee162fSJim Ingham ~CommandObjectProcessAttach () 5355aee162fSJim Ingham { 5365aee162fSJim Ingham } 5375aee162fSJim Ingham 5385a988416SJim Ingham Options * 5395a988416SJim Ingham GetOptions () 5405a988416SJim Ingham { 5415a988416SJim Ingham return &m_options; 5425a988416SJim Ingham } 5435a988416SJim Ingham 5445a988416SJim Ingham protected: 5455aee162fSJim Ingham bool 5465a988416SJim Ingham DoExecute (Args& command, 5475aee162fSJim Ingham CommandReturnObject &result) 5485aee162fSJim Ingham { 549a7015092SGreg Clayton Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 55031412642SJim Ingham // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach 55131412642SJim Ingham // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop 55231412642SJim Ingham // ourselves here. 5535aee162fSJim Ingham 55471337622SGreg Clayton StateType state = eStateInvalid; 555dcb1d856SJim Ingham Process *process = m_exe_ctx.GetProcessPtr(); 556dcb1d856SJim Ingham 557dcb1d856SJim Ingham if (!StopProcessIfNecessary (process, state, result)) 5585aee162fSJim Ingham return false; 5595aee162fSJim Ingham 5605aee162fSJim Ingham if (target == NULL) 5615aee162fSJim Ingham { 5625aee162fSJim Ingham // If there isn't a current target create one. 5635aee162fSJim Ingham TargetSP new_target_sp; 5645aee162fSJim Ingham Error error; 5655aee162fSJim Ingham 566a7015092SGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 567a0ca6601SGreg Clayton NULL, 568cac9c5f9SGreg Clayton NULL, 5695aee162fSJim Ingham false, 570cac9c5f9SGreg Clayton NULL, // No platform options 5715aee162fSJim Ingham new_target_sp); 5725aee162fSJim Ingham target = new_target_sp.get(); 5735aee162fSJim Ingham if (target == NULL || error.Fail()) 5745aee162fSJim Ingham { 575b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 5765aee162fSJim Ingham return false; 5775aee162fSJim Ingham } 578a7015092SGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 5795aee162fSJim Ingham } 5805aee162fSJim Ingham 5815aee162fSJim Ingham // Record the old executable module, we want to issue a warning if the process of attaching changed the 5825aee162fSJim Ingham // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 5835aee162fSJim Ingham 5845aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 5855aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 5865aee162fSJim Ingham 5875aee162fSJim Ingham if (command.GetArgumentCount()) 5885aee162fSJim Ingham { 589fd54b368SJason Molenda result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 5905aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 5915aee162fSJim Ingham } 5925aee162fSJim Ingham else 5935aee162fSJim Ingham { 59471337622SGreg Clayton if (state != eStateConnected) 59571337622SGreg Clayton { 596144f3a9cSGreg Clayton const char *plugin_name = m_options.attach_info.GetProcessPluginName(); 597c3776bf2SGreg Clayton process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get(); 59871337622SGreg Clayton } 5995aee162fSJim Ingham 6005aee162fSJim Ingham if (process) 6015aee162fSJim Ingham { 6025aee162fSJim Ingham Error error; 603144f3a9cSGreg Clayton // If no process info was specified, then use the target executable 604144f3a9cSGreg Clayton // name as the process to attach to by default 605144f3a9cSGreg Clayton if (!m_options.attach_info.ProcessInfoSpecified ()) 6065aee162fSJim Ingham { 6073a0b9cdfSJim Ingham if (old_exec_module_sp) 608ad9e828cSGreg Clayton m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename(); 609144f3a9cSGreg Clayton 610144f3a9cSGreg Clayton if (!m_options.attach_info.ProcessInfoSpecified ()) 6113a0b9cdfSJim Ingham { 612144f3a9cSGreg Clayton error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option"); 6133a0b9cdfSJim Ingham } 6145aee162fSJim Ingham } 6153a0b9cdfSJim Ingham 616144f3a9cSGreg Clayton if (error.Success()) 6173a0b9cdfSJim Ingham { 618144f3a9cSGreg Clayton error = process->Attach (m_options.attach_info); 6193a0b9cdfSJim Ingham 6205aee162fSJim Ingham if (error.Success()) 6215aee162fSJim Ingham { 6225aee162fSJim Ingham result.SetStatus (eReturnStatusSuccessContinuingNoResult); 6235aee162fSJim Ingham } 6245aee162fSJim Ingham else 6255aee162fSJim Ingham { 626144f3a9cSGreg Clayton result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString()); 6275aee162fSJim Ingham result.SetStatus (eReturnStatusFailed); 6285aee162fSJim Ingham return false; 6295aee162fSJim Ingham } 630bb3a283bSJim Ingham // If we're synchronous, wait for the stopped event and report that. 631bb3a283bSJim Ingham // Otherwise just return. 632bb3a283bSJim Ingham // FIXME: in the async case it will now be possible to get to the command 633bb3a283bSJim Ingham // interpreter with a state eStateAttaching. Make sure we handle that correctly. 634bb3a283bSJim Ingham StateType state = process->WaitForProcessToStop (NULL); 635bb3a283bSJim Ingham 636bb3a283bSJim Ingham result.SetDidChangeProcessState (true); 637aa739093SJohnny Chen 638aa739093SJohnny Chen if (state == eStateStopped) 639aa739093SJohnny Chen { 640d01b2953SDaniel Malea result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 641bb3a283bSJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 642bb3a283bSJim Ingham } 643aa739093SJohnny Chen else 644aa739093SJohnny Chen { 645aa739093SJohnny Chen result.AppendError ("attach failed: process did not stop (no such process or permission problem?)"); 646cfc0935eSJim Ingham process->Destroy(); 647aa739093SJohnny Chen result.SetStatus (eReturnStatusFailed); 648aa739093SJohnny Chen return false; 649aa739093SJohnny Chen } 650aa739093SJohnny Chen } 6515aee162fSJim Ingham } 6525aee162fSJim Ingham } 6535aee162fSJim Ingham 6545aee162fSJim Ingham if (result.Succeeded()) 6555aee162fSJim Ingham { 6565aee162fSJim Ingham // Okay, we're done. Last step is to warn if the executable module has changed: 657513c26ceSGreg Clayton char new_path[PATH_MAX]; 658aa149cbdSGreg Clayton ModuleSP new_exec_module_sp (target->GetExecutableModule()); 6595aee162fSJim Ingham if (!old_exec_module_sp) 6605aee162fSJim Ingham { 661513c26ceSGreg Clayton // We might not have a module if we attached to a raw pid... 662aa149cbdSGreg Clayton if (new_exec_module_sp) 663513c26ceSGreg Clayton { 664aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 665513c26ceSGreg Clayton result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path); 666513c26ceSGreg Clayton } 6675aee162fSJim Ingham } 668aa149cbdSGreg Clayton else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec()) 6695aee162fSJim Ingham { 670513c26ceSGreg Clayton char old_path[PATH_MAX]; 6715aee162fSJim Ingham 6725aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX); 673aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX); 6745aee162fSJim Ingham 6755aee162fSJim Ingham result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 6765aee162fSJim Ingham old_path, new_path); 6775aee162fSJim Ingham } 6785aee162fSJim Ingham 6795aee162fSJim Ingham if (!old_arch_spec.IsValid()) 6805aee162fSJim Ingham { 681c1b1f1eaSGreg Clayton result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str()); 6825aee162fSJim Ingham } 683bf4b7be6SSean Callanan else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) 6845aee162fSJim Ingham { 6855aee162fSJim Ingham result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 686c1b1f1eaSGreg Clayton old_arch_spec.GetTriple().getTriple().c_str(), 687c1b1f1eaSGreg Clayton target->GetArchitecture().GetTriple().getTriple().c_str()); 6885aee162fSJim Ingham } 689a95ce623SJohnny Chen 690a95ce623SJohnny Chen // This supports the use-case scenario of immediately continuing the process once attached. 691a95ce623SJohnny Chen if (m_options.attach_info.GetContinueOnceAttached()) 6925bcaf583SSean Callanan m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); 6935aee162fSJim Ingham } 6945aee162fSJim Ingham return result.Succeeded(); 6955aee162fSJim Ingham } 6965aee162fSJim Ingham 69730fdc8d8SChris Lattner CommandOptions m_options; 69830fdc8d8SChris Lattner }; 69930fdc8d8SChris Lattner 70030fdc8d8SChris Lattner 701e0d378b3SGreg Clayton OptionDefinition 70230fdc8d8SChris Lattner CommandObjectProcessAttach::CommandOptions::g_option_table[] = 70330fdc8d8SChris Lattner { 704a95ce623SJohnny Chen { LLDB_OPT_SET_ALL, false, "continue",'c', no_argument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, 705deaab222SCaroline Tice { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 706deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 707deaab222SCaroline Tice { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 708cd16df91SJim Ingham { LLDB_OPT_SET_2, false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, 7094ce37abbSJohnny Chen { LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."}, 710deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 71130fdc8d8SChris Lattner }; 71230fdc8d8SChris Lattner 71330fdc8d8SChris Lattner //------------------------------------------------------------------------- 71430fdc8d8SChris Lattner // CommandObjectProcessContinue 71530fdc8d8SChris Lattner //------------------------------------------------------------------------- 716bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue 71730fdc8d8SChris Lattner 7185a988416SJim Ingham class CommandObjectProcessContinue : public CommandObjectParsed 71930fdc8d8SChris Lattner { 72030fdc8d8SChris Lattner public: 72130fdc8d8SChris Lattner 722a7015092SGreg Clayton CommandObjectProcessContinue (CommandInterpreter &interpreter) : 7235a988416SJim Ingham CommandObjectParsed (interpreter, 724a7015092SGreg Clayton "process continue", 725e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 72630fdc8d8SChris Lattner "process continue", 727f9fc609fSGreg Clayton eFlagRequiresProcess | 728f9fc609fSGreg Clayton eFlagTryTargetAPILock | 729f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 730f9fc609fSGreg Clayton eFlagProcessMustBePaused ), 7310e41084aSJim Ingham m_options(interpreter) 73230fdc8d8SChris Lattner { 73330fdc8d8SChris Lattner } 73430fdc8d8SChris Lattner 73530fdc8d8SChris Lattner 73630fdc8d8SChris Lattner ~CommandObjectProcessContinue () 73730fdc8d8SChris Lattner { 73830fdc8d8SChris Lattner } 73930fdc8d8SChris Lattner 7405a988416SJim Ingham protected: 7410e41084aSJim Ingham 7420e41084aSJim Ingham class CommandOptions : public Options 7430e41084aSJim Ingham { 7440e41084aSJim Ingham public: 7450e41084aSJim Ingham 7460e41084aSJim Ingham CommandOptions (CommandInterpreter &interpreter) : 7470e41084aSJim Ingham Options(interpreter) 7480e41084aSJim Ingham { 7490e41084aSJim Ingham // Keep default values of all options in one place: OptionParsingStarting () 7500e41084aSJim Ingham OptionParsingStarting (); 7510e41084aSJim Ingham } 7520e41084aSJim Ingham 7530e41084aSJim Ingham ~CommandOptions () 7540e41084aSJim Ingham { 7550e41084aSJim Ingham } 7560e41084aSJim Ingham 7570e41084aSJim Ingham Error 7580e41084aSJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 7590e41084aSJim Ingham { 7600e41084aSJim Ingham Error error; 7613bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 7620e41084aSJim Ingham bool success = false; 7630e41084aSJim Ingham switch (short_option) 7640e41084aSJim Ingham { 7650e41084aSJim Ingham case 'i': 7660e41084aSJim Ingham m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success); 7670e41084aSJim Ingham if (!success) 7680e41084aSJim Ingham error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg); 7690e41084aSJim Ingham break; 7700e41084aSJim Ingham 7710e41084aSJim Ingham default: 7720e41084aSJim Ingham error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 7730e41084aSJim Ingham break; 7740e41084aSJim Ingham } 7750e41084aSJim Ingham return error; 7760e41084aSJim Ingham } 7770e41084aSJim Ingham 7780e41084aSJim Ingham void 7790e41084aSJim Ingham OptionParsingStarting () 7800e41084aSJim Ingham { 7810e41084aSJim Ingham m_ignore = 0; 7820e41084aSJim Ingham } 7830e41084aSJim Ingham 7840e41084aSJim Ingham const OptionDefinition* 7850e41084aSJim Ingham GetDefinitions () 7860e41084aSJim Ingham { 7870e41084aSJim Ingham return g_option_table; 7880e41084aSJim Ingham } 7890e41084aSJim Ingham 7900e41084aSJim Ingham // Options table: Required for subclasses of Options. 7910e41084aSJim Ingham 7920e41084aSJim Ingham static OptionDefinition g_option_table[]; 7930e41084aSJim Ingham 7940e41084aSJim Ingham uint32_t m_ignore; 7950e41084aSJim Ingham }; 7960e41084aSJim Ingham 79730fdc8d8SChris Lattner bool 798f9fc609fSGreg Clayton DoExecute (Args& command, CommandReturnObject &result) 79930fdc8d8SChris Lattner { 800f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 801a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous (); 80230fdc8d8SChris Lattner StateType state = process->GetState(); 80330fdc8d8SChris Lattner if (state == eStateStopped) 80430fdc8d8SChris Lattner { 80530fdc8d8SChris Lattner if (command.GetArgumentCount() != 0) 80630fdc8d8SChris Lattner { 80730fdc8d8SChris Lattner result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 80830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 80930fdc8d8SChris Lattner return false; 81030fdc8d8SChris Lattner } 81130fdc8d8SChris Lattner 8120e41084aSJim Ingham if (m_options.m_ignore > 0) 8130e41084aSJim Ingham { 8140e41084aSJim Ingham ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread()); 8150e41084aSJim Ingham if (sel_thread_sp) 8160e41084aSJim Ingham { 8170e41084aSJim Ingham StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo(); 8180e41084aSJim Ingham if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint) 8190e41084aSJim Ingham { 820c7bece56SGreg Clayton lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue(); 8210e41084aSJim Ingham BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id)); 8220e41084aSJim Ingham if (bp_site_sp) 8230e41084aSJim Ingham { 824c7bece56SGreg Clayton const size_t num_owners = bp_site_sp->GetNumberOfOwners(); 825c7bece56SGreg Clayton for (size_t i = 0; i < num_owners; i++) 8260e41084aSJim Ingham { 8270e41084aSJim Ingham Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 8280e41084aSJim Ingham if (!bp_ref.IsInternal()) 8290e41084aSJim Ingham { 8300e41084aSJim Ingham bp_ref.SetIgnoreCount(m_options.m_ignore); 8310e41084aSJim Ingham } 8320e41084aSJim Ingham } 8330e41084aSJim Ingham } 8340e41084aSJim Ingham } 8350e41084aSJim Ingham } 8360e41084aSJim Ingham } 8370e41084aSJim Ingham 83841f2b940SJim Ingham { // Scope for thread list mutex: 83941f2b940SJim Ingham Mutex::Locker locker (process->GetThreadList().GetMutex()); 84030fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 84130fdc8d8SChris Lattner 84230fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 84330fdc8d8SChris Lattner for (uint32_t idx=0; idx<num_threads; ++idx) 84430fdc8d8SChris Lattner { 84530fdc8d8SChris Lattner process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 84630fdc8d8SChris Lattner } 84741f2b940SJim Ingham } 84830fdc8d8SChris Lattner 84930fdc8d8SChris Lattner Error error(process->Resume()); 85030fdc8d8SChris Lattner if (error.Success()) 85130fdc8d8SChris Lattner { 852d01b2953SDaniel Malea result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 85330fdc8d8SChris Lattner if (synchronous_execution) 85430fdc8d8SChris Lattner { 855b132097bSGreg Clayton state = process->WaitForProcessToStop (NULL); 85630fdc8d8SChris Lattner 85730fdc8d8SChris Lattner result.SetDidChangeProcessState (true); 858d01b2953SDaniel Malea result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); 85930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 86030fdc8d8SChris Lattner } 86130fdc8d8SChris Lattner else 86230fdc8d8SChris Lattner { 86330fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessContinuingNoResult); 86430fdc8d8SChris Lattner } 86530fdc8d8SChris Lattner } 86630fdc8d8SChris Lattner else 86730fdc8d8SChris Lattner { 86830fdc8d8SChris Lattner result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 86930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 87030fdc8d8SChris Lattner } 87130fdc8d8SChris Lattner } 87230fdc8d8SChris Lattner else 87330fdc8d8SChris Lattner { 87430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 87530fdc8d8SChris Lattner StateAsCString(state)); 87630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 87730fdc8d8SChris Lattner } 87830fdc8d8SChris Lattner return result.Succeeded(); 87930fdc8d8SChris Lattner } 8800e41084aSJim Ingham 8810e41084aSJim Ingham Options * 8820e41084aSJim Ingham GetOptions () 8830e41084aSJim Ingham { 8840e41084aSJim Ingham return &m_options; 8850e41084aSJim Ingham } 8860e41084aSJim Ingham 8870e41084aSJim Ingham CommandOptions m_options; 8880e41084aSJim Ingham 8890e41084aSJim Ingham }; 8900e41084aSJim Ingham 8910e41084aSJim Ingham OptionDefinition 8920e41084aSJim Ingham CommandObjectProcessContinue::CommandOptions::g_option_table[] = 8930e41084aSJim Ingham { 8940e41084aSJim Ingham { LLDB_OPT_SET_ALL, false, "ignore-count",'i', required_argument, NULL, 0, eArgTypeUnsignedInteger, 8950e41084aSJim Ingham "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."}, 8960e41084aSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 89730fdc8d8SChris Lattner }; 89830fdc8d8SChris Lattner 89930fdc8d8SChris Lattner //------------------------------------------------------------------------- 90030fdc8d8SChris Lattner // CommandObjectProcessDetach 90130fdc8d8SChris Lattner //------------------------------------------------------------------------- 902bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach 90330fdc8d8SChris Lattner 9045a988416SJim Ingham class CommandObjectProcessDetach : public CommandObjectParsed 90530fdc8d8SChris Lattner { 90630fdc8d8SChris Lattner public: 907*acff8950SJim Ingham class CommandOptions : public Options 908*acff8950SJim Ingham { 909*acff8950SJim Ingham public: 910*acff8950SJim Ingham 911*acff8950SJim Ingham CommandOptions (CommandInterpreter &interpreter) : 912*acff8950SJim Ingham Options (interpreter) 913*acff8950SJim Ingham { 914*acff8950SJim Ingham OptionParsingStarting (); 915*acff8950SJim Ingham } 916*acff8950SJim Ingham 917*acff8950SJim Ingham ~CommandOptions () 918*acff8950SJim Ingham { 919*acff8950SJim Ingham } 920*acff8950SJim Ingham 921*acff8950SJim Ingham Error 922*acff8950SJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 923*acff8950SJim Ingham { 924*acff8950SJim Ingham Error error; 925*acff8950SJim Ingham const int short_option = m_getopt_table[option_idx].val; 926*acff8950SJim Ingham 927*acff8950SJim Ingham switch (short_option) 928*acff8950SJim Ingham { 929*acff8950SJim Ingham case 's': 930*acff8950SJim Ingham bool tmp_result; 931*acff8950SJim Ingham bool success; 932*acff8950SJim Ingham tmp_result = Args::StringToBoolean(option_arg, false, &success); 933*acff8950SJim Ingham if (!success) 934*acff8950SJim Ingham error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg); 935*acff8950SJim Ingham else 936*acff8950SJim Ingham { 937*acff8950SJim Ingham if (tmp_result) 938*acff8950SJim Ingham m_keep_stopped = eLazyBoolYes; 939*acff8950SJim Ingham else 940*acff8950SJim Ingham m_keep_stopped = eLazyBoolNo; 941*acff8950SJim Ingham } 942*acff8950SJim Ingham break; 943*acff8950SJim Ingham default: 944*acff8950SJim Ingham error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 945*acff8950SJim Ingham break; 946*acff8950SJim Ingham } 947*acff8950SJim Ingham return error; 948*acff8950SJim Ingham } 949*acff8950SJim Ingham 950*acff8950SJim Ingham void 951*acff8950SJim Ingham OptionParsingStarting () 952*acff8950SJim Ingham { 953*acff8950SJim Ingham m_keep_stopped = eLazyBoolCalculate; 954*acff8950SJim Ingham } 955*acff8950SJim Ingham 956*acff8950SJim Ingham const OptionDefinition* 957*acff8950SJim Ingham GetDefinitions () 958*acff8950SJim Ingham { 959*acff8950SJim Ingham return g_option_table; 960*acff8950SJim Ingham } 961*acff8950SJim Ingham 962*acff8950SJim Ingham // Options table: Required for subclasses of Options. 963*acff8950SJim Ingham 964*acff8950SJim Ingham static OptionDefinition g_option_table[]; 965*acff8950SJim Ingham 966*acff8950SJim Ingham // Instance variables to hold the values for command options. 967*acff8950SJim Ingham LazyBool m_keep_stopped; 968*acff8950SJim Ingham }; 96930fdc8d8SChris Lattner 970a7015092SGreg Clayton CommandObjectProcessDetach (CommandInterpreter &interpreter) : 9715a988416SJim Ingham CommandObjectParsed (interpreter, 972a7015092SGreg Clayton "process detach", 973e3d26315SCaroline Tice "Detach from the current process being debugged.", 97430fdc8d8SChris Lattner "process detach", 975f9fc609fSGreg Clayton eFlagRequiresProcess | 976f9fc609fSGreg Clayton eFlagTryTargetAPILock | 977*acff8950SJim Ingham eFlagProcessMustBeLaunched), 978*acff8950SJim Ingham m_options(interpreter) 97930fdc8d8SChris Lattner { 98030fdc8d8SChris Lattner } 98130fdc8d8SChris Lattner 98230fdc8d8SChris Lattner ~CommandObjectProcessDetach () 98330fdc8d8SChris Lattner { 98430fdc8d8SChris Lattner } 98530fdc8d8SChris Lattner 986*acff8950SJim Ingham Options * 987*acff8950SJim Ingham GetOptions () 988*acff8950SJim Ingham { 989*acff8950SJim Ingham return &m_options; 990*acff8950SJim Ingham } 991*acff8950SJim Ingham 992*acff8950SJim Ingham 9935a988416SJim Ingham protected: 99430fdc8d8SChris Lattner bool 995f9fc609fSGreg Clayton DoExecute (Args& command, CommandReturnObject &result) 99630fdc8d8SChris Lattner { 997f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 998d01b2953SDaniel Malea result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID()); 999*acff8950SJim Ingham // FIXME: This will be a Command Option: 1000*acff8950SJim Ingham bool keep_stopped; 1001*acff8950SJim Ingham if (m_options.m_keep_stopped == eLazyBoolCalculate) 1002*acff8950SJim Ingham { 1003*acff8950SJim Ingham // Check the process default: 1004*acff8950SJim Ingham if (process->GetDetachKeepsStopped()) 1005*acff8950SJim Ingham keep_stopped = true; 1006*acff8950SJim Ingham else 1007*acff8950SJim Ingham keep_stopped = false; 1008*acff8950SJim Ingham } 1009*acff8950SJim Ingham else if (m_options.m_keep_stopped == eLazyBoolYes) 1010*acff8950SJim Ingham keep_stopped = true; 1011*acff8950SJim Ingham else 1012*acff8950SJim Ingham keep_stopped = false; 1013*acff8950SJim Ingham 1014*acff8950SJim Ingham Error error (process->Detach(keep_stopped)); 101530fdc8d8SChris Lattner if (error.Success()) 101630fdc8d8SChris Lattner { 101730fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 101830fdc8d8SChris Lattner } 101930fdc8d8SChris Lattner else 102030fdc8d8SChris Lattner { 102130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 102230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 102330fdc8d8SChris Lattner return false; 102430fdc8d8SChris Lattner } 102530fdc8d8SChris Lattner return result.Succeeded(); 102630fdc8d8SChris Lattner } 1027*acff8950SJim Ingham 1028*acff8950SJim Ingham CommandOptions m_options; 1029*acff8950SJim Ingham }; 1030*acff8950SJim Ingham 1031*acff8950SJim Ingham OptionDefinition 1032*acff8950SJim Ingham CommandObjectProcessDetach::CommandOptions::g_option_table[] = 1033*acff8950SJim Ingham { 1034*acff8950SJim Ingham { LLDB_OPT_SET_1, false, "keep-stopped", 's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, 1035*acff8950SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 103630fdc8d8SChris Lattner }; 103730fdc8d8SChris Lattner 103830fdc8d8SChris Lattner //------------------------------------------------------------------------- 1039b766a73dSGreg Clayton // CommandObjectProcessConnect 1040b766a73dSGreg Clayton //------------------------------------------------------------------------- 1041b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect 1042b766a73dSGreg Clayton 10435a988416SJim Ingham class CommandObjectProcessConnect : public CommandObjectParsed 1044b766a73dSGreg Clayton { 1045b766a73dSGreg Clayton public: 1046b766a73dSGreg Clayton 1047b766a73dSGreg Clayton class CommandOptions : public Options 1048b766a73dSGreg Clayton { 1049b766a73dSGreg Clayton public: 1050b766a73dSGreg Clayton 1051eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1052eb0103f2SGreg Clayton Options(interpreter) 1053b766a73dSGreg Clayton { 1054f6b8b581SGreg Clayton // Keep default values of all options in one place: OptionParsingStarting () 1055f6b8b581SGreg Clayton OptionParsingStarting (); 1056b766a73dSGreg Clayton } 1057b766a73dSGreg Clayton 1058b766a73dSGreg Clayton ~CommandOptions () 1059b766a73dSGreg Clayton { 1060b766a73dSGreg Clayton } 1061b766a73dSGreg Clayton 1062b766a73dSGreg Clayton Error 1063f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 1064b766a73dSGreg Clayton { 1065b766a73dSGreg Clayton Error error; 10663bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1067b766a73dSGreg Clayton 1068b766a73dSGreg Clayton switch (short_option) 1069b766a73dSGreg Clayton { 1070b766a73dSGreg Clayton case 'p': 1071b766a73dSGreg Clayton plugin_name.assign (option_arg); 1072b766a73dSGreg Clayton break; 1073b766a73dSGreg Clayton 1074b766a73dSGreg Clayton default: 107586edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1076b766a73dSGreg Clayton break; 1077b766a73dSGreg Clayton } 1078b766a73dSGreg Clayton return error; 1079b766a73dSGreg Clayton } 1080b766a73dSGreg Clayton 1081b766a73dSGreg Clayton void 1082f6b8b581SGreg Clayton OptionParsingStarting () 1083b766a73dSGreg Clayton { 1084b766a73dSGreg Clayton plugin_name.clear(); 1085b766a73dSGreg Clayton } 1086b766a73dSGreg Clayton 1087e0d378b3SGreg Clayton const OptionDefinition* 1088b766a73dSGreg Clayton GetDefinitions () 1089b766a73dSGreg Clayton { 1090b766a73dSGreg Clayton return g_option_table; 1091b766a73dSGreg Clayton } 1092b766a73dSGreg Clayton 1093b766a73dSGreg Clayton // Options table: Required for subclasses of Options. 1094b766a73dSGreg Clayton 1095e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 1096b766a73dSGreg Clayton 1097b766a73dSGreg Clayton // Instance variables to hold the values for command options. 1098b766a73dSGreg Clayton 1099b766a73dSGreg Clayton std::string plugin_name; 1100b766a73dSGreg Clayton }; 1101b766a73dSGreg Clayton 1102b766a73dSGreg Clayton CommandObjectProcessConnect (CommandInterpreter &interpreter) : 11035a988416SJim Ingham CommandObjectParsed (interpreter, 1104b766a73dSGreg Clayton "process connect", 1105b766a73dSGreg Clayton "Connect to a remote debug service.", 1106b766a73dSGreg Clayton "process connect <remote-url>", 1107eb0103f2SGreg Clayton 0), 1108eb0103f2SGreg Clayton m_options (interpreter) 1109b766a73dSGreg Clayton { 1110b766a73dSGreg Clayton } 1111b766a73dSGreg Clayton 1112b766a73dSGreg Clayton ~CommandObjectProcessConnect () 1113b766a73dSGreg Clayton { 1114b766a73dSGreg Clayton } 1115b766a73dSGreg Clayton 1116b766a73dSGreg Clayton 11175a988416SJim Ingham Options * 11185a988416SJim Ingham GetOptions () 11195a988416SJim Ingham { 11205a988416SJim Ingham return &m_options; 11215a988416SJim Ingham } 11225a988416SJim Ingham 11235a988416SJim Ingham protected: 1124b766a73dSGreg Clayton bool 11255a988416SJim Ingham DoExecute (Args& command, 1126b766a73dSGreg Clayton CommandReturnObject &result) 1127b766a73dSGreg Clayton { 1128b766a73dSGreg Clayton 1129b766a73dSGreg Clayton TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget()); 1130b766a73dSGreg Clayton Error error; 1131f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 1132b766a73dSGreg Clayton if (process) 1133b766a73dSGreg Clayton { 1134b766a73dSGreg Clayton if (process->IsAlive()) 1135b766a73dSGreg Clayton { 1136d01b2953SDaniel Malea result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n", 1137b766a73dSGreg Clayton process->GetID()); 1138b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1139b766a73dSGreg Clayton return false; 1140b766a73dSGreg Clayton } 1141b766a73dSGreg Clayton } 1142b766a73dSGreg Clayton 1143b766a73dSGreg Clayton if (!target_sp) 1144b766a73dSGreg Clayton { 1145b766a73dSGreg Clayton // If there isn't a current target create one. 1146b766a73dSGreg Clayton 1147b766a73dSGreg Clayton error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 1148a0ca6601SGreg Clayton NULL, 1149cac9c5f9SGreg Clayton NULL, 1150b766a73dSGreg Clayton false, 1151cac9c5f9SGreg Clayton NULL, // No platform options 1152b766a73dSGreg Clayton target_sp); 1153b766a73dSGreg Clayton if (!target_sp || error.Fail()) 1154b766a73dSGreg Clayton { 1155b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 1156b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1157b766a73dSGreg Clayton return false; 1158b766a73dSGreg Clayton } 1159b766a73dSGreg Clayton m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get()); 1160b766a73dSGreg Clayton } 1161b766a73dSGreg Clayton 1162b766a73dSGreg Clayton if (command.GetArgumentCount() == 1) 1163b766a73dSGreg Clayton { 1164b766a73dSGreg Clayton const char *plugin_name = NULL; 1165b766a73dSGreg Clayton if (!m_options.plugin_name.empty()) 1166b766a73dSGreg Clayton plugin_name = m_options.plugin_name.c_str(); 1167b766a73dSGreg Clayton 1168b766a73dSGreg Clayton const char *remote_url = command.GetArgumentAtIndex(0); 1169c3776bf2SGreg Clayton process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get(); 1170b766a73dSGreg Clayton 1171b766a73dSGreg Clayton if (process) 1172b766a73dSGreg Clayton { 11734bd4e7e3SJason Molenda error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url); 1174b766a73dSGreg Clayton 1175b766a73dSGreg Clayton if (error.Fail()) 1176b766a73dSGreg Clayton { 1177b766a73dSGreg Clayton result.AppendError(error.AsCString("Remote connect failed")); 1178b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 11791517dd33SGreg Clayton target_sp->DeleteCurrentProcess(); 1180b766a73dSGreg Clayton return false; 1181b766a73dSGreg Clayton } 1182b766a73dSGreg Clayton } 1183b766a73dSGreg Clayton else 1184b766a73dSGreg Clayton { 1185fd54b368SJason Molenda result.AppendErrorWithFormat ("Unable to find process plug-in for remote URL '%s'.\nPlease specify a process plug-in name with the --plugin option, or specify an object file using the \"file\" command.\n", 1186f00b7511SDaniel Malea remote_url); 1187b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1188b766a73dSGreg Clayton } 1189b766a73dSGreg Clayton } 1190b766a73dSGreg Clayton else 1191b766a73dSGreg Clayton { 1192fd54b368SJason Molenda result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n", 1193b766a73dSGreg Clayton m_cmd_name.c_str(), 1194b766a73dSGreg Clayton m_cmd_syntax.c_str()); 1195b766a73dSGreg Clayton result.SetStatus (eReturnStatusFailed); 1196b766a73dSGreg Clayton } 1197b766a73dSGreg Clayton return result.Succeeded(); 1198b766a73dSGreg Clayton } 1199b766a73dSGreg Clayton 1200b766a73dSGreg Clayton CommandOptions m_options; 1201b766a73dSGreg Clayton }; 1202b766a73dSGreg Clayton 1203e0d378b3SGreg Clayton OptionDefinition 1204b766a73dSGreg Clayton CommandObjectProcessConnect::CommandOptions::g_option_table[] = 1205b766a73dSGreg Clayton { 1206b766a73dSGreg Clayton { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 1207b766a73dSGreg Clayton { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } 1208b766a73dSGreg Clayton }; 1209b766a73dSGreg Clayton 1210b766a73dSGreg Clayton //------------------------------------------------------------------------- 1211998255bfSGreg Clayton // CommandObjectProcessPlugin 1212998255bfSGreg Clayton //------------------------------------------------------------------------- 1213998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin 1214998255bfSGreg Clayton 1215998255bfSGreg Clayton class CommandObjectProcessPlugin : public CommandObjectProxy 1216998255bfSGreg Clayton { 1217998255bfSGreg Clayton public: 1218998255bfSGreg Clayton 1219998255bfSGreg Clayton CommandObjectProcessPlugin (CommandInterpreter &interpreter) : 1220998255bfSGreg Clayton CommandObjectProxy (interpreter, 1221998255bfSGreg Clayton "process plugin", 1222998255bfSGreg Clayton "Send a custom command to the current process plug-in.", 1223998255bfSGreg Clayton "process plugin <args>", 1224998255bfSGreg Clayton 0) 1225998255bfSGreg Clayton { 1226998255bfSGreg Clayton } 1227998255bfSGreg Clayton 1228998255bfSGreg Clayton ~CommandObjectProcessPlugin () 1229998255bfSGreg Clayton { 1230998255bfSGreg Clayton } 1231998255bfSGreg Clayton 1232998255bfSGreg Clayton virtual CommandObject * 1233998255bfSGreg Clayton GetProxyCommandObject() 1234998255bfSGreg Clayton { 1235e05b2efeSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1236998255bfSGreg Clayton if (process) 1237998255bfSGreg Clayton return process->GetPluginCommandObject(); 1238998255bfSGreg Clayton return NULL; 1239998255bfSGreg Clayton } 1240998255bfSGreg Clayton }; 1241998255bfSGreg Clayton 1242998255bfSGreg Clayton 1243998255bfSGreg Clayton //------------------------------------------------------------------------- 12448f343b09SGreg Clayton // CommandObjectProcessLoad 12458f343b09SGreg Clayton //------------------------------------------------------------------------- 1246bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad 12478f343b09SGreg Clayton 12485a988416SJim Ingham class CommandObjectProcessLoad : public CommandObjectParsed 12498f343b09SGreg Clayton { 12508f343b09SGreg Clayton public: 12518f343b09SGreg Clayton 12528f343b09SGreg Clayton CommandObjectProcessLoad (CommandInterpreter &interpreter) : 12535a988416SJim Ingham CommandObjectParsed (interpreter, 12548f343b09SGreg Clayton "process load", 12558f343b09SGreg Clayton "Load a shared library into the current process.", 12568f343b09SGreg Clayton "process load <filename> [<filename> ...]", 1257f9fc609fSGreg Clayton eFlagRequiresProcess | 1258f9fc609fSGreg Clayton eFlagTryTargetAPILock | 1259f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 1260f9fc609fSGreg Clayton eFlagProcessMustBePaused ) 12618f343b09SGreg Clayton { 12628f343b09SGreg Clayton } 12638f343b09SGreg Clayton 12648f343b09SGreg Clayton ~CommandObjectProcessLoad () 12658f343b09SGreg Clayton { 12668f343b09SGreg Clayton } 12678f343b09SGreg Clayton 12685a988416SJim Ingham protected: 12698f343b09SGreg Clayton bool 12705a988416SJim Ingham DoExecute (Args& command, 12718f343b09SGreg Clayton CommandReturnObject &result) 12728f343b09SGreg Clayton { 1273f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 12748f343b09SGreg Clayton 1275c7bece56SGreg Clayton const size_t argc = command.GetArgumentCount(); 12768f343b09SGreg Clayton 12778f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 12788f343b09SGreg Clayton { 12798f343b09SGreg Clayton Error error; 12808f343b09SGreg Clayton const char *image_path = command.GetArgumentAtIndex(i); 12818f343b09SGreg Clayton FileSpec image_spec (image_path, false); 1282aa516843SGreg Clayton process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec); 12838f343b09SGreg Clayton uint32_t image_token = process->LoadImage(image_spec, error); 12848f343b09SGreg Clayton if (image_token != LLDB_INVALID_IMAGE_TOKEN) 12858f343b09SGreg Clayton { 12868f343b09SGreg Clayton result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 12878f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 12888f343b09SGreg Clayton } 12898f343b09SGreg Clayton else 12908f343b09SGreg Clayton { 12918f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 12928f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 12938f343b09SGreg Clayton } 12948f343b09SGreg Clayton } 12958f343b09SGreg Clayton return result.Succeeded(); 12968f343b09SGreg Clayton } 12978f343b09SGreg Clayton }; 12988f343b09SGreg Clayton 12998f343b09SGreg Clayton 13008f343b09SGreg Clayton //------------------------------------------------------------------------- 13018f343b09SGreg Clayton // CommandObjectProcessUnload 13028f343b09SGreg Clayton //------------------------------------------------------------------------- 1303bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload 13048f343b09SGreg Clayton 13055a988416SJim Ingham class CommandObjectProcessUnload : public CommandObjectParsed 13068f343b09SGreg Clayton { 13078f343b09SGreg Clayton public: 13088f343b09SGreg Clayton 13098f343b09SGreg Clayton CommandObjectProcessUnload (CommandInterpreter &interpreter) : 13105a988416SJim Ingham CommandObjectParsed (interpreter, 13118f343b09SGreg Clayton "process unload", 13128f343b09SGreg Clayton "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 13138f343b09SGreg Clayton "process unload <index>", 1314f9fc609fSGreg Clayton eFlagRequiresProcess | 1315f9fc609fSGreg Clayton eFlagTryTargetAPILock | 1316f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 1317f9fc609fSGreg Clayton eFlagProcessMustBePaused ) 13188f343b09SGreg Clayton { 13198f343b09SGreg Clayton } 13208f343b09SGreg Clayton 13218f343b09SGreg Clayton ~CommandObjectProcessUnload () 13228f343b09SGreg Clayton { 13238f343b09SGreg Clayton } 13248f343b09SGreg Clayton 13255a988416SJim Ingham protected: 13268f343b09SGreg Clayton bool 13275a988416SJim Ingham DoExecute (Args& command, 13288f343b09SGreg Clayton CommandReturnObject &result) 13298f343b09SGreg Clayton { 1330f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 13318f343b09SGreg Clayton 1332c7bece56SGreg Clayton const size_t argc = command.GetArgumentCount(); 13338f343b09SGreg Clayton 13348f343b09SGreg Clayton for (uint32_t i=0; i<argc; ++i) 13358f343b09SGreg Clayton { 13368f343b09SGreg Clayton const char *image_token_cstr = command.GetArgumentAtIndex(i); 13378f343b09SGreg Clayton uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 13388f343b09SGreg Clayton if (image_token == LLDB_INVALID_IMAGE_TOKEN) 13398f343b09SGreg Clayton { 13408f343b09SGreg Clayton result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 13418f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 13428f343b09SGreg Clayton break; 13438f343b09SGreg Clayton } 13448f343b09SGreg Clayton else 13458f343b09SGreg Clayton { 13468f343b09SGreg Clayton Error error (process->UnloadImage(image_token)); 13478f343b09SGreg Clayton if (error.Success()) 13488f343b09SGreg Clayton { 13498f343b09SGreg Clayton result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 13508f343b09SGreg Clayton result.SetStatus (eReturnStatusSuccessFinishResult); 13518f343b09SGreg Clayton } 13528f343b09SGreg Clayton else 13538f343b09SGreg Clayton { 13548f343b09SGreg Clayton result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 13558f343b09SGreg Clayton result.SetStatus (eReturnStatusFailed); 13568f343b09SGreg Clayton break; 13578f343b09SGreg Clayton } 13588f343b09SGreg Clayton } 13598f343b09SGreg Clayton } 13608f343b09SGreg Clayton return result.Succeeded(); 13618f343b09SGreg Clayton } 13628f343b09SGreg Clayton }; 13638f343b09SGreg Clayton 13648f343b09SGreg Clayton //------------------------------------------------------------------------- 136530fdc8d8SChris Lattner // CommandObjectProcessSignal 136630fdc8d8SChris Lattner //------------------------------------------------------------------------- 1367bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal 136830fdc8d8SChris Lattner 13695a988416SJim Ingham class CommandObjectProcessSignal : public CommandObjectParsed 137030fdc8d8SChris Lattner { 137130fdc8d8SChris Lattner public: 137230fdc8d8SChris Lattner 1373a7015092SGreg Clayton CommandObjectProcessSignal (CommandInterpreter &interpreter) : 13745a988416SJim Ingham CommandObjectParsed (interpreter, 1375a7015092SGreg Clayton "process signal", 1376e3d26315SCaroline Tice "Send a UNIX signal to the current process being debugged.", 1377f9fc609fSGreg Clayton NULL, 1378f9fc609fSGreg Clayton eFlagRequiresProcess | eFlagTryTargetAPILock) 137930fdc8d8SChris Lattner { 1380405fe67fSCaroline Tice CommandArgumentEntry arg; 1381405fe67fSCaroline Tice CommandArgumentData signal_arg; 1382405fe67fSCaroline Tice 1383405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 1384c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1385405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 1386405fe67fSCaroline Tice 1387405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 1388405fe67fSCaroline Tice arg.push_back (signal_arg); 1389405fe67fSCaroline Tice 1390405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1391405fe67fSCaroline Tice m_arguments.push_back (arg); 139230fdc8d8SChris Lattner } 139330fdc8d8SChris Lattner 139430fdc8d8SChris Lattner ~CommandObjectProcessSignal () 139530fdc8d8SChris Lattner { 139630fdc8d8SChris Lattner } 139730fdc8d8SChris Lattner 13985a988416SJim Ingham protected: 139930fdc8d8SChris Lattner bool 14005a988416SJim Ingham DoExecute (Args& command, 140130fdc8d8SChris Lattner CommandReturnObject &result) 140230fdc8d8SChris Lattner { 1403f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 140430fdc8d8SChris Lattner 140530fdc8d8SChris Lattner if (command.GetArgumentCount() == 1) 140630fdc8d8SChris Lattner { 1407237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1408237cd906SGreg Clayton 1409237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1410237cd906SGreg Clayton if (::isxdigit (signal_name[0])) 1411237cd906SGreg Clayton signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1412237cd906SGreg Clayton else 1413237cd906SGreg Clayton signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 1414237cd906SGreg Clayton 1415237cd906SGreg Clayton if (signo == LLDB_INVALID_SIGNAL_NUMBER) 141630fdc8d8SChris Lattner { 141730fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 141830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 141930fdc8d8SChris Lattner } 142030fdc8d8SChris Lattner else 142130fdc8d8SChris Lattner { 142230fdc8d8SChris Lattner Error error (process->Signal (signo)); 142330fdc8d8SChris Lattner if (error.Success()) 142430fdc8d8SChris Lattner { 142530fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 142630fdc8d8SChris Lattner } 142730fdc8d8SChris Lattner else 142830fdc8d8SChris Lattner { 142930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 143030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 143130fdc8d8SChris Lattner } 143230fdc8d8SChris Lattner } 143330fdc8d8SChris Lattner } 143430fdc8d8SChris Lattner else 143530fdc8d8SChris Lattner { 1436fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(), 143730fdc8d8SChris Lattner m_cmd_syntax.c_str()); 143830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 143930fdc8d8SChris Lattner } 144030fdc8d8SChris Lattner return result.Succeeded(); 144130fdc8d8SChris Lattner } 144230fdc8d8SChris Lattner }; 144330fdc8d8SChris Lattner 144430fdc8d8SChris Lattner 144530fdc8d8SChris Lattner //------------------------------------------------------------------------- 144630fdc8d8SChris Lattner // CommandObjectProcessInterrupt 144730fdc8d8SChris Lattner //------------------------------------------------------------------------- 1448bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt 144930fdc8d8SChris Lattner 14505a988416SJim Ingham class CommandObjectProcessInterrupt : public CommandObjectParsed 145130fdc8d8SChris Lattner { 145230fdc8d8SChris Lattner public: 145330fdc8d8SChris Lattner 145430fdc8d8SChris Lattner 1455a7015092SGreg Clayton CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 14565a988416SJim Ingham CommandObjectParsed (interpreter, 1457a7015092SGreg Clayton "process interrupt", 1458e3d26315SCaroline Tice "Interrupt the current process being debugged.", 145930fdc8d8SChris Lattner "process interrupt", 1460f9fc609fSGreg Clayton eFlagRequiresProcess | 1461f9fc609fSGreg Clayton eFlagTryTargetAPILock | 146230fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 146330fdc8d8SChris Lattner { 146430fdc8d8SChris Lattner } 146530fdc8d8SChris Lattner 146630fdc8d8SChris Lattner ~CommandObjectProcessInterrupt () 146730fdc8d8SChris Lattner { 146830fdc8d8SChris Lattner } 146930fdc8d8SChris Lattner 14705a988416SJim Ingham protected: 147130fdc8d8SChris Lattner bool 14725a988416SJim Ingham DoExecute (Args& command, 147330fdc8d8SChris Lattner CommandReturnObject &result) 147430fdc8d8SChris Lattner { 1475f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 147630fdc8d8SChris Lattner if (process == NULL) 147730fdc8d8SChris Lattner { 147830fdc8d8SChris Lattner result.AppendError ("no process to halt"); 147930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 148030fdc8d8SChris Lattner return false; 148130fdc8d8SChris Lattner } 148230fdc8d8SChris Lattner 148330fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 148430fdc8d8SChris Lattner { 148530fdc8d8SChris Lattner Error error(process->Halt ()); 148630fdc8d8SChris Lattner if (error.Success()) 148730fdc8d8SChris Lattner { 148830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 148930fdc8d8SChris Lattner 149030fdc8d8SChris Lattner // Maybe we should add a "SuspendThreadPlans so we 149130fdc8d8SChris Lattner // can halt, and keep in place all the current thread plans. 149230fdc8d8SChris Lattner process->GetThreadList().DiscardThreadPlans(); 149330fdc8d8SChris Lattner } 149430fdc8d8SChris Lattner else 149530fdc8d8SChris Lattner { 149630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 149730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 149830fdc8d8SChris Lattner } 149930fdc8d8SChris Lattner } 150030fdc8d8SChris Lattner else 150130fdc8d8SChris Lattner { 1502fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 150330fdc8d8SChris Lattner m_cmd_name.c_str(), 150430fdc8d8SChris Lattner m_cmd_syntax.c_str()); 150530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 150630fdc8d8SChris Lattner } 150730fdc8d8SChris Lattner return result.Succeeded(); 150830fdc8d8SChris Lattner } 150930fdc8d8SChris Lattner }; 151030fdc8d8SChris Lattner 151130fdc8d8SChris Lattner //------------------------------------------------------------------------- 151230fdc8d8SChris Lattner // CommandObjectProcessKill 151330fdc8d8SChris Lattner //------------------------------------------------------------------------- 1514bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill 151530fdc8d8SChris Lattner 15165a988416SJim Ingham class CommandObjectProcessKill : public CommandObjectParsed 151730fdc8d8SChris Lattner { 151830fdc8d8SChris Lattner public: 151930fdc8d8SChris Lattner 1520a7015092SGreg Clayton CommandObjectProcessKill (CommandInterpreter &interpreter) : 15215a988416SJim Ingham CommandObjectParsed (interpreter, 1522a7015092SGreg Clayton "process kill", 1523e3d26315SCaroline Tice "Terminate the current process being debugged.", 152430fdc8d8SChris Lattner "process kill", 1525f9fc609fSGreg Clayton eFlagRequiresProcess | 1526f9fc609fSGreg Clayton eFlagTryTargetAPILock | 152730fdc8d8SChris Lattner eFlagProcessMustBeLaunched) 152830fdc8d8SChris Lattner { 152930fdc8d8SChris Lattner } 153030fdc8d8SChris Lattner 153130fdc8d8SChris Lattner ~CommandObjectProcessKill () 153230fdc8d8SChris Lattner { 153330fdc8d8SChris Lattner } 153430fdc8d8SChris Lattner 15355a988416SJim Ingham protected: 153630fdc8d8SChris Lattner bool 15375a988416SJim Ingham DoExecute (Args& command, 153830fdc8d8SChris Lattner CommandReturnObject &result) 153930fdc8d8SChris Lattner { 1540f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 154130fdc8d8SChris Lattner if (process == NULL) 154230fdc8d8SChris Lattner { 154330fdc8d8SChris Lattner result.AppendError ("no process to kill"); 154430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 154530fdc8d8SChris Lattner return false; 154630fdc8d8SChris Lattner } 154730fdc8d8SChris Lattner 154830fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 154930fdc8d8SChris Lattner { 155030fdc8d8SChris Lattner Error error (process->Destroy()); 155130fdc8d8SChris Lattner if (error.Success()) 155230fdc8d8SChris Lattner { 155330fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishResult); 155430fdc8d8SChris Lattner } 155530fdc8d8SChris Lattner else 155630fdc8d8SChris Lattner { 155730fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 155830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 155930fdc8d8SChris Lattner } 156030fdc8d8SChris Lattner } 156130fdc8d8SChris Lattner else 156230fdc8d8SChris Lattner { 1563fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 156430fdc8d8SChris Lattner m_cmd_name.c_str(), 156530fdc8d8SChris Lattner m_cmd_syntax.c_str()); 156630fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 156730fdc8d8SChris Lattner } 156830fdc8d8SChris Lattner return result.Succeeded(); 156930fdc8d8SChris Lattner } 157030fdc8d8SChris Lattner }; 157130fdc8d8SChris Lattner 157230fdc8d8SChris Lattner //------------------------------------------------------------------------- 15734b9bea87SJim Ingham // CommandObjectProcessStatus 15744b9bea87SJim Ingham //------------------------------------------------------------------------- 1575bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus 1576bb9caf73SJim Ingham 15775a988416SJim Ingham class CommandObjectProcessStatus : public CommandObjectParsed 15784b9bea87SJim Ingham { 15794b9bea87SJim Ingham public: 1580a7015092SGreg Clayton CommandObjectProcessStatus (CommandInterpreter &interpreter) : 15815a988416SJim Ingham CommandObjectParsed (interpreter, 1582a7015092SGreg Clayton "process status", 1583e3d26315SCaroline Tice "Show the current status and location of executing process.", 1584e3d26315SCaroline Tice "process status", 1585f9fc609fSGreg Clayton eFlagRequiresProcess | eFlagTryTargetAPILock) 15864b9bea87SJim Ingham { 15874b9bea87SJim Ingham } 15884b9bea87SJim Ingham 15894b9bea87SJim Ingham ~CommandObjectProcessStatus() 15904b9bea87SJim Ingham { 15914b9bea87SJim Ingham } 15924b9bea87SJim Ingham 15934b9bea87SJim Ingham 15944b9bea87SJim Ingham bool 15955a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 15964b9bea87SJim Ingham { 15977260f620SGreg Clayton Stream &strm = result.GetOutputStream(); 15984b9bea87SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1599f9fc609fSGreg Clayton // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid 1600f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 16017260f620SGreg Clayton const bool only_threads_with_stop_reason = true; 16027260f620SGreg Clayton const uint32_t start_frame = 0; 16037260f620SGreg Clayton const uint32_t num_frames = 1; 16047260f620SGreg Clayton const uint32_t num_frames_with_source = 1; 1605c14ee32dSGreg Clayton process->GetStatus(strm); 1606c14ee32dSGreg Clayton process->GetThreadStatus (strm, 16077260f620SGreg Clayton only_threads_with_stop_reason, 16087260f620SGreg Clayton start_frame, 16097260f620SGreg Clayton num_frames, 16107260f620SGreg Clayton num_frames_with_source); 16114b9bea87SJim Ingham return result.Succeeded(); 16124b9bea87SJim Ingham } 16134b9bea87SJim Ingham }; 16144b9bea87SJim Ingham 16154b9bea87SJim Ingham //------------------------------------------------------------------------- 161635731357SCaroline Tice // CommandObjectProcessHandle 161735731357SCaroline Tice //------------------------------------------------------------------------- 1618bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle 161935731357SCaroline Tice 16205a988416SJim Ingham class CommandObjectProcessHandle : public CommandObjectParsed 162135731357SCaroline Tice { 162235731357SCaroline Tice public: 162335731357SCaroline Tice 162435731357SCaroline Tice class CommandOptions : public Options 162535731357SCaroline Tice { 162635731357SCaroline Tice public: 162735731357SCaroline Tice 1628eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1629eb0103f2SGreg Clayton Options (interpreter) 163035731357SCaroline Tice { 1631f6b8b581SGreg Clayton OptionParsingStarting (); 163235731357SCaroline Tice } 163335731357SCaroline Tice 163435731357SCaroline Tice ~CommandOptions () 163535731357SCaroline Tice { 163635731357SCaroline Tice } 163735731357SCaroline Tice 163835731357SCaroline Tice Error 1639f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 164035731357SCaroline Tice { 164135731357SCaroline Tice Error error; 16423bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 164335731357SCaroline Tice 164435731357SCaroline Tice switch (short_option) 164535731357SCaroline Tice { 164635731357SCaroline Tice case 's': 164735731357SCaroline Tice stop = option_arg; 164835731357SCaroline Tice break; 164935731357SCaroline Tice case 'n': 165035731357SCaroline Tice notify = option_arg; 165135731357SCaroline Tice break; 165235731357SCaroline Tice case 'p': 165335731357SCaroline Tice pass = option_arg; 165435731357SCaroline Tice break; 165535731357SCaroline Tice default: 165686edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 165735731357SCaroline Tice break; 165835731357SCaroline Tice } 165935731357SCaroline Tice return error; 166035731357SCaroline Tice } 166135731357SCaroline Tice 166235731357SCaroline Tice void 1663f6b8b581SGreg Clayton OptionParsingStarting () 166435731357SCaroline Tice { 166535731357SCaroline Tice stop.clear(); 166635731357SCaroline Tice notify.clear(); 166735731357SCaroline Tice pass.clear(); 166835731357SCaroline Tice } 166935731357SCaroline Tice 1670e0d378b3SGreg Clayton const OptionDefinition* 167135731357SCaroline Tice GetDefinitions () 167235731357SCaroline Tice { 167335731357SCaroline Tice return g_option_table; 167435731357SCaroline Tice } 167535731357SCaroline Tice 167635731357SCaroline Tice // Options table: Required for subclasses of Options. 167735731357SCaroline Tice 1678e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 167935731357SCaroline Tice 168035731357SCaroline Tice // Instance variables to hold the values for command options. 168135731357SCaroline Tice 168235731357SCaroline Tice std::string stop; 168335731357SCaroline Tice std::string notify; 168435731357SCaroline Tice std::string pass; 168535731357SCaroline Tice }; 168635731357SCaroline Tice 168735731357SCaroline Tice 168835731357SCaroline Tice CommandObjectProcessHandle (CommandInterpreter &interpreter) : 16895a988416SJim Ingham CommandObjectParsed (interpreter, 169035731357SCaroline Tice "process handle", 169110ad7993SCaroline Tice "Show or update what the process and debugger should do with various signals received from the OS.", 1692eb0103f2SGreg Clayton NULL), 1693eb0103f2SGreg Clayton m_options (interpreter) 169435731357SCaroline Tice { 169510ad7993SCaroline Tice SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 169635731357SCaroline Tice CommandArgumentEntry arg; 1697c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 169835731357SCaroline Tice 1699c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1700c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 170135731357SCaroline Tice 1702c0dbdfb6SCaroline Tice arg.push_back (signal_arg); 170335731357SCaroline Tice 170435731357SCaroline Tice m_arguments.push_back (arg); 170535731357SCaroline Tice } 170635731357SCaroline Tice 170735731357SCaroline Tice ~CommandObjectProcessHandle () 170835731357SCaroline Tice { 170935731357SCaroline Tice } 171035731357SCaroline Tice 171135731357SCaroline Tice Options * 171235731357SCaroline Tice GetOptions () 171335731357SCaroline Tice { 171435731357SCaroline Tice return &m_options; 171535731357SCaroline Tice } 171635731357SCaroline Tice 171735731357SCaroline Tice bool 171810ad7993SCaroline Tice VerifyCommandOptionValue (const std::string &option, int &real_value) 171935731357SCaroline Tice { 172035731357SCaroline Tice bool okay = true; 172135731357SCaroline Tice 172210ad7993SCaroline Tice bool success = false; 172310ad7993SCaroline Tice bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 172410ad7993SCaroline Tice 172510ad7993SCaroline Tice if (success && tmp_value) 172610ad7993SCaroline Tice real_value = 1; 172710ad7993SCaroline Tice else if (success && !tmp_value) 172810ad7993SCaroline Tice real_value = 0; 172935731357SCaroline Tice else 173035731357SCaroline Tice { 173135731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 173210ad7993SCaroline Tice real_value = Args::StringToUInt32 (option.c_str(), 3); 173310ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 173435731357SCaroline Tice okay = false; 173535731357SCaroline Tice } 173635731357SCaroline Tice 173735731357SCaroline Tice return okay; 173835731357SCaroline Tice } 173935731357SCaroline Tice 174010ad7993SCaroline Tice void 174110ad7993SCaroline Tice PrintSignalHeader (Stream &str) 174210ad7993SCaroline Tice { 174310ad7993SCaroline Tice str.Printf ("NAME PASS STOP NOTIFY\n"); 174410ad7993SCaroline Tice str.Printf ("========== ===== ===== ======\n"); 174510ad7993SCaroline Tice } 174610ad7993SCaroline Tice 174710ad7993SCaroline Tice void 174810ad7993SCaroline Tice PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 174910ad7993SCaroline Tice { 175010ad7993SCaroline Tice bool stop; 175110ad7993SCaroline Tice bool suppress; 175210ad7993SCaroline Tice bool notify; 175310ad7993SCaroline Tice 175410ad7993SCaroline Tice str.Printf ("%-10s ", sig_name); 175510ad7993SCaroline Tice if (signals.GetSignalInfo (signo, suppress, stop, notify)) 175610ad7993SCaroline Tice { 175710ad7993SCaroline Tice bool pass = !suppress; 175810ad7993SCaroline Tice str.Printf ("%s %s %s", 175910ad7993SCaroline Tice (pass ? "true " : "false"), 176010ad7993SCaroline Tice (stop ? "true " : "false"), 176110ad7993SCaroline Tice (notify ? "true " : "false")); 176210ad7993SCaroline Tice } 176310ad7993SCaroline Tice str.Printf ("\n"); 176410ad7993SCaroline Tice } 176510ad7993SCaroline Tice 176610ad7993SCaroline Tice void 176710ad7993SCaroline Tice PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 176810ad7993SCaroline Tice { 176910ad7993SCaroline Tice PrintSignalHeader (str); 177010ad7993SCaroline Tice 177110ad7993SCaroline Tice if (num_valid_signals > 0) 177210ad7993SCaroline Tice { 177310ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 177410ad7993SCaroline Tice for (size_t i = 0; i < num_args; ++i) 177510ad7993SCaroline Tice { 177610ad7993SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 177710ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 177810ad7993SCaroline Tice PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 177910ad7993SCaroline Tice } 178010ad7993SCaroline Tice } 178110ad7993SCaroline Tice else // Print info for ALL signals 178210ad7993SCaroline Tice { 178310ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 178410ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 178510ad7993SCaroline Tice { 178610ad7993SCaroline Tice PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 178710ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 178810ad7993SCaroline Tice } 178910ad7993SCaroline Tice } 179010ad7993SCaroline Tice } 179110ad7993SCaroline Tice 17925a988416SJim Ingham protected: 179335731357SCaroline Tice bool 17945a988416SJim Ingham DoExecute (Args &signal_args, CommandReturnObject &result) 179535731357SCaroline Tice { 179635731357SCaroline Tice TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 179735731357SCaroline Tice 179835731357SCaroline Tice if (!target_sp) 179935731357SCaroline Tice { 180035731357SCaroline Tice result.AppendError ("No current target;" 180135731357SCaroline Tice " cannot handle signals until you have a valid target and process.\n"); 180235731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 180335731357SCaroline Tice return false; 180435731357SCaroline Tice } 180535731357SCaroline Tice 180635731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 180735731357SCaroline Tice 180835731357SCaroline Tice if (!process_sp) 180935731357SCaroline Tice { 181035731357SCaroline Tice result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 181135731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 181235731357SCaroline Tice return false; 181335731357SCaroline Tice } 181435731357SCaroline Tice 181535731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 181635731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 181735731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 181835731357SCaroline Tice 181935731357SCaroline Tice if (! m_options.stop.empty() 182010ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 182135731357SCaroline Tice { 182235731357SCaroline Tice result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 182335731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 182435731357SCaroline Tice return false; 182535731357SCaroline Tice } 182635731357SCaroline Tice 182735731357SCaroline Tice if (! m_options.notify.empty() 182810ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 182935731357SCaroline Tice { 183035731357SCaroline Tice result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 183135731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 183235731357SCaroline Tice return false; 183335731357SCaroline Tice } 183435731357SCaroline Tice 183535731357SCaroline Tice if (! m_options.pass.empty() 183610ad7993SCaroline Tice && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 183735731357SCaroline Tice { 183835731357SCaroline Tice result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 183935731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 184035731357SCaroline Tice return false; 184135731357SCaroline Tice } 184235731357SCaroline Tice 184335731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 184435731357SCaroline Tice UnixSignals &signals = process_sp->GetUnixSignals(); 184535731357SCaroline Tice int num_signals_set = 0; 184635731357SCaroline Tice 184710ad7993SCaroline Tice if (num_args > 0) 184810ad7993SCaroline Tice { 184935731357SCaroline Tice for (size_t i = 0; i < num_args; ++i) 185035731357SCaroline Tice { 185135731357SCaroline Tice int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 185235731357SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 185335731357SCaroline Tice { 185410ad7993SCaroline Tice // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 185535731357SCaroline Tice // the value is either 0 or 1. 185635731357SCaroline Tice if (stop_action != -1) 185735731357SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 185835731357SCaroline Tice if (pass_action != -1) 185935731357SCaroline Tice { 186010ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 186110ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 186235731357SCaroline Tice } 186335731357SCaroline Tice if (notify_action != -1) 186435731357SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 186535731357SCaroline Tice ++num_signals_set; 186635731357SCaroline Tice } 186735731357SCaroline Tice else 186835731357SCaroline Tice { 186935731357SCaroline Tice result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 187035731357SCaroline Tice } 187135731357SCaroline Tice } 187210ad7993SCaroline Tice } 187310ad7993SCaroline Tice else 187410ad7993SCaroline Tice { 187510ad7993SCaroline Tice // No signal specified, if any command options were specified, update ALL signals. 187610ad7993SCaroline Tice if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 187710ad7993SCaroline Tice { 187810ad7993SCaroline Tice if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 187910ad7993SCaroline Tice { 188010ad7993SCaroline Tice int32_t signo = signals.GetFirstSignalNumber(); 188110ad7993SCaroline Tice while (signo != LLDB_INVALID_SIGNAL_NUMBER) 188210ad7993SCaroline Tice { 188310ad7993SCaroline Tice if (notify_action != -1) 188410ad7993SCaroline Tice signals.SetShouldNotify (signo, (bool) notify_action); 188510ad7993SCaroline Tice if (stop_action != -1) 188610ad7993SCaroline Tice signals.SetShouldStop (signo, (bool) stop_action); 188710ad7993SCaroline Tice if (pass_action != -1) 188810ad7993SCaroline Tice { 188910ad7993SCaroline Tice bool suppress = ! ((bool) pass_action); 189010ad7993SCaroline Tice signals.SetShouldSuppress (signo, suppress); 189110ad7993SCaroline Tice } 189210ad7993SCaroline Tice signo = signals.GetNextSignalNumber (signo); 189310ad7993SCaroline Tice } 189410ad7993SCaroline Tice } 189510ad7993SCaroline Tice } 189610ad7993SCaroline Tice } 189710ad7993SCaroline Tice 189810ad7993SCaroline Tice PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 189935731357SCaroline Tice 190035731357SCaroline Tice if (num_signals_set > 0) 190135731357SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 190235731357SCaroline Tice else 190335731357SCaroline Tice result.SetStatus (eReturnStatusFailed); 190435731357SCaroline Tice 190535731357SCaroline Tice return result.Succeeded(); 190635731357SCaroline Tice } 190735731357SCaroline Tice 190835731357SCaroline Tice CommandOptions m_options; 190935731357SCaroline Tice }; 191035731357SCaroline Tice 1911e0d378b3SGreg Clayton OptionDefinition 191235731357SCaroline Tice CommandObjectProcessHandle::CommandOptions::g_option_table[] = 191335731357SCaroline Tice { 191435731357SCaroline 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." }, 191535731357SCaroline 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." }, 191635731357SCaroline Tice { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 191735731357SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 191835731357SCaroline Tice }; 191935731357SCaroline Tice 192035731357SCaroline Tice //------------------------------------------------------------------------- 192130fdc8d8SChris Lattner // CommandObjectMultiwordProcess 192230fdc8d8SChris Lattner //------------------------------------------------------------------------- 192330fdc8d8SChris Lattner 19246611103cSGreg Clayton CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1925a7015092SGreg Clayton CommandObjectMultiword (interpreter, 1926a7015092SGreg Clayton "process", 192730fdc8d8SChris Lattner "A set of commands for operating on a process.", 192830fdc8d8SChris Lattner "process <subcommand> [<subcommand-options>]") 192930fdc8d8SChris Lattner { 1930a7015092SGreg Clayton LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1931a7015092SGreg Clayton LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1932a7015092SGreg Clayton LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1933b766a73dSGreg Clayton LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); 1934a7015092SGreg Clayton LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 19358f343b09SGreg Clayton LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 19368f343b09SGreg Clayton LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1937a7015092SGreg Clayton LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 193835731357SCaroline Tice LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1939a7015092SGreg Clayton LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1940a7015092SGreg Clayton LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1941a7015092SGreg Clayton LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 1942998255bfSGreg Clayton LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter))); 194330fdc8d8SChris Lattner } 194430fdc8d8SChris Lattner 194530fdc8d8SChris Lattner CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 194630fdc8d8SChris Lattner { 194730fdc8d8SChris Lattner } 194830fdc8d8SChris Lattner 1949