1ac7ddfbfSEd Maste //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===// 2ac7ddfbfSEd Maste // 3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure 4ac7ddfbfSEd Maste // 5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source 6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details. 7ac7ddfbfSEd Maste // 8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===// 9ac7ddfbfSEd Maste 10ac7ddfbfSEd Maste #include "CommandObjectProcess.h" 11ac7ddfbfSEd Maste 12ac7ddfbfSEd Maste // C Includes 13ac7ddfbfSEd Maste // C++ Includes 14ac7ddfbfSEd Maste // Other libraries and framework includes 15ac7ddfbfSEd Maste // Project includes 16ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h" 17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h" 18ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointSite.h" 19ac7ddfbfSEd Maste #include "lldb/Core/State.h" 20ac7ddfbfSEd Maste #include "lldb/Core/Module.h" 210127ef0fSEd Maste #include "lldb/Core/PluginManager.h" 22ac7ddfbfSEd Maste #include "lldb/Host/Host.h" 231c3bbb01SEd Maste #include "lldb/Host/StringConvert.h" 24ac7ddfbfSEd Maste #include "lldb/Interpreter/Args.h" 25ac7ddfbfSEd Maste #include "lldb/Interpreter/Options.h" 26ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h" 27ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h" 28ac7ddfbfSEd Maste #include "lldb/Target/Platform.h" 29ac7ddfbfSEd Maste #include "lldb/Target/Process.h" 30ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h" 31ac7ddfbfSEd Maste #include "lldb/Target/Target.h" 32ac7ddfbfSEd Maste #include "lldb/Target/Thread.h" 331c3bbb01SEd Maste #include "lldb/Target/UnixSignals.h" 34ac7ddfbfSEd Maste 35ac7ddfbfSEd Maste using namespace lldb; 36ac7ddfbfSEd Maste using namespace lldb_private; 37ac7ddfbfSEd Maste 38ac7ddfbfSEd Maste class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed 39ac7ddfbfSEd Maste { 40ac7ddfbfSEd Maste public: 41ac7ddfbfSEd Maste CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter, 42ac7ddfbfSEd Maste const char *name, 43ac7ddfbfSEd Maste const char *help, 44ac7ddfbfSEd Maste const char *syntax, 45ac7ddfbfSEd Maste uint32_t flags, 46ac7ddfbfSEd Maste const char *new_process_action) : 47ac7ddfbfSEd Maste CommandObjectParsed (interpreter, name, help, syntax, flags), 48ac7ddfbfSEd Maste m_new_process_action (new_process_action) {} 49ac7ddfbfSEd Maste 50ac7ddfbfSEd Maste virtual ~CommandObjectProcessLaunchOrAttach () {} 51ac7ddfbfSEd Maste protected: 52ac7ddfbfSEd Maste bool 5312b93ac6SEd Maste StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result) 54ac7ddfbfSEd Maste { 55ac7ddfbfSEd Maste state = eStateInvalid; 56ac7ddfbfSEd Maste if (process) 57ac7ddfbfSEd Maste { 58ac7ddfbfSEd Maste state = process->GetState(); 59ac7ddfbfSEd Maste 60ac7ddfbfSEd Maste if (process->IsAlive() && state != eStateConnected) 61ac7ddfbfSEd Maste { 62ac7ddfbfSEd Maste char message[1024]; 63ac7ddfbfSEd Maste if (process->GetState() == eStateAttaching) 64ac7ddfbfSEd Maste ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str()); 65ac7ddfbfSEd Maste else if (process->GetShouldDetach()) 66ac7ddfbfSEd Maste ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str()); 67ac7ddfbfSEd Maste else 68ac7ddfbfSEd Maste ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str()); 69ac7ddfbfSEd Maste 70ac7ddfbfSEd Maste if (!m_interpreter.Confirm (message, true)) 71ac7ddfbfSEd Maste { 72ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 73ac7ddfbfSEd Maste return false; 74ac7ddfbfSEd Maste } 75ac7ddfbfSEd Maste else 76ac7ddfbfSEd Maste { 77ac7ddfbfSEd Maste if (process->GetShouldDetach()) 78ac7ddfbfSEd Maste { 79ac7ddfbfSEd Maste bool keep_stopped = false; 80ac7ddfbfSEd Maste Error detach_error (process->Detach(keep_stopped)); 81ac7ddfbfSEd Maste if (detach_error.Success()) 82ac7ddfbfSEd Maste { 83ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 84ac7ddfbfSEd Maste process = NULL; 85ac7ddfbfSEd Maste } 86ac7ddfbfSEd Maste else 87ac7ddfbfSEd Maste { 88ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString()); 89ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 90ac7ddfbfSEd Maste } 91ac7ddfbfSEd Maste } 92ac7ddfbfSEd Maste else 93ac7ddfbfSEd Maste { 941c3bbb01SEd Maste Error destroy_error (process->Destroy(false)); 95ac7ddfbfSEd Maste if (destroy_error.Success()) 96ac7ddfbfSEd Maste { 97ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 98ac7ddfbfSEd Maste process = NULL; 99ac7ddfbfSEd Maste } 100ac7ddfbfSEd Maste else 101ac7ddfbfSEd Maste { 102ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString()); 103ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 104ac7ddfbfSEd Maste } 105ac7ddfbfSEd Maste } 106ac7ddfbfSEd Maste } 107ac7ddfbfSEd Maste } 108ac7ddfbfSEd Maste } 109ac7ddfbfSEd Maste return result.Succeeded(); 110ac7ddfbfSEd Maste } 111ac7ddfbfSEd Maste std::string m_new_process_action; 112ac7ddfbfSEd Maste }; 113ac7ddfbfSEd Maste //------------------------------------------------------------------------- 114ac7ddfbfSEd Maste // CommandObjectProcessLaunch 115ac7ddfbfSEd Maste //------------------------------------------------------------------------- 116ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLaunch 117ac7ddfbfSEd Maste class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach 118ac7ddfbfSEd Maste { 119ac7ddfbfSEd Maste public: 120ac7ddfbfSEd Maste 121ac7ddfbfSEd Maste CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 122ac7ddfbfSEd Maste CommandObjectProcessLaunchOrAttach (interpreter, 123ac7ddfbfSEd Maste "process launch", 124ac7ddfbfSEd Maste "Launch the executable in the debugger.", 125ac7ddfbfSEd Maste NULL, 1261c3bbb01SEd Maste eCommandRequiresTarget, 127ac7ddfbfSEd Maste "restart"), 128ac7ddfbfSEd Maste m_options (interpreter) 129ac7ddfbfSEd Maste { 130ac7ddfbfSEd Maste CommandArgumentEntry arg; 131ac7ddfbfSEd Maste CommandArgumentData run_args_arg; 132ac7ddfbfSEd Maste 133ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 134ac7ddfbfSEd Maste run_args_arg.arg_type = eArgTypeRunArgs; 135ac7ddfbfSEd Maste run_args_arg.arg_repetition = eArgRepeatOptional; 136ac7ddfbfSEd Maste 137ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 138ac7ddfbfSEd Maste arg.push_back (run_args_arg); 139ac7ddfbfSEd Maste 140ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 141ac7ddfbfSEd Maste m_arguments.push_back (arg); 142ac7ddfbfSEd Maste } 143ac7ddfbfSEd Maste 144ac7ddfbfSEd Maste 145ac7ddfbfSEd Maste ~CommandObjectProcessLaunch () 146ac7ddfbfSEd Maste { 147ac7ddfbfSEd Maste } 148ac7ddfbfSEd Maste 149ac7ddfbfSEd Maste virtual int 150ac7ddfbfSEd Maste HandleArgumentCompletion (Args &input, 151ac7ddfbfSEd Maste int &cursor_index, 152ac7ddfbfSEd Maste int &cursor_char_position, 153ac7ddfbfSEd Maste OptionElementVector &opt_element_vector, 154ac7ddfbfSEd Maste int match_start_point, 155ac7ddfbfSEd Maste int max_return_elements, 156ac7ddfbfSEd Maste bool &word_complete, 157ac7ddfbfSEd Maste StringList &matches) 158ac7ddfbfSEd Maste { 159ac7ddfbfSEd Maste std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 160ac7ddfbfSEd Maste completion_str.erase (cursor_char_position); 161ac7ddfbfSEd Maste 162ac7ddfbfSEd Maste CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 163ac7ddfbfSEd Maste CommandCompletions::eDiskFileCompletion, 164ac7ddfbfSEd Maste completion_str.c_str(), 165ac7ddfbfSEd Maste match_start_point, 166ac7ddfbfSEd Maste max_return_elements, 167ac7ddfbfSEd Maste NULL, 168ac7ddfbfSEd Maste word_complete, 169ac7ddfbfSEd Maste matches); 170ac7ddfbfSEd Maste return matches.GetSize(); 171ac7ddfbfSEd Maste } 172ac7ddfbfSEd Maste 173ac7ddfbfSEd Maste Options * 174ac7ddfbfSEd Maste GetOptions () 175ac7ddfbfSEd Maste { 176ac7ddfbfSEd Maste return &m_options; 177ac7ddfbfSEd Maste } 178ac7ddfbfSEd Maste 179ac7ddfbfSEd Maste virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 180ac7ddfbfSEd Maste { 181ac7ddfbfSEd Maste // No repeat for "process launch"... 182ac7ddfbfSEd Maste return ""; 183ac7ddfbfSEd Maste } 184ac7ddfbfSEd Maste 185ac7ddfbfSEd Maste protected: 186ac7ddfbfSEd Maste bool 187ac7ddfbfSEd Maste DoExecute (Args& launch_args, CommandReturnObject &result) 188ac7ddfbfSEd Maste { 189ac7ddfbfSEd Maste Debugger &debugger = m_interpreter.GetDebugger(); 190ac7ddfbfSEd Maste Target *target = debugger.GetSelectedTarget().get(); 191ac7ddfbfSEd Maste // If our listener is NULL, users aren't allows to launch 19212b93ac6SEd Maste ModuleSP exe_module_sp = target->GetExecutableModule(); 193ac7ddfbfSEd Maste 19412b93ac6SEd Maste if (exe_module_sp == NULL) 195ac7ddfbfSEd Maste { 196ac7ddfbfSEd Maste result.AppendError ("no file in target, create a debug target using the 'target create' command"); 197ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 198ac7ddfbfSEd Maste return false; 199ac7ddfbfSEd Maste } 200ac7ddfbfSEd Maste 201ac7ddfbfSEd Maste StateType state = eStateInvalid; 202ac7ddfbfSEd Maste 20312b93ac6SEd Maste if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result)) 204ac7ddfbfSEd Maste return false; 205ac7ddfbfSEd Maste 206ac7ddfbfSEd Maste const char *target_settings_argv0 = target->GetArg0(); 207ac7ddfbfSEd Maste 2080127ef0fSEd Maste // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it). 2090127ef0fSEd Maste // First check if the process launch options explicitly turn on/off disabling ASLR. If so, use that setting; 2100127ef0fSEd Maste // otherwise, use the 'settings target.disable-aslr' setting. 2110127ef0fSEd Maste bool disable_aslr = false; 2120127ef0fSEd Maste if (m_options.disable_aslr != eLazyBoolCalculate) 2130127ef0fSEd Maste { 2140127ef0fSEd Maste // The user specified an explicit setting on the process launch line. Use it. 2150127ef0fSEd Maste disable_aslr = (m_options.disable_aslr == eLazyBoolYes); 2160127ef0fSEd Maste } 2170127ef0fSEd Maste else 2180127ef0fSEd Maste { 2190127ef0fSEd Maste // The user did not explicitly specify whether to disable ASLR. Fall back to the target.disable-aslr setting. 2200127ef0fSEd Maste disable_aslr = target->GetDisableASLR (); 2210127ef0fSEd Maste } 2220127ef0fSEd Maste 2230127ef0fSEd Maste if (disable_aslr) 22412b93ac6SEd Maste m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 2250127ef0fSEd Maste else 2260127ef0fSEd Maste m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); 2270127ef0fSEd Maste 2280127ef0fSEd Maste if (target->GetDetachOnError()) 2290127ef0fSEd Maste m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError); 23012b93ac6SEd Maste 23112b93ac6SEd Maste if (target->GetDisableSTDIO()) 23212b93ac6SEd Maste m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO); 23312b93ac6SEd Maste 23412b93ac6SEd Maste Args environment; 23512b93ac6SEd Maste target->GetEnvironmentAsArgs (environment); 23612b93ac6SEd Maste if (environment.GetArgumentCount() > 0) 23712b93ac6SEd Maste m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment); 238ac7ddfbfSEd Maste 239ac7ddfbfSEd Maste if (target_settings_argv0) 240ac7ddfbfSEd Maste { 241ac7ddfbfSEd Maste m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0); 24212b93ac6SEd Maste m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false); 243ac7ddfbfSEd Maste } 244ac7ddfbfSEd Maste else 245ac7ddfbfSEd Maste { 24612b93ac6SEd Maste m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true); 247ac7ddfbfSEd Maste } 248ac7ddfbfSEd Maste 249ac7ddfbfSEd Maste if (launch_args.GetArgumentCount() == 0) 250ac7ddfbfSEd Maste { 2511c3bbb01SEd Maste m_options.launch_info.GetArguments().AppendArguments (target->GetProcessLaunchInfo().GetArguments()); 252ac7ddfbfSEd Maste } 253ac7ddfbfSEd Maste else 254ac7ddfbfSEd Maste { 255ac7ddfbfSEd Maste m_options.launch_info.GetArguments().AppendArguments (launch_args); 256ac7ddfbfSEd Maste // Save the arguments for subsequent runs in the current target. 257ac7ddfbfSEd Maste target->SetRunArguments (launch_args); 258ac7ddfbfSEd Maste } 259ac7ddfbfSEd Maste 2607aa51b79SEd Maste StreamString stream; 2617aa51b79SEd Maste Error error = target->Launch(m_options.launch_info, &stream); 262ac7ddfbfSEd Maste 263ac7ddfbfSEd Maste if (error.Success()) 264ac7ddfbfSEd Maste { 26512b93ac6SEd Maste ProcessSP process_sp (target->GetProcessSP()); 26612b93ac6SEd Maste if (process_sp) 267ac7ddfbfSEd Maste { 2681c3bbb01SEd Maste // There is a race condition where this thread will return up the call stack to the main command 2691c3bbb01SEd Maste // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has 2701c3bbb01SEd Maste // a chance to call PushProcessIOHandler(). 2711c3bbb01SEd Maste process_sp->SyncIOHandler (0, 2000); 2721c3bbb01SEd Maste 2737aa51b79SEd Maste const char *data = stream.GetData(); 2747aa51b79SEd Maste if (data && strlen(data) > 0) 2757aa51b79SEd Maste result.AppendMessage(stream.GetData()); 2761c3bbb01SEd Maste const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName(); 27712b93ac6SEd Maste result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname); 278ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 27912b93ac6SEd Maste result.SetDidChangeProcessState (true); 280ac7ddfbfSEd Maste } 281ac7ddfbfSEd Maste else 282ac7ddfbfSEd Maste { 28312b93ac6SEd Maste result.AppendError("no error returned from Target::Launch, and target has no process"); 284ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 285ac7ddfbfSEd Maste } 286ac7ddfbfSEd Maste } 287ac7ddfbfSEd Maste else 288ac7ddfbfSEd Maste { 28912b93ac6SEd Maste result.AppendError(error.AsCString()); 290ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 291ac7ddfbfSEd Maste } 292ac7ddfbfSEd Maste return result.Succeeded(); 293ac7ddfbfSEd Maste } 294ac7ddfbfSEd Maste 295ac7ddfbfSEd Maste protected: 296ac7ddfbfSEd Maste ProcessLaunchCommandOptions m_options; 297ac7ddfbfSEd Maste }; 298ac7ddfbfSEd Maste 299ac7ddfbfSEd Maste 300ac7ddfbfSEd Maste //#define SET1 LLDB_OPT_SET_1 301ac7ddfbfSEd Maste //#define SET2 LLDB_OPT_SET_2 302ac7ddfbfSEd Maste //#define SET3 LLDB_OPT_SET_3 303ac7ddfbfSEd Maste // 304ac7ddfbfSEd Maste //OptionDefinition 305ac7ddfbfSEd Maste //CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 306ac7ddfbfSEd Maste //{ 30735617911SEd Maste //{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 30835617911SEd Maste //{ SET1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."}, 30935617911SEd Maste //{ SET1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."}, 31035617911SEd Maste //{ SET1 , false, "stderr", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."}, 31135617911SEd Maste //{ SET1 | SET2 | SET3, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 31235617911SEd Maste //{ SET2 , false, "tty", 't', OptionParser::eOptionalArgument, 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."}, 31335617911SEd Maste //{ SET3, false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, 31435617911SEd Maste //{ SET1 | SET2 | SET3, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."}, 315ac7ddfbfSEd Maste //{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 316ac7ddfbfSEd Maste //}; 317ac7ddfbfSEd Maste // 318ac7ddfbfSEd Maste //#undef SET1 319ac7ddfbfSEd Maste //#undef SET2 320ac7ddfbfSEd Maste //#undef SET3 321ac7ddfbfSEd Maste 322ac7ddfbfSEd Maste //------------------------------------------------------------------------- 323ac7ddfbfSEd Maste // CommandObjectProcessAttach 324ac7ddfbfSEd Maste //------------------------------------------------------------------------- 325ac7ddfbfSEd Maste #pragma mark CommandObjectProcessAttach 326ac7ddfbfSEd Maste class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach 327ac7ddfbfSEd Maste { 328ac7ddfbfSEd Maste public: 329ac7ddfbfSEd Maste 330ac7ddfbfSEd Maste class CommandOptions : public Options 331ac7ddfbfSEd Maste { 332ac7ddfbfSEd Maste public: 333ac7ddfbfSEd Maste 334ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 335ac7ddfbfSEd Maste Options(interpreter) 336ac7ddfbfSEd Maste { 337ac7ddfbfSEd Maste // Keep default values of all options in one place: OptionParsingStarting () 338ac7ddfbfSEd Maste OptionParsingStarting (); 339ac7ddfbfSEd Maste } 340ac7ddfbfSEd Maste 341ac7ddfbfSEd Maste ~CommandOptions () 342ac7ddfbfSEd Maste { 343ac7ddfbfSEd Maste } 344ac7ddfbfSEd Maste 345ac7ddfbfSEd Maste Error 346ac7ddfbfSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) 347ac7ddfbfSEd Maste { 348ac7ddfbfSEd Maste Error error; 349ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 350ac7ddfbfSEd Maste bool success = false; 351ac7ddfbfSEd Maste switch (short_option) 352ac7ddfbfSEd Maste { 353ac7ddfbfSEd Maste case 'c': 354ac7ddfbfSEd Maste attach_info.SetContinueOnceAttached(true); 355ac7ddfbfSEd Maste break; 356ac7ddfbfSEd Maste 357ac7ddfbfSEd Maste case 'p': 358ac7ddfbfSEd Maste { 3591c3bbb01SEd Maste lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 360ac7ddfbfSEd Maste if (!success || pid == LLDB_INVALID_PROCESS_ID) 361ac7ddfbfSEd Maste { 362ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg); 363ac7ddfbfSEd Maste } 364ac7ddfbfSEd Maste else 365ac7ddfbfSEd Maste { 366ac7ddfbfSEd Maste attach_info.SetProcessID (pid); 367ac7ddfbfSEd Maste } 368ac7ddfbfSEd Maste } 369ac7ddfbfSEd Maste break; 370ac7ddfbfSEd Maste 371ac7ddfbfSEd Maste case 'P': 372ac7ddfbfSEd Maste attach_info.SetProcessPluginName (option_arg); 373ac7ddfbfSEd Maste break; 374ac7ddfbfSEd Maste 375ac7ddfbfSEd Maste case 'n': 376ac7ddfbfSEd Maste attach_info.GetExecutableFile().SetFile(option_arg, false); 377ac7ddfbfSEd Maste break; 378ac7ddfbfSEd Maste 379ac7ddfbfSEd Maste case 'w': 380ac7ddfbfSEd Maste attach_info.SetWaitForLaunch(true); 381ac7ddfbfSEd Maste break; 382ac7ddfbfSEd Maste 383ac7ddfbfSEd Maste case 'i': 384ac7ddfbfSEd Maste attach_info.SetIgnoreExisting(false); 385ac7ddfbfSEd Maste break; 386ac7ddfbfSEd Maste 387ac7ddfbfSEd Maste default: 388ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 389ac7ddfbfSEd Maste break; 390ac7ddfbfSEd Maste } 391ac7ddfbfSEd Maste return error; 392ac7ddfbfSEd Maste } 393ac7ddfbfSEd Maste 394ac7ddfbfSEd Maste void 395ac7ddfbfSEd Maste OptionParsingStarting () 396ac7ddfbfSEd Maste { 397ac7ddfbfSEd Maste attach_info.Clear(); 398ac7ddfbfSEd Maste } 399ac7ddfbfSEd Maste 400ac7ddfbfSEd Maste const OptionDefinition* 401ac7ddfbfSEd Maste GetDefinitions () 402ac7ddfbfSEd Maste { 403ac7ddfbfSEd Maste return g_option_table; 404ac7ddfbfSEd Maste } 405ac7ddfbfSEd Maste 406ac7ddfbfSEd Maste virtual bool 407ac7ddfbfSEd Maste HandleOptionArgumentCompletion (Args &input, 408ac7ddfbfSEd Maste int cursor_index, 409ac7ddfbfSEd Maste int char_pos, 410ac7ddfbfSEd Maste OptionElementVector &opt_element_vector, 411ac7ddfbfSEd Maste int opt_element_index, 412ac7ddfbfSEd Maste int match_start_point, 413ac7ddfbfSEd Maste int max_return_elements, 414ac7ddfbfSEd Maste bool &word_complete, 415ac7ddfbfSEd Maste StringList &matches) 416ac7ddfbfSEd Maste { 417ac7ddfbfSEd Maste int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 418ac7ddfbfSEd Maste int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 419ac7ddfbfSEd Maste 420ac7ddfbfSEd Maste // We are only completing the name option for now... 421ac7ddfbfSEd Maste 422ac7ddfbfSEd Maste const OptionDefinition *opt_defs = GetDefinitions(); 423ac7ddfbfSEd Maste if (opt_defs[opt_defs_index].short_option == 'n') 424ac7ddfbfSEd Maste { 425ac7ddfbfSEd Maste // Are we in the name? 426ac7ddfbfSEd Maste 427ac7ddfbfSEd Maste // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 428ac7ddfbfSEd Maste // use the default plugin. 429ac7ddfbfSEd Maste 430ac7ddfbfSEd Maste const char *partial_name = NULL; 431ac7ddfbfSEd Maste partial_name = input.GetArgumentAtIndex(opt_arg_pos); 432ac7ddfbfSEd Maste 433ac7ddfbfSEd Maste PlatformSP platform_sp (m_interpreter.GetPlatform (true)); 434ac7ddfbfSEd Maste if (platform_sp) 435ac7ddfbfSEd Maste { 436ac7ddfbfSEd Maste ProcessInstanceInfoList process_infos; 437ac7ddfbfSEd Maste ProcessInstanceInfoMatch match_info; 438ac7ddfbfSEd Maste if (partial_name) 439ac7ddfbfSEd Maste { 440ac7ddfbfSEd Maste match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false); 441ac7ddfbfSEd Maste match_info.SetNameMatchType(eNameMatchStartsWith); 442ac7ddfbfSEd Maste } 443ac7ddfbfSEd Maste platform_sp->FindProcesses (match_info, process_infos); 444ac7ddfbfSEd Maste const size_t num_matches = process_infos.GetSize(); 445ac7ddfbfSEd Maste if (num_matches > 0) 446ac7ddfbfSEd Maste { 447ac7ddfbfSEd Maste for (size_t i=0; i<num_matches; ++i) 448ac7ddfbfSEd Maste { 449ac7ddfbfSEd Maste matches.AppendString (process_infos.GetProcessNameAtIndex(i), 450ac7ddfbfSEd Maste process_infos.GetProcessNameLengthAtIndex(i)); 451ac7ddfbfSEd Maste } 452ac7ddfbfSEd Maste } 453ac7ddfbfSEd Maste } 454ac7ddfbfSEd Maste } 455ac7ddfbfSEd Maste 456ac7ddfbfSEd Maste return false; 457ac7ddfbfSEd Maste } 458ac7ddfbfSEd Maste 459ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 460ac7ddfbfSEd Maste 461ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 462ac7ddfbfSEd Maste 463ac7ddfbfSEd Maste // Instance variables to hold the values for command options. 464ac7ddfbfSEd Maste 465ac7ddfbfSEd Maste ProcessAttachInfo attach_info; 466ac7ddfbfSEd Maste }; 467ac7ddfbfSEd Maste 468ac7ddfbfSEd Maste CommandObjectProcessAttach (CommandInterpreter &interpreter) : 469ac7ddfbfSEd Maste CommandObjectProcessLaunchOrAttach (interpreter, 470ac7ddfbfSEd Maste "process attach", 471ac7ddfbfSEd Maste "Attach to a process.", 472ac7ddfbfSEd Maste "process attach <cmd-options>", 473ac7ddfbfSEd Maste 0, 474ac7ddfbfSEd Maste "attach"), 475ac7ddfbfSEd Maste m_options (interpreter) 476ac7ddfbfSEd Maste { 477ac7ddfbfSEd Maste } 478ac7ddfbfSEd Maste 479ac7ddfbfSEd Maste ~CommandObjectProcessAttach () 480ac7ddfbfSEd Maste { 481ac7ddfbfSEd Maste } 482ac7ddfbfSEd Maste 483ac7ddfbfSEd Maste Options * 484ac7ddfbfSEd Maste GetOptions () 485ac7ddfbfSEd Maste { 486ac7ddfbfSEd Maste return &m_options; 487ac7ddfbfSEd Maste } 488ac7ddfbfSEd Maste 489ac7ddfbfSEd Maste protected: 490ac7ddfbfSEd Maste bool 491ac7ddfbfSEd Maste DoExecute (Args& command, 492ac7ddfbfSEd Maste CommandReturnObject &result) 493ac7ddfbfSEd Maste { 4941c3bbb01SEd Maste PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); 4951c3bbb01SEd Maste 496ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 497ac7ddfbfSEd Maste // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach 498ac7ddfbfSEd Maste // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop 499ac7ddfbfSEd Maste // ourselves here. 500ac7ddfbfSEd Maste 501ac7ddfbfSEd Maste StateType state = eStateInvalid; 502ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 503ac7ddfbfSEd Maste 504ac7ddfbfSEd Maste if (!StopProcessIfNecessary (process, state, result)) 505ac7ddfbfSEd Maste return false; 506ac7ddfbfSEd Maste 507ac7ddfbfSEd Maste if (target == NULL) 508ac7ddfbfSEd Maste { 509ac7ddfbfSEd Maste // If there isn't a current target create one. 510ac7ddfbfSEd Maste TargetSP new_target_sp; 511ac7ddfbfSEd Maste Error error; 512ac7ddfbfSEd Maste 513ac7ddfbfSEd Maste error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 514ac7ddfbfSEd Maste NULL, 515ac7ddfbfSEd Maste NULL, 516ac7ddfbfSEd Maste false, 517ac7ddfbfSEd Maste NULL, // No platform options 518ac7ddfbfSEd Maste new_target_sp); 519ac7ddfbfSEd Maste target = new_target_sp.get(); 520ac7ddfbfSEd Maste if (target == NULL || error.Fail()) 521ac7ddfbfSEd Maste { 522ac7ddfbfSEd Maste result.AppendError(error.AsCString("Error creating target")); 523ac7ddfbfSEd Maste return false; 524ac7ddfbfSEd Maste } 525ac7ddfbfSEd Maste m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 526ac7ddfbfSEd Maste } 527ac7ddfbfSEd Maste 528ac7ddfbfSEd Maste // Record the old executable module, we want to issue a warning if the process of attaching changed the 529ac7ddfbfSEd Maste // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 530ac7ddfbfSEd Maste 531ac7ddfbfSEd Maste ModuleSP old_exec_module_sp = target->GetExecutableModule(); 532ac7ddfbfSEd Maste ArchSpec old_arch_spec = target->GetArchitecture(); 533ac7ddfbfSEd Maste 534ac7ddfbfSEd Maste if (command.GetArgumentCount()) 535ac7ddfbfSEd Maste { 536ac7ddfbfSEd Maste result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 537ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 5381c3bbb01SEd Maste return false; 539ac7ddfbfSEd Maste } 540ac7ddfbfSEd Maste 5411c3bbb01SEd Maste m_interpreter.UpdateExecutionContext(nullptr); 5427aa51b79SEd Maste StreamString stream; 5431c3bbb01SEd Maste const auto error = target->Attach(m_options.attach_info, &stream); 5441c3bbb01SEd Maste if (error.Success()) 5451c3bbb01SEd Maste { 5461c3bbb01SEd Maste ProcessSP process_sp (target->GetProcessSP()); 5471c3bbb01SEd Maste if (process_sp) 5481c3bbb01SEd Maste { 5497aa51b79SEd Maste if (stream.GetData()) 5507aa51b79SEd Maste result.AppendMessage(stream.GetData()); 551ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishNoResult); 5521c3bbb01SEd Maste result.SetDidChangeProcessState (true); 553ac7ddfbfSEd Maste } 554ac7ddfbfSEd Maste else 555ac7ddfbfSEd Maste { 5561c3bbb01SEd Maste result.AppendError("no error returned from Target::Attach, and target has no process"); 557ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 55812b93ac6SEd Maste } 55912b93ac6SEd Maste } 56012b93ac6SEd Maste else 56112b93ac6SEd Maste { 56212b93ac6SEd Maste result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString()); 56312b93ac6SEd Maste result.SetStatus (eReturnStatusFailed); 564ac7ddfbfSEd Maste } 565ac7ddfbfSEd Maste 5661c3bbb01SEd Maste if (!result.Succeeded()) 5671c3bbb01SEd Maste return false; 5681c3bbb01SEd Maste 569ac7ddfbfSEd Maste // Okay, we're done. Last step is to warn if the executable module has changed: 570ac7ddfbfSEd Maste char new_path[PATH_MAX]; 571ac7ddfbfSEd Maste ModuleSP new_exec_module_sp (target->GetExecutableModule()); 572ac7ddfbfSEd Maste if (!old_exec_module_sp) 573ac7ddfbfSEd Maste { 574ac7ddfbfSEd Maste // We might not have a module if we attached to a raw pid... 575ac7ddfbfSEd Maste if (new_exec_module_sp) 576ac7ddfbfSEd Maste { 577ac7ddfbfSEd Maste new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 578ac7ddfbfSEd Maste result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path); 579ac7ddfbfSEd Maste } 580ac7ddfbfSEd Maste } 581ac7ddfbfSEd Maste else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec()) 582ac7ddfbfSEd Maste { 583ac7ddfbfSEd Maste char old_path[PATH_MAX]; 584ac7ddfbfSEd Maste 585ac7ddfbfSEd Maste old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX); 586ac7ddfbfSEd Maste new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX); 587ac7ddfbfSEd Maste 588ac7ddfbfSEd Maste result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 589ac7ddfbfSEd Maste old_path, new_path); 590ac7ddfbfSEd Maste } 591ac7ddfbfSEd Maste 592ac7ddfbfSEd Maste if (!old_arch_spec.IsValid()) 593ac7ddfbfSEd Maste { 594ac7ddfbfSEd Maste result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str()); 595ac7ddfbfSEd Maste } 596ac7ddfbfSEd Maste else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) 597ac7ddfbfSEd Maste { 598ac7ddfbfSEd Maste result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 599ac7ddfbfSEd Maste old_arch_spec.GetTriple().getTriple().c_str(), 600ac7ddfbfSEd Maste target->GetArchitecture().GetTriple().getTriple().c_str()); 601ac7ddfbfSEd Maste } 602ac7ddfbfSEd Maste 603ac7ddfbfSEd Maste // This supports the use-case scenario of immediately continuing the process once attached. 604ac7ddfbfSEd Maste if (m_options.attach_info.GetContinueOnceAttached()) 605ac7ddfbfSEd Maste m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); 6061c3bbb01SEd Maste 607ac7ddfbfSEd Maste return result.Succeeded(); 608ac7ddfbfSEd Maste } 609ac7ddfbfSEd Maste 610ac7ddfbfSEd Maste CommandOptions m_options; 611ac7ddfbfSEd Maste }; 612ac7ddfbfSEd Maste 613ac7ddfbfSEd Maste 614ac7ddfbfSEd Maste OptionDefinition 615ac7ddfbfSEd Maste CommandObjectProcessAttach::CommandOptions::g_option_table[] = 616ac7ddfbfSEd Maste { 6170127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, 6180127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 6190127ef0fSEd Maste { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 6200127ef0fSEd Maste { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 6210127ef0fSEd Maste { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, 6220127ef0fSEd Maste { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."}, 6230127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 624ac7ddfbfSEd Maste }; 625ac7ddfbfSEd Maste 626ac7ddfbfSEd Maste //------------------------------------------------------------------------- 627ac7ddfbfSEd Maste // CommandObjectProcessContinue 628ac7ddfbfSEd Maste //------------------------------------------------------------------------- 629ac7ddfbfSEd Maste #pragma mark CommandObjectProcessContinue 630ac7ddfbfSEd Maste 631ac7ddfbfSEd Maste class CommandObjectProcessContinue : public CommandObjectParsed 632ac7ddfbfSEd Maste { 633ac7ddfbfSEd Maste public: 634ac7ddfbfSEd Maste 635ac7ddfbfSEd Maste CommandObjectProcessContinue (CommandInterpreter &interpreter) : 636ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 637ac7ddfbfSEd Maste "process continue", 638ac7ddfbfSEd Maste "Continue execution of all threads in the current process.", 639ac7ddfbfSEd Maste "process continue", 6401c3bbb01SEd Maste eCommandRequiresProcess | 6411c3bbb01SEd Maste eCommandTryTargetAPILock | 6421c3bbb01SEd Maste eCommandProcessMustBeLaunched | 6431c3bbb01SEd Maste eCommandProcessMustBePaused ), 644ac7ddfbfSEd Maste m_options(interpreter) 645ac7ddfbfSEd Maste { 646ac7ddfbfSEd Maste } 647ac7ddfbfSEd Maste 648ac7ddfbfSEd Maste 649ac7ddfbfSEd Maste ~CommandObjectProcessContinue () 650ac7ddfbfSEd Maste { 651ac7ddfbfSEd Maste } 652ac7ddfbfSEd Maste 653ac7ddfbfSEd Maste protected: 654ac7ddfbfSEd Maste 655ac7ddfbfSEd Maste class CommandOptions : public Options 656ac7ddfbfSEd Maste { 657ac7ddfbfSEd Maste public: 658ac7ddfbfSEd Maste 659ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 660ac7ddfbfSEd Maste Options(interpreter) 661ac7ddfbfSEd Maste { 662ac7ddfbfSEd Maste // Keep default values of all options in one place: OptionParsingStarting () 663ac7ddfbfSEd Maste OptionParsingStarting (); 664ac7ddfbfSEd Maste } 665ac7ddfbfSEd Maste 666ac7ddfbfSEd Maste ~CommandOptions () 667ac7ddfbfSEd Maste { 668ac7ddfbfSEd Maste } 669ac7ddfbfSEd Maste 670ac7ddfbfSEd Maste Error 671ac7ddfbfSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) 672ac7ddfbfSEd Maste { 673ac7ddfbfSEd Maste Error error; 674ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 675ac7ddfbfSEd Maste bool success = false; 676ac7ddfbfSEd Maste switch (short_option) 677ac7ddfbfSEd Maste { 678ac7ddfbfSEd Maste case 'i': 6791c3bbb01SEd Maste m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 680ac7ddfbfSEd Maste if (!success) 681ac7ddfbfSEd Maste error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg); 682ac7ddfbfSEd Maste break; 683ac7ddfbfSEd Maste 684ac7ddfbfSEd Maste default: 685ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 686ac7ddfbfSEd Maste break; 687ac7ddfbfSEd Maste } 688ac7ddfbfSEd Maste return error; 689ac7ddfbfSEd Maste } 690ac7ddfbfSEd Maste 691ac7ddfbfSEd Maste void 692ac7ddfbfSEd Maste OptionParsingStarting () 693ac7ddfbfSEd Maste { 694ac7ddfbfSEd Maste m_ignore = 0; 695ac7ddfbfSEd Maste } 696ac7ddfbfSEd Maste 697ac7ddfbfSEd Maste const OptionDefinition* 698ac7ddfbfSEd Maste GetDefinitions () 699ac7ddfbfSEd Maste { 700ac7ddfbfSEd Maste return g_option_table; 701ac7ddfbfSEd Maste } 702ac7ddfbfSEd Maste 703ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 704ac7ddfbfSEd Maste 705ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 706ac7ddfbfSEd Maste 707ac7ddfbfSEd Maste uint32_t m_ignore; 708ac7ddfbfSEd Maste }; 709ac7ddfbfSEd Maste 710ac7ddfbfSEd Maste bool 711ac7ddfbfSEd Maste DoExecute (Args& command, CommandReturnObject &result) 712ac7ddfbfSEd Maste { 713ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 714ac7ddfbfSEd Maste bool synchronous_execution = m_interpreter.GetSynchronous (); 715ac7ddfbfSEd Maste StateType state = process->GetState(); 716ac7ddfbfSEd Maste if (state == eStateStopped) 717ac7ddfbfSEd Maste { 718ac7ddfbfSEd Maste if (command.GetArgumentCount() != 0) 719ac7ddfbfSEd Maste { 720ac7ddfbfSEd Maste result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 721ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 722ac7ddfbfSEd Maste return false; 723ac7ddfbfSEd Maste } 724ac7ddfbfSEd Maste 725ac7ddfbfSEd Maste if (m_options.m_ignore > 0) 726ac7ddfbfSEd Maste { 727ac7ddfbfSEd Maste ThreadSP sel_thread_sp(process->GetThreadList().GetSelectedThread()); 728ac7ddfbfSEd Maste if (sel_thread_sp) 729ac7ddfbfSEd Maste { 730ac7ddfbfSEd Maste StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo(); 731ac7ddfbfSEd Maste if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint) 732ac7ddfbfSEd Maste { 733ac7ddfbfSEd Maste lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue(); 734ac7ddfbfSEd Maste BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id)); 735ac7ddfbfSEd Maste if (bp_site_sp) 736ac7ddfbfSEd Maste { 737ac7ddfbfSEd Maste const size_t num_owners = bp_site_sp->GetNumberOfOwners(); 738ac7ddfbfSEd Maste for (size_t i = 0; i < num_owners; i++) 739ac7ddfbfSEd Maste { 740ac7ddfbfSEd Maste Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 741ac7ddfbfSEd Maste if (!bp_ref.IsInternal()) 742ac7ddfbfSEd Maste { 743ac7ddfbfSEd Maste bp_ref.SetIgnoreCount(m_options.m_ignore); 744ac7ddfbfSEd Maste } 745ac7ddfbfSEd Maste } 746ac7ddfbfSEd Maste } 747ac7ddfbfSEd Maste } 748ac7ddfbfSEd Maste } 749ac7ddfbfSEd Maste } 750ac7ddfbfSEd Maste 751ac7ddfbfSEd Maste { // Scope for thread list mutex: 752ac7ddfbfSEd Maste Mutex::Locker locker (process->GetThreadList().GetMutex()); 753ac7ddfbfSEd Maste const uint32_t num_threads = process->GetThreadList().GetSize(); 754ac7ddfbfSEd Maste 755ac7ddfbfSEd Maste // Set the actions that the threads should each take when resuming 756ac7ddfbfSEd Maste for (uint32_t idx=0; idx<num_threads; ++idx) 757ac7ddfbfSEd Maste { 7580127ef0fSEd Maste const bool override_suspend = false; 7590127ef0fSEd Maste process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend); 760ac7ddfbfSEd Maste } 761ac7ddfbfSEd Maste } 762ac7ddfbfSEd Maste 7631c3bbb01SEd Maste const uint32_t iohandler_id = process->GetIOHandlerID(); 7641c3bbb01SEd Maste 7657aa51b79SEd Maste StreamString stream; 7667aa51b79SEd Maste Error error; 7677aa51b79SEd Maste if (synchronous_execution) 7687aa51b79SEd Maste error = process->ResumeSynchronous (&stream); 7697aa51b79SEd Maste else 7707aa51b79SEd Maste error = process->Resume (); 7710127ef0fSEd Maste 772ac7ddfbfSEd Maste if (error.Success()) 773ac7ddfbfSEd Maste { 7740127ef0fSEd Maste // There is a race condition where this thread will return up the call stack to the main command 7750127ef0fSEd Maste // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has 7760127ef0fSEd Maste // a chance to call PushProcessIOHandler(). 7771c3bbb01SEd Maste process->SyncIOHandler(iohandler_id, 2000); 7780127ef0fSEd Maste 779ac7ddfbfSEd Maste result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); 780ac7ddfbfSEd Maste if (synchronous_execution) 781ac7ddfbfSEd Maste { 7827aa51b79SEd Maste // If any state changed events had anything to say, add that to the result 7837aa51b79SEd Maste if (stream.GetData()) 7847aa51b79SEd Maste result.AppendMessage(stream.GetData()); 785ac7ddfbfSEd Maste 786ac7ddfbfSEd Maste result.SetDidChangeProcessState (true); 787ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishNoResult); 788ac7ddfbfSEd Maste } 789ac7ddfbfSEd Maste else 790ac7ddfbfSEd Maste { 791ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessContinuingNoResult); 792ac7ddfbfSEd Maste } 793ac7ddfbfSEd Maste } 794ac7ddfbfSEd Maste else 795ac7ddfbfSEd Maste { 796ac7ddfbfSEd Maste result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 797ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 798ac7ddfbfSEd Maste } 799ac7ddfbfSEd Maste } 800ac7ddfbfSEd Maste else 801ac7ddfbfSEd Maste { 802ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 803ac7ddfbfSEd Maste StateAsCString(state)); 804ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 805ac7ddfbfSEd Maste } 806ac7ddfbfSEd Maste return result.Succeeded(); 807ac7ddfbfSEd Maste } 808ac7ddfbfSEd Maste 809ac7ddfbfSEd Maste Options * 810ac7ddfbfSEd Maste GetOptions () 811ac7ddfbfSEd Maste { 812ac7ddfbfSEd Maste return &m_options; 813ac7ddfbfSEd Maste } 814ac7ddfbfSEd Maste 815ac7ddfbfSEd Maste CommandOptions m_options; 816ac7ddfbfSEd Maste 817ac7ddfbfSEd Maste }; 818ac7ddfbfSEd Maste 819ac7ddfbfSEd Maste OptionDefinition 820ac7ddfbfSEd Maste CommandObjectProcessContinue::CommandOptions::g_option_table[] = 821ac7ddfbfSEd Maste { 8220127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, 823ac7ddfbfSEd Maste "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."}, 8240127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 825ac7ddfbfSEd Maste }; 826ac7ddfbfSEd Maste 827ac7ddfbfSEd Maste //------------------------------------------------------------------------- 828ac7ddfbfSEd Maste // CommandObjectProcessDetach 829ac7ddfbfSEd Maste //------------------------------------------------------------------------- 830ac7ddfbfSEd Maste #pragma mark CommandObjectProcessDetach 831ac7ddfbfSEd Maste 832ac7ddfbfSEd Maste class CommandObjectProcessDetach : public CommandObjectParsed 833ac7ddfbfSEd Maste { 834ac7ddfbfSEd Maste public: 835ac7ddfbfSEd Maste class CommandOptions : public Options 836ac7ddfbfSEd Maste { 837ac7ddfbfSEd Maste public: 838ac7ddfbfSEd Maste 839ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 840ac7ddfbfSEd Maste Options (interpreter) 841ac7ddfbfSEd Maste { 842ac7ddfbfSEd Maste OptionParsingStarting (); 843ac7ddfbfSEd Maste } 844ac7ddfbfSEd Maste 845ac7ddfbfSEd Maste ~CommandOptions () 846ac7ddfbfSEd Maste { 847ac7ddfbfSEd Maste } 848ac7ddfbfSEd Maste 849ac7ddfbfSEd Maste Error 850ac7ddfbfSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) 851ac7ddfbfSEd Maste { 852ac7ddfbfSEd Maste Error error; 853ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 854ac7ddfbfSEd Maste 855ac7ddfbfSEd Maste switch (short_option) 856ac7ddfbfSEd Maste { 857ac7ddfbfSEd Maste case 's': 858ac7ddfbfSEd Maste bool tmp_result; 859ac7ddfbfSEd Maste bool success; 860ac7ddfbfSEd Maste tmp_result = Args::StringToBoolean(option_arg, false, &success); 861ac7ddfbfSEd Maste if (!success) 862ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg); 863ac7ddfbfSEd Maste else 864ac7ddfbfSEd Maste { 865ac7ddfbfSEd Maste if (tmp_result) 866ac7ddfbfSEd Maste m_keep_stopped = eLazyBoolYes; 867ac7ddfbfSEd Maste else 868ac7ddfbfSEd Maste m_keep_stopped = eLazyBoolNo; 869ac7ddfbfSEd Maste } 870ac7ddfbfSEd Maste break; 871ac7ddfbfSEd Maste default: 872ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 873ac7ddfbfSEd Maste break; 874ac7ddfbfSEd Maste } 875ac7ddfbfSEd Maste return error; 876ac7ddfbfSEd Maste } 877ac7ddfbfSEd Maste 878ac7ddfbfSEd Maste void 879ac7ddfbfSEd Maste OptionParsingStarting () 880ac7ddfbfSEd Maste { 881ac7ddfbfSEd Maste m_keep_stopped = eLazyBoolCalculate; 882ac7ddfbfSEd Maste } 883ac7ddfbfSEd Maste 884ac7ddfbfSEd Maste const OptionDefinition* 885ac7ddfbfSEd Maste GetDefinitions () 886ac7ddfbfSEd Maste { 887ac7ddfbfSEd Maste return g_option_table; 888ac7ddfbfSEd Maste } 889ac7ddfbfSEd Maste 890ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 891ac7ddfbfSEd Maste 892ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 893ac7ddfbfSEd Maste 894ac7ddfbfSEd Maste // Instance variables to hold the values for command options. 895ac7ddfbfSEd Maste LazyBool m_keep_stopped; 896ac7ddfbfSEd Maste }; 897ac7ddfbfSEd Maste 898ac7ddfbfSEd Maste CommandObjectProcessDetach (CommandInterpreter &interpreter) : 899ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 900ac7ddfbfSEd Maste "process detach", 901ac7ddfbfSEd Maste "Detach from the current process being debugged.", 902ac7ddfbfSEd Maste "process detach", 9031c3bbb01SEd Maste eCommandRequiresProcess | 9041c3bbb01SEd Maste eCommandTryTargetAPILock | 9051c3bbb01SEd Maste eCommandProcessMustBeLaunched), 906ac7ddfbfSEd Maste m_options(interpreter) 907ac7ddfbfSEd Maste { 908ac7ddfbfSEd Maste } 909ac7ddfbfSEd Maste 910ac7ddfbfSEd Maste ~CommandObjectProcessDetach () 911ac7ddfbfSEd Maste { 912ac7ddfbfSEd Maste } 913ac7ddfbfSEd Maste 914ac7ddfbfSEd Maste Options * 915ac7ddfbfSEd Maste GetOptions () 916ac7ddfbfSEd Maste { 917ac7ddfbfSEd Maste return &m_options; 918ac7ddfbfSEd Maste } 919ac7ddfbfSEd Maste 920ac7ddfbfSEd Maste 921ac7ddfbfSEd Maste protected: 922ac7ddfbfSEd Maste bool 923ac7ddfbfSEd Maste DoExecute (Args& command, CommandReturnObject &result) 924ac7ddfbfSEd Maste { 925ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 926ac7ddfbfSEd Maste // FIXME: This will be a Command Option: 927ac7ddfbfSEd Maste bool keep_stopped; 928ac7ddfbfSEd Maste if (m_options.m_keep_stopped == eLazyBoolCalculate) 929ac7ddfbfSEd Maste { 930ac7ddfbfSEd Maste // Check the process default: 931ac7ddfbfSEd Maste if (process->GetDetachKeepsStopped()) 932ac7ddfbfSEd Maste keep_stopped = true; 933ac7ddfbfSEd Maste else 934ac7ddfbfSEd Maste keep_stopped = false; 935ac7ddfbfSEd Maste } 936ac7ddfbfSEd Maste else if (m_options.m_keep_stopped == eLazyBoolYes) 937ac7ddfbfSEd Maste keep_stopped = true; 938ac7ddfbfSEd Maste else 939ac7ddfbfSEd Maste keep_stopped = false; 940ac7ddfbfSEd Maste 941ac7ddfbfSEd Maste Error error (process->Detach(keep_stopped)); 942ac7ddfbfSEd Maste if (error.Success()) 943ac7ddfbfSEd Maste { 944ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 945ac7ddfbfSEd Maste } 946ac7ddfbfSEd Maste else 947ac7ddfbfSEd Maste { 948ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 949ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 950ac7ddfbfSEd Maste return false; 951ac7ddfbfSEd Maste } 952ac7ddfbfSEd Maste return result.Succeeded(); 953ac7ddfbfSEd Maste } 954ac7ddfbfSEd Maste 955ac7ddfbfSEd Maste CommandOptions m_options; 956ac7ddfbfSEd Maste }; 957ac7ddfbfSEd Maste 958ac7ddfbfSEd Maste OptionDefinition 959ac7ddfbfSEd Maste CommandObjectProcessDetach::CommandOptions::g_option_table[] = 960ac7ddfbfSEd Maste { 9610127ef0fSEd Maste { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, 9620127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 963ac7ddfbfSEd Maste }; 964ac7ddfbfSEd Maste 965ac7ddfbfSEd Maste //------------------------------------------------------------------------- 966ac7ddfbfSEd Maste // CommandObjectProcessConnect 967ac7ddfbfSEd Maste //------------------------------------------------------------------------- 968ac7ddfbfSEd Maste #pragma mark CommandObjectProcessConnect 969ac7ddfbfSEd Maste 970ac7ddfbfSEd Maste class CommandObjectProcessConnect : public CommandObjectParsed 971ac7ddfbfSEd Maste { 972ac7ddfbfSEd Maste public: 973ac7ddfbfSEd Maste 974ac7ddfbfSEd Maste class CommandOptions : public Options 975ac7ddfbfSEd Maste { 976ac7ddfbfSEd Maste public: 977ac7ddfbfSEd Maste 978ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 979ac7ddfbfSEd Maste Options(interpreter) 980ac7ddfbfSEd Maste { 981ac7ddfbfSEd Maste // Keep default values of all options in one place: OptionParsingStarting () 982ac7ddfbfSEd Maste OptionParsingStarting (); 983ac7ddfbfSEd Maste } 984ac7ddfbfSEd Maste 985ac7ddfbfSEd Maste ~CommandOptions () 986ac7ddfbfSEd Maste { 987ac7ddfbfSEd Maste } 988ac7ddfbfSEd Maste 989ac7ddfbfSEd Maste Error 990ac7ddfbfSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) 991ac7ddfbfSEd Maste { 992ac7ddfbfSEd Maste Error error; 993ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 994ac7ddfbfSEd Maste 995ac7ddfbfSEd Maste switch (short_option) 996ac7ddfbfSEd Maste { 997ac7ddfbfSEd Maste case 'p': 998ac7ddfbfSEd Maste plugin_name.assign (option_arg); 999ac7ddfbfSEd Maste break; 1000ac7ddfbfSEd Maste 1001ac7ddfbfSEd Maste default: 1002ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1003ac7ddfbfSEd Maste break; 1004ac7ddfbfSEd Maste } 1005ac7ddfbfSEd Maste return error; 1006ac7ddfbfSEd Maste } 1007ac7ddfbfSEd Maste 1008ac7ddfbfSEd Maste void 1009ac7ddfbfSEd Maste OptionParsingStarting () 1010ac7ddfbfSEd Maste { 1011ac7ddfbfSEd Maste plugin_name.clear(); 1012ac7ddfbfSEd Maste } 1013ac7ddfbfSEd Maste 1014ac7ddfbfSEd Maste const OptionDefinition* 1015ac7ddfbfSEd Maste GetDefinitions () 1016ac7ddfbfSEd Maste { 1017ac7ddfbfSEd Maste return g_option_table; 1018ac7ddfbfSEd Maste } 1019ac7ddfbfSEd Maste 1020ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 1021ac7ddfbfSEd Maste 1022ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 1023ac7ddfbfSEd Maste 1024ac7ddfbfSEd Maste // Instance variables to hold the values for command options. 1025ac7ddfbfSEd Maste 1026ac7ddfbfSEd Maste std::string plugin_name; 1027ac7ddfbfSEd Maste }; 1028ac7ddfbfSEd Maste 1029ac7ddfbfSEd Maste CommandObjectProcessConnect (CommandInterpreter &interpreter) : 1030ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1031ac7ddfbfSEd Maste "process connect", 1032ac7ddfbfSEd Maste "Connect to a remote debug service.", 1033ac7ddfbfSEd Maste "process connect <remote-url>", 1034ac7ddfbfSEd Maste 0), 1035ac7ddfbfSEd Maste m_options (interpreter) 1036ac7ddfbfSEd Maste { 1037ac7ddfbfSEd Maste } 1038ac7ddfbfSEd Maste 1039ac7ddfbfSEd Maste ~CommandObjectProcessConnect () 1040ac7ddfbfSEd Maste { 1041ac7ddfbfSEd Maste } 1042ac7ddfbfSEd Maste 1043ac7ddfbfSEd Maste 1044ac7ddfbfSEd Maste Options * 1045ac7ddfbfSEd Maste GetOptions () 1046ac7ddfbfSEd Maste { 1047ac7ddfbfSEd Maste return &m_options; 1048ac7ddfbfSEd Maste } 1049ac7ddfbfSEd Maste 1050ac7ddfbfSEd Maste protected: 1051ac7ddfbfSEd Maste bool 1052ac7ddfbfSEd Maste DoExecute (Args& command, 1053ac7ddfbfSEd Maste CommandReturnObject &result) 1054ac7ddfbfSEd Maste { 1055ac7ddfbfSEd Maste 1056ac7ddfbfSEd Maste TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget()); 1057ac7ddfbfSEd Maste Error error; 1058ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1059ac7ddfbfSEd Maste if (process) 1060ac7ddfbfSEd Maste { 1061ac7ddfbfSEd Maste if (process->IsAlive()) 1062ac7ddfbfSEd Maste { 1063ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n", 1064ac7ddfbfSEd Maste process->GetID()); 1065ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1066ac7ddfbfSEd Maste return false; 1067ac7ddfbfSEd Maste } 1068ac7ddfbfSEd Maste } 1069ac7ddfbfSEd Maste 1070ac7ddfbfSEd Maste if (!target_sp) 1071ac7ddfbfSEd Maste { 1072ac7ddfbfSEd Maste // If there isn't a current target create one. 1073ac7ddfbfSEd Maste 1074ac7ddfbfSEd Maste error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 1075ac7ddfbfSEd Maste NULL, 1076ac7ddfbfSEd Maste NULL, 1077ac7ddfbfSEd Maste false, 1078ac7ddfbfSEd Maste NULL, // No platform options 1079ac7ddfbfSEd Maste target_sp); 1080ac7ddfbfSEd Maste if (!target_sp || error.Fail()) 1081ac7ddfbfSEd Maste { 1082ac7ddfbfSEd Maste result.AppendError(error.AsCString("Error creating target")); 1083ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1084ac7ddfbfSEd Maste return false; 1085ac7ddfbfSEd Maste } 1086ac7ddfbfSEd Maste m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get()); 1087ac7ddfbfSEd Maste } 1088ac7ddfbfSEd Maste 1089ac7ddfbfSEd Maste if (command.GetArgumentCount() == 1) 1090ac7ddfbfSEd Maste { 1091ac7ddfbfSEd Maste const char *plugin_name = NULL; 1092ac7ddfbfSEd Maste if (!m_options.plugin_name.empty()) 1093ac7ddfbfSEd Maste plugin_name = m_options.plugin_name.c_str(); 1094ac7ddfbfSEd Maste 1095ac7ddfbfSEd Maste const char *remote_url = command.GetArgumentAtIndex(0); 1096ac7ddfbfSEd Maste process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get(); 1097ac7ddfbfSEd Maste 1098ac7ddfbfSEd Maste if (process) 1099ac7ddfbfSEd Maste { 110012b93ac6SEd Maste error = process->ConnectRemote (process->GetTarget().GetDebugger().GetOutputFile().get(), remote_url); 1101ac7ddfbfSEd Maste 1102ac7ddfbfSEd Maste if (error.Fail()) 1103ac7ddfbfSEd Maste { 1104ac7ddfbfSEd Maste result.AppendError(error.AsCString("Remote connect failed")); 1105ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1106ac7ddfbfSEd Maste target_sp->DeleteCurrentProcess(); 1107ac7ddfbfSEd Maste return false; 1108ac7ddfbfSEd Maste } 1109ac7ddfbfSEd Maste } 1110ac7ddfbfSEd Maste else 1111ac7ddfbfSEd Maste { 1112ac7ddfbfSEd Maste 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", 1113ac7ddfbfSEd Maste remote_url); 1114ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1115ac7ddfbfSEd Maste } 1116ac7ddfbfSEd Maste } 1117ac7ddfbfSEd Maste else 1118ac7ddfbfSEd Maste { 1119ac7ddfbfSEd Maste result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n", 1120ac7ddfbfSEd Maste m_cmd_name.c_str(), 1121ac7ddfbfSEd Maste m_cmd_syntax.c_str()); 1122ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1123ac7ddfbfSEd Maste } 1124ac7ddfbfSEd Maste return result.Succeeded(); 1125ac7ddfbfSEd Maste } 1126ac7ddfbfSEd Maste 1127ac7ddfbfSEd Maste CommandOptions m_options; 1128ac7ddfbfSEd Maste }; 1129ac7ddfbfSEd Maste 1130ac7ddfbfSEd Maste OptionDefinition 1131ac7ddfbfSEd Maste CommandObjectProcessConnect::CommandOptions::g_option_table[] = 1132ac7ddfbfSEd Maste { 11330127ef0fSEd Maste { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 11340127ef0fSEd Maste { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } 1135ac7ddfbfSEd Maste }; 1136ac7ddfbfSEd Maste 1137ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1138ac7ddfbfSEd Maste // CommandObjectProcessPlugin 1139ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1140ac7ddfbfSEd Maste #pragma mark CommandObjectProcessPlugin 1141ac7ddfbfSEd Maste 1142ac7ddfbfSEd Maste class CommandObjectProcessPlugin : public CommandObjectProxy 1143ac7ddfbfSEd Maste { 1144ac7ddfbfSEd Maste public: 1145ac7ddfbfSEd Maste 1146ac7ddfbfSEd Maste CommandObjectProcessPlugin (CommandInterpreter &interpreter) : 1147ac7ddfbfSEd Maste CommandObjectProxy (interpreter, 1148ac7ddfbfSEd Maste "process plugin", 1149ac7ddfbfSEd Maste "Send a custom command to the current process plug-in.", 1150ac7ddfbfSEd Maste "process plugin <args>", 1151ac7ddfbfSEd Maste 0) 1152ac7ddfbfSEd Maste { 1153ac7ddfbfSEd Maste } 1154ac7ddfbfSEd Maste 1155ac7ddfbfSEd Maste ~CommandObjectProcessPlugin () 1156ac7ddfbfSEd Maste { 1157ac7ddfbfSEd Maste } 1158ac7ddfbfSEd Maste 1159ac7ddfbfSEd Maste virtual CommandObject * 1160ac7ddfbfSEd Maste GetProxyCommandObject() 1161ac7ddfbfSEd Maste { 1162ac7ddfbfSEd Maste Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1163ac7ddfbfSEd Maste if (process) 1164ac7ddfbfSEd Maste return process->GetPluginCommandObject(); 1165ac7ddfbfSEd Maste return NULL; 1166ac7ddfbfSEd Maste } 1167ac7ddfbfSEd Maste }; 1168ac7ddfbfSEd Maste 1169ac7ddfbfSEd Maste 1170ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1171ac7ddfbfSEd Maste // CommandObjectProcessLoad 1172ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1173ac7ddfbfSEd Maste #pragma mark CommandObjectProcessLoad 1174ac7ddfbfSEd Maste 1175ac7ddfbfSEd Maste class CommandObjectProcessLoad : public CommandObjectParsed 1176ac7ddfbfSEd Maste { 1177ac7ddfbfSEd Maste public: 1178ac7ddfbfSEd Maste 1179ac7ddfbfSEd Maste CommandObjectProcessLoad (CommandInterpreter &interpreter) : 1180ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1181ac7ddfbfSEd Maste "process load", 1182ac7ddfbfSEd Maste "Load a shared library into the current process.", 1183ac7ddfbfSEd Maste "process load <filename> [<filename> ...]", 11841c3bbb01SEd Maste eCommandRequiresProcess | 11851c3bbb01SEd Maste eCommandTryTargetAPILock | 11861c3bbb01SEd Maste eCommandProcessMustBeLaunched | 11871c3bbb01SEd Maste eCommandProcessMustBePaused ) 1188ac7ddfbfSEd Maste { 1189ac7ddfbfSEd Maste } 1190ac7ddfbfSEd Maste 1191ac7ddfbfSEd Maste ~CommandObjectProcessLoad () 1192ac7ddfbfSEd Maste { 1193ac7ddfbfSEd Maste } 1194ac7ddfbfSEd Maste 1195ac7ddfbfSEd Maste protected: 1196ac7ddfbfSEd Maste bool 1197ac7ddfbfSEd Maste DoExecute (Args& command, 1198ac7ddfbfSEd Maste CommandReturnObject &result) 1199ac7ddfbfSEd Maste { 1200ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1201ac7ddfbfSEd Maste 1202ac7ddfbfSEd Maste const size_t argc = command.GetArgumentCount(); 1203ac7ddfbfSEd Maste 1204ac7ddfbfSEd Maste for (uint32_t i=0; i<argc; ++i) 1205ac7ddfbfSEd Maste { 1206ac7ddfbfSEd Maste Error error; 1207ac7ddfbfSEd Maste const char *image_path = command.GetArgumentAtIndex(i); 1208ac7ddfbfSEd Maste FileSpec image_spec (image_path, false); 1209ac7ddfbfSEd Maste process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec); 1210ac7ddfbfSEd Maste uint32_t image_token = process->LoadImage(image_spec, error); 1211ac7ddfbfSEd Maste if (image_token != LLDB_INVALID_IMAGE_TOKEN) 1212ac7ddfbfSEd Maste { 1213ac7ddfbfSEd Maste result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 1214ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 1215ac7ddfbfSEd Maste } 1216ac7ddfbfSEd Maste else 1217ac7ddfbfSEd Maste { 1218ac7ddfbfSEd Maste result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 1219ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1220ac7ddfbfSEd Maste } 1221ac7ddfbfSEd Maste } 1222ac7ddfbfSEd Maste return result.Succeeded(); 1223ac7ddfbfSEd Maste } 1224ac7ddfbfSEd Maste }; 1225ac7ddfbfSEd Maste 1226ac7ddfbfSEd Maste 1227ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1228ac7ddfbfSEd Maste // CommandObjectProcessUnload 1229ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1230ac7ddfbfSEd Maste #pragma mark CommandObjectProcessUnload 1231ac7ddfbfSEd Maste 1232ac7ddfbfSEd Maste class CommandObjectProcessUnload : public CommandObjectParsed 1233ac7ddfbfSEd Maste { 1234ac7ddfbfSEd Maste public: 1235ac7ddfbfSEd Maste 1236ac7ddfbfSEd Maste CommandObjectProcessUnload (CommandInterpreter &interpreter) : 1237ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1238ac7ddfbfSEd Maste "process unload", 1239ac7ddfbfSEd Maste "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 1240ac7ddfbfSEd Maste "process unload <index>", 12411c3bbb01SEd Maste eCommandRequiresProcess | 12421c3bbb01SEd Maste eCommandTryTargetAPILock | 12431c3bbb01SEd Maste eCommandProcessMustBeLaunched | 12441c3bbb01SEd Maste eCommandProcessMustBePaused ) 1245ac7ddfbfSEd Maste { 1246ac7ddfbfSEd Maste } 1247ac7ddfbfSEd Maste 1248ac7ddfbfSEd Maste ~CommandObjectProcessUnload () 1249ac7ddfbfSEd Maste { 1250ac7ddfbfSEd Maste } 1251ac7ddfbfSEd Maste 1252ac7ddfbfSEd Maste protected: 1253ac7ddfbfSEd Maste bool 1254ac7ddfbfSEd Maste DoExecute (Args& command, 1255ac7ddfbfSEd Maste CommandReturnObject &result) 1256ac7ddfbfSEd Maste { 1257ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1258ac7ddfbfSEd Maste 1259ac7ddfbfSEd Maste const size_t argc = command.GetArgumentCount(); 1260ac7ddfbfSEd Maste 1261ac7ddfbfSEd Maste for (uint32_t i=0; i<argc; ++i) 1262ac7ddfbfSEd Maste { 1263ac7ddfbfSEd Maste const char *image_token_cstr = command.GetArgumentAtIndex(i); 12641c3bbb01SEd Maste uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 1265ac7ddfbfSEd Maste if (image_token == LLDB_INVALID_IMAGE_TOKEN) 1266ac7ddfbfSEd Maste { 1267ac7ddfbfSEd Maste result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 1268ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1269ac7ddfbfSEd Maste break; 1270ac7ddfbfSEd Maste } 1271ac7ddfbfSEd Maste else 1272ac7ddfbfSEd Maste { 1273ac7ddfbfSEd Maste Error error (process->UnloadImage(image_token)); 1274ac7ddfbfSEd Maste if (error.Success()) 1275ac7ddfbfSEd Maste { 1276ac7ddfbfSEd Maste result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 1277ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 1278ac7ddfbfSEd Maste } 1279ac7ddfbfSEd Maste else 1280ac7ddfbfSEd Maste { 1281ac7ddfbfSEd Maste result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 1282ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1283ac7ddfbfSEd Maste break; 1284ac7ddfbfSEd Maste } 1285ac7ddfbfSEd Maste } 1286ac7ddfbfSEd Maste } 1287ac7ddfbfSEd Maste return result.Succeeded(); 1288ac7ddfbfSEd Maste } 1289ac7ddfbfSEd Maste }; 1290ac7ddfbfSEd Maste 1291ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1292ac7ddfbfSEd Maste // CommandObjectProcessSignal 1293ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1294ac7ddfbfSEd Maste #pragma mark CommandObjectProcessSignal 1295ac7ddfbfSEd Maste 1296ac7ddfbfSEd Maste class CommandObjectProcessSignal : public CommandObjectParsed 1297ac7ddfbfSEd Maste { 1298ac7ddfbfSEd Maste public: 1299ac7ddfbfSEd Maste 1300ac7ddfbfSEd Maste CommandObjectProcessSignal (CommandInterpreter &interpreter) : 1301ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1302ac7ddfbfSEd Maste "process signal", 1303ac7ddfbfSEd Maste "Send a UNIX signal to the current process being debugged.", 1304ac7ddfbfSEd Maste NULL, 13051c3bbb01SEd Maste eCommandRequiresProcess | eCommandTryTargetAPILock) 1306ac7ddfbfSEd Maste { 1307ac7ddfbfSEd Maste CommandArgumentEntry arg; 1308ac7ddfbfSEd Maste CommandArgumentData signal_arg; 1309ac7ddfbfSEd Maste 1310ac7ddfbfSEd Maste // Define the first (and only) variant of this arg. 1311ac7ddfbfSEd Maste signal_arg.arg_type = eArgTypeUnixSignal; 1312ac7ddfbfSEd Maste signal_arg.arg_repetition = eArgRepeatPlain; 1313ac7ddfbfSEd Maste 1314ac7ddfbfSEd Maste // There is only one variant this argument could be; put it into the argument entry. 1315ac7ddfbfSEd Maste arg.push_back (signal_arg); 1316ac7ddfbfSEd Maste 1317ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector. 1318ac7ddfbfSEd Maste m_arguments.push_back (arg); 1319ac7ddfbfSEd Maste } 1320ac7ddfbfSEd Maste 1321ac7ddfbfSEd Maste ~CommandObjectProcessSignal () 1322ac7ddfbfSEd Maste { 1323ac7ddfbfSEd Maste } 1324ac7ddfbfSEd Maste 1325ac7ddfbfSEd Maste protected: 1326ac7ddfbfSEd Maste bool 1327ac7ddfbfSEd Maste DoExecute (Args& command, 1328ac7ddfbfSEd Maste CommandReturnObject &result) 1329ac7ddfbfSEd Maste { 1330ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1331ac7ddfbfSEd Maste 1332ac7ddfbfSEd Maste if (command.GetArgumentCount() == 1) 1333ac7ddfbfSEd Maste { 1334ac7ddfbfSEd Maste int signo = LLDB_INVALID_SIGNAL_NUMBER; 1335ac7ddfbfSEd Maste 1336ac7ddfbfSEd Maste const char *signal_name = command.GetArgumentAtIndex(0); 1337ac7ddfbfSEd Maste if (::isxdigit (signal_name[0])) 13381c3bbb01SEd Maste signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1339ac7ddfbfSEd Maste else 1340b91a7dfcSDimitry Andric signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); 1341ac7ddfbfSEd Maste 1342ac7ddfbfSEd Maste if (signo == LLDB_INVALID_SIGNAL_NUMBER) 1343ac7ddfbfSEd Maste { 1344ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 1345ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1346ac7ddfbfSEd Maste } 1347ac7ddfbfSEd Maste else 1348ac7ddfbfSEd Maste { 1349ac7ddfbfSEd Maste Error error (process->Signal (signo)); 1350ac7ddfbfSEd Maste if (error.Success()) 1351ac7ddfbfSEd Maste { 1352ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 1353ac7ddfbfSEd Maste } 1354ac7ddfbfSEd Maste else 1355ac7ddfbfSEd Maste { 1356ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 1357ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1358ac7ddfbfSEd Maste } 1359ac7ddfbfSEd Maste } 1360ac7ddfbfSEd Maste } 1361ac7ddfbfSEd Maste else 1362ac7ddfbfSEd Maste { 1363ac7ddfbfSEd Maste result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(), 1364ac7ddfbfSEd Maste m_cmd_syntax.c_str()); 1365ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1366ac7ddfbfSEd Maste } 1367ac7ddfbfSEd Maste return result.Succeeded(); 1368ac7ddfbfSEd Maste } 1369ac7ddfbfSEd Maste }; 1370ac7ddfbfSEd Maste 1371ac7ddfbfSEd Maste 1372ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1373ac7ddfbfSEd Maste // CommandObjectProcessInterrupt 1374ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1375ac7ddfbfSEd Maste #pragma mark CommandObjectProcessInterrupt 1376ac7ddfbfSEd Maste 1377ac7ddfbfSEd Maste class CommandObjectProcessInterrupt : public CommandObjectParsed 1378ac7ddfbfSEd Maste { 1379ac7ddfbfSEd Maste public: 1380ac7ddfbfSEd Maste 1381ac7ddfbfSEd Maste 1382ac7ddfbfSEd Maste CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 1383ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1384ac7ddfbfSEd Maste "process interrupt", 1385ac7ddfbfSEd Maste "Interrupt the current process being debugged.", 1386ac7ddfbfSEd Maste "process interrupt", 13871c3bbb01SEd Maste eCommandRequiresProcess | 13881c3bbb01SEd Maste eCommandTryTargetAPILock | 13891c3bbb01SEd Maste eCommandProcessMustBeLaunched) 1390ac7ddfbfSEd Maste { 1391ac7ddfbfSEd Maste } 1392ac7ddfbfSEd Maste 1393ac7ddfbfSEd Maste ~CommandObjectProcessInterrupt () 1394ac7ddfbfSEd Maste { 1395ac7ddfbfSEd Maste } 1396ac7ddfbfSEd Maste 1397ac7ddfbfSEd Maste protected: 1398ac7ddfbfSEd Maste bool 1399ac7ddfbfSEd Maste DoExecute (Args& command, 1400ac7ddfbfSEd Maste CommandReturnObject &result) 1401ac7ddfbfSEd Maste { 1402ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1403ac7ddfbfSEd Maste if (process == NULL) 1404ac7ddfbfSEd Maste { 1405ac7ddfbfSEd Maste result.AppendError ("no process to halt"); 1406ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1407ac7ddfbfSEd Maste return false; 1408ac7ddfbfSEd Maste } 1409ac7ddfbfSEd Maste 1410ac7ddfbfSEd Maste if (command.GetArgumentCount() == 0) 1411ac7ddfbfSEd Maste { 1412ac7ddfbfSEd Maste bool clear_thread_plans = true; 1413ac7ddfbfSEd Maste Error error(process->Halt (clear_thread_plans)); 1414ac7ddfbfSEd Maste if (error.Success()) 1415ac7ddfbfSEd Maste { 1416ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 1417ac7ddfbfSEd Maste } 1418ac7ddfbfSEd Maste else 1419ac7ddfbfSEd Maste { 1420ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 1421ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1422ac7ddfbfSEd Maste } 1423ac7ddfbfSEd Maste } 1424ac7ddfbfSEd Maste else 1425ac7ddfbfSEd Maste { 1426ac7ddfbfSEd Maste result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1427ac7ddfbfSEd Maste m_cmd_name.c_str(), 1428ac7ddfbfSEd Maste m_cmd_syntax.c_str()); 1429ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1430ac7ddfbfSEd Maste } 1431ac7ddfbfSEd Maste return result.Succeeded(); 1432ac7ddfbfSEd Maste } 1433ac7ddfbfSEd Maste }; 1434ac7ddfbfSEd Maste 1435ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1436ac7ddfbfSEd Maste // CommandObjectProcessKill 1437ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1438ac7ddfbfSEd Maste #pragma mark CommandObjectProcessKill 1439ac7ddfbfSEd Maste 1440ac7ddfbfSEd Maste class CommandObjectProcessKill : public CommandObjectParsed 1441ac7ddfbfSEd Maste { 1442ac7ddfbfSEd Maste public: 1443ac7ddfbfSEd Maste 1444ac7ddfbfSEd Maste CommandObjectProcessKill (CommandInterpreter &interpreter) : 1445ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1446ac7ddfbfSEd Maste "process kill", 1447ac7ddfbfSEd Maste "Terminate the current process being debugged.", 1448ac7ddfbfSEd Maste "process kill", 14491c3bbb01SEd Maste eCommandRequiresProcess | 14501c3bbb01SEd Maste eCommandTryTargetAPILock | 14511c3bbb01SEd Maste eCommandProcessMustBeLaunched) 1452ac7ddfbfSEd Maste { 1453ac7ddfbfSEd Maste } 1454ac7ddfbfSEd Maste 1455ac7ddfbfSEd Maste ~CommandObjectProcessKill () 1456ac7ddfbfSEd Maste { 1457ac7ddfbfSEd Maste } 1458ac7ddfbfSEd Maste 1459ac7ddfbfSEd Maste protected: 1460ac7ddfbfSEd Maste bool 1461ac7ddfbfSEd Maste DoExecute (Args& command, 1462ac7ddfbfSEd Maste CommandReturnObject &result) 1463ac7ddfbfSEd Maste { 1464ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1465ac7ddfbfSEd Maste if (process == NULL) 1466ac7ddfbfSEd Maste { 1467ac7ddfbfSEd Maste result.AppendError ("no process to kill"); 1468ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1469ac7ddfbfSEd Maste return false; 1470ac7ddfbfSEd Maste } 1471ac7ddfbfSEd Maste 1472ac7ddfbfSEd Maste if (command.GetArgumentCount() == 0) 1473ac7ddfbfSEd Maste { 14741c3bbb01SEd Maste Error error (process->Destroy(true)); 1475ac7ddfbfSEd Maste if (error.Success()) 1476ac7ddfbfSEd Maste { 1477ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 1478ac7ddfbfSEd Maste } 1479ac7ddfbfSEd Maste else 1480ac7ddfbfSEd Maste { 1481ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 1482ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1483ac7ddfbfSEd Maste } 1484ac7ddfbfSEd Maste } 1485ac7ddfbfSEd Maste else 1486ac7ddfbfSEd Maste { 1487ac7ddfbfSEd Maste result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1488ac7ddfbfSEd Maste m_cmd_name.c_str(), 1489ac7ddfbfSEd Maste m_cmd_syntax.c_str()); 1490ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1491ac7ddfbfSEd Maste } 1492ac7ddfbfSEd Maste return result.Succeeded(); 1493ac7ddfbfSEd Maste } 1494ac7ddfbfSEd Maste }; 1495ac7ddfbfSEd Maste 1496ac7ddfbfSEd Maste //------------------------------------------------------------------------- 14970127ef0fSEd Maste // CommandObjectProcessSaveCore 14980127ef0fSEd Maste //------------------------------------------------------------------------- 14990127ef0fSEd Maste #pragma mark CommandObjectProcessSaveCore 15000127ef0fSEd Maste 15010127ef0fSEd Maste class CommandObjectProcessSaveCore : public CommandObjectParsed 15020127ef0fSEd Maste { 15030127ef0fSEd Maste public: 15040127ef0fSEd Maste 15050127ef0fSEd Maste CommandObjectProcessSaveCore (CommandInterpreter &interpreter) : 15060127ef0fSEd Maste CommandObjectParsed (interpreter, 15070127ef0fSEd Maste "process save-core", 15080127ef0fSEd Maste "Save the current process as a core file using an appropriate file type.", 15090127ef0fSEd Maste "process save-core FILE", 15101c3bbb01SEd Maste eCommandRequiresProcess | 15111c3bbb01SEd Maste eCommandTryTargetAPILock | 15121c3bbb01SEd Maste eCommandProcessMustBeLaunched) 15130127ef0fSEd Maste { 15140127ef0fSEd Maste } 15150127ef0fSEd Maste 15160127ef0fSEd Maste ~CommandObjectProcessSaveCore () 15170127ef0fSEd Maste { 15180127ef0fSEd Maste } 15190127ef0fSEd Maste 15200127ef0fSEd Maste protected: 15210127ef0fSEd Maste bool 15220127ef0fSEd Maste DoExecute (Args& command, 15230127ef0fSEd Maste CommandReturnObject &result) 15240127ef0fSEd Maste { 15250127ef0fSEd Maste ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 15260127ef0fSEd Maste if (process_sp) 15270127ef0fSEd Maste { 15280127ef0fSEd Maste if (command.GetArgumentCount() == 1) 15290127ef0fSEd Maste { 15300127ef0fSEd Maste FileSpec output_file(command.GetArgumentAtIndex(0), false); 15310127ef0fSEd Maste Error error = PluginManager::SaveCore(process_sp, output_file); 15320127ef0fSEd Maste if (error.Success()) 15330127ef0fSEd Maste { 15340127ef0fSEd Maste result.SetStatus (eReturnStatusSuccessFinishResult); 15350127ef0fSEd Maste } 15360127ef0fSEd Maste else 15370127ef0fSEd Maste { 15380127ef0fSEd Maste result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString()); 15390127ef0fSEd Maste result.SetStatus (eReturnStatusFailed); 15400127ef0fSEd Maste } 15410127ef0fSEd Maste } 15420127ef0fSEd Maste else 15430127ef0fSEd Maste { 15440127ef0fSEd Maste result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n", 15450127ef0fSEd Maste m_cmd_name.c_str(), 15460127ef0fSEd Maste m_cmd_syntax.c_str()); 15470127ef0fSEd Maste result.SetStatus (eReturnStatusFailed); 15480127ef0fSEd Maste } 15490127ef0fSEd Maste } 15500127ef0fSEd Maste else 15510127ef0fSEd Maste { 15520127ef0fSEd Maste result.AppendError ("invalid process"); 15530127ef0fSEd Maste result.SetStatus (eReturnStatusFailed); 15540127ef0fSEd Maste return false; 15550127ef0fSEd Maste } 15560127ef0fSEd Maste 15570127ef0fSEd Maste return result.Succeeded(); 15580127ef0fSEd Maste } 15590127ef0fSEd Maste }; 15600127ef0fSEd Maste 15610127ef0fSEd Maste //------------------------------------------------------------------------- 1562ac7ddfbfSEd Maste // CommandObjectProcessStatus 1563ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1564ac7ddfbfSEd Maste #pragma mark CommandObjectProcessStatus 1565ac7ddfbfSEd Maste 1566ac7ddfbfSEd Maste class CommandObjectProcessStatus : public CommandObjectParsed 1567ac7ddfbfSEd Maste { 1568ac7ddfbfSEd Maste public: 1569ac7ddfbfSEd Maste CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1570ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1571ac7ddfbfSEd Maste "process status", 1572ac7ddfbfSEd Maste "Show the current status and location of executing process.", 1573ac7ddfbfSEd Maste "process status", 15741c3bbb01SEd Maste eCommandRequiresProcess | eCommandTryTargetAPILock) 1575ac7ddfbfSEd Maste { 1576ac7ddfbfSEd Maste } 1577ac7ddfbfSEd Maste 1578ac7ddfbfSEd Maste ~CommandObjectProcessStatus() 1579ac7ddfbfSEd Maste { 1580ac7ddfbfSEd Maste } 1581ac7ddfbfSEd Maste 1582ac7ddfbfSEd Maste 1583ac7ddfbfSEd Maste bool 1584ac7ddfbfSEd Maste DoExecute (Args& command, CommandReturnObject &result) 1585ac7ddfbfSEd Maste { 1586ac7ddfbfSEd Maste Stream &strm = result.GetOutputStream(); 1587ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishNoResult); 15881c3bbb01SEd Maste // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid 1589ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr(); 1590ac7ddfbfSEd Maste const bool only_threads_with_stop_reason = true; 1591ac7ddfbfSEd Maste const uint32_t start_frame = 0; 1592ac7ddfbfSEd Maste const uint32_t num_frames = 1; 1593ac7ddfbfSEd Maste const uint32_t num_frames_with_source = 1; 1594ac7ddfbfSEd Maste process->GetStatus(strm); 1595ac7ddfbfSEd Maste process->GetThreadStatus (strm, 1596ac7ddfbfSEd Maste only_threads_with_stop_reason, 1597ac7ddfbfSEd Maste start_frame, 1598ac7ddfbfSEd Maste num_frames, 1599ac7ddfbfSEd Maste num_frames_with_source); 1600ac7ddfbfSEd Maste return result.Succeeded(); 1601ac7ddfbfSEd Maste } 1602ac7ddfbfSEd Maste }; 1603ac7ddfbfSEd Maste 1604ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1605ac7ddfbfSEd Maste // CommandObjectProcessHandle 1606ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1607ac7ddfbfSEd Maste #pragma mark CommandObjectProcessHandle 1608ac7ddfbfSEd Maste 1609ac7ddfbfSEd Maste class CommandObjectProcessHandle : public CommandObjectParsed 1610ac7ddfbfSEd Maste { 1611ac7ddfbfSEd Maste public: 1612ac7ddfbfSEd Maste 1613ac7ddfbfSEd Maste class CommandOptions : public Options 1614ac7ddfbfSEd Maste { 1615ac7ddfbfSEd Maste public: 1616ac7ddfbfSEd Maste 1617ac7ddfbfSEd Maste CommandOptions (CommandInterpreter &interpreter) : 1618ac7ddfbfSEd Maste Options (interpreter) 1619ac7ddfbfSEd Maste { 1620ac7ddfbfSEd Maste OptionParsingStarting (); 1621ac7ddfbfSEd Maste } 1622ac7ddfbfSEd Maste 1623ac7ddfbfSEd Maste ~CommandOptions () 1624ac7ddfbfSEd Maste { 1625ac7ddfbfSEd Maste } 1626ac7ddfbfSEd Maste 1627ac7ddfbfSEd Maste Error 1628ac7ddfbfSEd Maste SetOptionValue (uint32_t option_idx, const char *option_arg) 1629ac7ddfbfSEd Maste { 1630ac7ddfbfSEd Maste Error error; 1631ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val; 1632ac7ddfbfSEd Maste 1633ac7ddfbfSEd Maste switch (short_option) 1634ac7ddfbfSEd Maste { 1635ac7ddfbfSEd Maste case 's': 1636ac7ddfbfSEd Maste stop = option_arg; 1637ac7ddfbfSEd Maste break; 1638ac7ddfbfSEd Maste case 'n': 1639ac7ddfbfSEd Maste notify = option_arg; 1640ac7ddfbfSEd Maste break; 1641ac7ddfbfSEd Maste case 'p': 1642ac7ddfbfSEd Maste pass = option_arg; 1643ac7ddfbfSEd Maste break; 1644ac7ddfbfSEd Maste default: 1645ac7ddfbfSEd Maste error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1646ac7ddfbfSEd Maste break; 1647ac7ddfbfSEd Maste } 1648ac7ddfbfSEd Maste return error; 1649ac7ddfbfSEd Maste } 1650ac7ddfbfSEd Maste 1651ac7ddfbfSEd Maste void 1652ac7ddfbfSEd Maste OptionParsingStarting () 1653ac7ddfbfSEd Maste { 1654ac7ddfbfSEd Maste stop.clear(); 1655ac7ddfbfSEd Maste notify.clear(); 1656ac7ddfbfSEd Maste pass.clear(); 1657ac7ddfbfSEd Maste } 1658ac7ddfbfSEd Maste 1659ac7ddfbfSEd Maste const OptionDefinition* 1660ac7ddfbfSEd Maste GetDefinitions () 1661ac7ddfbfSEd Maste { 1662ac7ddfbfSEd Maste return g_option_table; 1663ac7ddfbfSEd Maste } 1664ac7ddfbfSEd Maste 1665ac7ddfbfSEd Maste // Options table: Required for subclasses of Options. 1666ac7ddfbfSEd Maste 1667ac7ddfbfSEd Maste static OptionDefinition g_option_table[]; 1668ac7ddfbfSEd Maste 1669ac7ddfbfSEd Maste // Instance variables to hold the values for command options. 1670ac7ddfbfSEd Maste 1671ac7ddfbfSEd Maste std::string stop; 1672ac7ddfbfSEd Maste std::string notify; 1673ac7ddfbfSEd Maste std::string pass; 1674ac7ddfbfSEd Maste }; 1675ac7ddfbfSEd Maste 1676ac7ddfbfSEd Maste 1677ac7ddfbfSEd Maste CommandObjectProcessHandle (CommandInterpreter &interpreter) : 1678ac7ddfbfSEd Maste CommandObjectParsed (interpreter, 1679ac7ddfbfSEd Maste "process handle", 1680ac7ddfbfSEd Maste "Show or update what the process and debugger should do with various signals received from the OS.", 1681ac7ddfbfSEd Maste NULL), 1682ac7ddfbfSEd Maste m_options (interpreter) 1683ac7ddfbfSEd Maste { 1684b91a7dfcSDimitry Andric SetHelpLong ("\nIf no signals are specified, update them all. If no update " 1685b91a7dfcSDimitry Andric "option is specified, list the current values."); 1686ac7ddfbfSEd Maste CommandArgumentEntry arg; 1687ac7ddfbfSEd Maste CommandArgumentData signal_arg; 1688ac7ddfbfSEd Maste 1689ac7ddfbfSEd Maste signal_arg.arg_type = eArgTypeUnixSignal; 1690ac7ddfbfSEd Maste signal_arg.arg_repetition = eArgRepeatStar; 1691ac7ddfbfSEd Maste 1692ac7ddfbfSEd Maste arg.push_back (signal_arg); 1693ac7ddfbfSEd Maste 1694ac7ddfbfSEd Maste m_arguments.push_back (arg); 1695ac7ddfbfSEd Maste } 1696ac7ddfbfSEd Maste 1697ac7ddfbfSEd Maste ~CommandObjectProcessHandle () 1698ac7ddfbfSEd Maste { 1699ac7ddfbfSEd Maste } 1700ac7ddfbfSEd Maste 1701ac7ddfbfSEd Maste Options * 1702ac7ddfbfSEd Maste GetOptions () 1703ac7ddfbfSEd Maste { 1704ac7ddfbfSEd Maste return &m_options; 1705ac7ddfbfSEd Maste } 1706ac7ddfbfSEd Maste 1707ac7ddfbfSEd Maste bool 1708ac7ddfbfSEd Maste VerifyCommandOptionValue (const std::string &option, int &real_value) 1709ac7ddfbfSEd Maste { 1710ac7ddfbfSEd Maste bool okay = true; 1711ac7ddfbfSEd Maste 1712ac7ddfbfSEd Maste bool success = false; 1713ac7ddfbfSEd Maste bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 1714ac7ddfbfSEd Maste 1715ac7ddfbfSEd Maste if (success && tmp_value) 1716ac7ddfbfSEd Maste real_value = 1; 1717ac7ddfbfSEd Maste else if (success && !tmp_value) 1718ac7ddfbfSEd Maste real_value = 0; 1719ac7ddfbfSEd Maste else 1720ac7ddfbfSEd Maste { 1721ac7ddfbfSEd Maste // If the value isn't 'true' or 'false', it had better be 0 or 1. 17221c3bbb01SEd Maste real_value = StringConvert::ToUInt32 (option.c_str(), 3); 1723ac7ddfbfSEd Maste if (real_value != 0 && real_value != 1) 1724ac7ddfbfSEd Maste okay = false; 1725ac7ddfbfSEd Maste } 1726ac7ddfbfSEd Maste 1727ac7ddfbfSEd Maste return okay; 1728ac7ddfbfSEd Maste } 1729ac7ddfbfSEd Maste 1730ac7ddfbfSEd Maste void 1731ac7ddfbfSEd Maste PrintSignalHeader (Stream &str) 1732ac7ddfbfSEd Maste { 1733ac7ddfbfSEd Maste str.Printf ("NAME PASS STOP NOTIFY\n"); 17341c3bbb01SEd Maste str.Printf ("=========== ===== ===== ======\n"); 1735ac7ddfbfSEd Maste } 1736ac7ddfbfSEd Maste 1737ac7ddfbfSEd Maste void 1738b91a7dfcSDimitry Andric PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp) 1739ac7ddfbfSEd Maste { 1740ac7ddfbfSEd Maste bool stop; 1741ac7ddfbfSEd Maste bool suppress; 1742ac7ddfbfSEd Maste bool notify; 1743ac7ddfbfSEd Maste 17441c3bbb01SEd Maste str.Printf ("%-11s ", sig_name); 1745b91a7dfcSDimitry Andric if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) 1746ac7ddfbfSEd Maste { 1747ac7ddfbfSEd Maste bool pass = !suppress; 1748ac7ddfbfSEd Maste str.Printf ("%s %s %s", 1749ac7ddfbfSEd Maste (pass ? "true " : "false"), 1750ac7ddfbfSEd Maste (stop ? "true " : "false"), 1751ac7ddfbfSEd Maste (notify ? "true " : "false")); 1752ac7ddfbfSEd Maste } 1753ac7ddfbfSEd Maste str.Printf ("\n"); 1754ac7ddfbfSEd Maste } 1755ac7ddfbfSEd Maste 1756ac7ddfbfSEd Maste void 1757b91a7dfcSDimitry Andric PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp) 1758ac7ddfbfSEd Maste { 1759ac7ddfbfSEd Maste PrintSignalHeader (str); 1760ac7ddfbfSEd Maste 1761ac7ddfbfSEd Maste if (num_valid_signals > 0) 1762ac7ddfbfSEd Maste { 1763ac7ddfbfSEd Maste size_t num_args = signal_args.GetArgumentCount(); 1764ac7ddfbfSEd Maste for (size_t i = 0; i < num_args; ++i) 1765ac7ddfbfSEd Maste { 1766b91a7dfcSDimitry Andric int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); 1767ac7ddfbfSEd Maste if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1768b91a7dfcSDimitry Andric PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp); 1769ac7ddfbfSEd Maste } 1770ac7ddfbfSEd Maste } 1771ac7ddfbfSEd Maste else // Print info for ALL signals 1772ac7ddfbfSEd Maste { 1773b91a7dfcSDimitry Andric int32_t signo = signals_sp->GetFirstSignalNumber(); 1774ac7ddfbfSEd Maste while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1775ac7ddfbfSEd Maste { 1776b91a7dfcSDimitry Andric PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp); 1777b91a7dfcSDimitry Andric signo = signals_sp->GetNextSignalNumber(signo); 1778ac7ddfbfSEd Maste } 1779ac7ddfbfSEd Maste } 1780ac7ddfbfSEd Maste } 1781ac7ddfbfSEd Maste 1782ac7ddfbfSEd Maste protected: 1783ac7ddfbfSEd Maste bool 1784ac7ddfbfSEd Maste DoExecute (Args &signal_args, CommandReturnObject &result) 1785ac7ddfbfSEd Maste { 1786ac7ddfbfSEd Maste TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 1787ac7ddfbfSEd Maste 1788ac7ddfbfSEd Maste if (!target_sp) 1789ac7ddfbfSEd Maste { 1790ac7ddfbfSEd Maste result.AppendError ("No current target;" 1791ac7ddfbfSEd Maste " cannot handle signals until you have a valid target and process.\n"); 1792ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1793ac7ddfbfSEd Maste return false; 1794ac7ddfbfSEd Maste } 1795ac7ddfbfSEd Maste 1796ac7ddfbfSEd Maste ProcessSP process_sp = target_sp->GetProcessSP(); 1797ac7ddfbfSEd Maste 1798ac7ddfbfSEd Maste if (!process_sp) 1799ac7ddfbfSEd Maste { 1800ac7ddfbfSEd Maste result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 1801ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1802ac7ddfbfSEd Maste return false; 1803ac7ddfbfSEd Maste } 1804ac7ddfbfSEd Maste 1805ac7ddfbfSEd Maste int stop_action = -1; // -1 means leave the current setting alone 1806ac7ddfbfSEd Maste int pass_action = -1; // -1 means leave the current setting alone 1807ac7ddfbfSEd Maste int notify_action = -1; // -1 means leave the current setting alone 1808ac7ddfbfSEd Maste 1809ac7ddfbfSEd Maste if (! m_options.stop.empty() 1810ac7ddfbfSEd Maste && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 1811ac7ddfbfSEd Maste { 1812ac7ddfbfSEd Maste result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 1813ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1814ac7ddfbfSEd Maste return false; 1815ac7ddfbfSEd Maste } 1816ac7ddfbfSEd Maste 1817ac7ddfbfSEd Maste if (! m_options.notify.empty() 1818ac7ddfbfSEd Maste && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 1819ac7ddfbfSEd Maste { 1820ac7ddfbfSEd Maste result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 1821ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1822ac7ddfbfSEd Maste return false; 1823ac7ddfbfSEd Maste } 1824ac7ddfbfSEd Maste 1825ac7ddfbfSEd Maste if (! m_options.pass.empty() 1826ac7ddfbfSEd Maste && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 1827ac7ddfbfSEd Maste { 1828ac7ddfbfSEd Maste result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 1829ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1830ac7ddfbfSEd Maste return false; 1831ac7ddfbfSEd Maste } 1832ac7ddfbfSEd Maste 1833ac7ddfbfSEd Maste size_t num_args = signal_args.GetArgumentCount(); 1834b91a7dfcSDimitry Andric UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); 1835ac7ddfbfSEd Maste int num_signals_set = 0; 1836ac7ddfbfSEd Maste 1837ac7ddfbfSEd Maste if (num_args > 0) 1838ac7ddfbfSEd Maste { 1839ac7ddfbfSEd Maste for (size_t i = 0; i < num_args; ++i) 1840ac7ddfbfSEd Maste { 1841b91a7dfcSDimitry Andric int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); 1842ac7ddfbfSEd Maste if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1843ac7ddfbfSEd Maste { 1844ac7ddfbfSEd Maste // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 1845ac7ddfbfSEd Maste // the value is either 0 or 1. 1846ac7ddfbfSEd Maste if (stop_action != -1) 1847b91a7dfcSDimitry Andric signals_sp->SetShouldStop(signo, stop_action); 1848ac7ddfbfSEd Maste if (pass_action != -1) 1849ac7ddfbfSEd Maste { 1850b91a7dfcSDimitry Andric bool suppress = !pass_action; 1851b91a7dfcSDimitry Andric signals_sp->SetShouldSuppress(signo, suppress); 1852ac7ddfbfSEd Maste } 1853ac7ddfbfSEd Maste if (notify_action != -1) 1854b91a7dfcSDimitry Andric signals_sp->SetShouldNotify(signo, notify_action); 1855ac7ddfbfSEd Maste ++num_signals_set; 1856ac7ddfbfSEd Maste } 1857ac7ddfbfSEd Maste else 1858ac7ddfbfSEd Maste { 1859ac7ddfbfSEd Maste result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 1860ac7ddfbfSEd Maste } 1861ac7ddfbfSEd Maste } 1862ac7ddfbfSEd Maste } 1863ac7ddfbfSEd Maste else 1864ac7ddfbfSEd Maste { 1865ac7ddfbfSEd Maste // No signal specified, if any command options were specified, update ALL signals. 1866ac7ddfbfSEd Maste if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 1867ac7ddfbfSEd Maste { 1868ac7ddfbfSEd Maste if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 1869ac7ddfbfSEd Maste { 1870b91a7dfcSDimitry Andric int32_t signo = signals_sp->GetFirstSignalNumber(); 1871ac7ddfbfSEd Maste while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1872ac7ddfbfSEd Maste { 1873ac7ddfbfSEd Maste if (notify_action != -1) 1874b91a7dfcSDimitry Andric signals_sp->SetShouldNotify(signo, notify_action); 1875ac7ddfbfSEd Maste if (stop_action != -1) 1876b91a7dfcSDimitry Andric signals_sp->SetShouldStop(signo, stop_action); 1877ac7ddfbfSEd Maste if (pass_action != -1) 1878ac7ddfbfSEd Maste { 1879b91a7dfcSDimitry Andric bool suppress = !pass_action; 1880b91a7dfcSDimitry Andric signals_sp->SetShouldSuppress(signo, suppress); 1881ac7ddfbfSEd Maste } 1882b91a7dfcSDimitry Andric signo = signals_sp->GetNextSignalNumber(signo); 1883ac7ddfbfSEd Maste } 1884ac7ddfbfSEd Maste } 1885ac7ddfbfSEd Maste } 1886ac7ddfbfSEd Maste } 1887ac7ddfbfSEd Maste 1888b91a7dfcSDimitry Andric PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp); 1889ac7ddfbfSEd Maste 1890ac7ddfbfSEd Maste if (num_signals_set > 0) 1891ac7ddfbfSEd Maste result.SetStatus (eReturnStatusSuccessFinishNoResult); 1892ac7ddfbfSEd Maste else 1893ac7ddfbfSEd Maste result.SetStatus (eReturnStatusFailed); 1894ac7ddfbfSEd Maste 1895ac7ddfbfSEd Maste return result.Succeeded(); 1896ac7ddfbfSEd Maste } 1897ac7ddfbfSEd Maste 1898ac7ddfbfSEd Maste CommandOptions m_options; 1899ac7ddfbfSEd Maste }; 1900ac7ddfbfSEd Maste 1901ac7ddfbfSEd Maste OptionDefinition 1902ac7ddfbfSEd Maste CommandObjectProcessHandle::CommandOptions::g_option_table[] = 1903ac7ddfbfSEd Maste { 19040127ef0fSEd Maste { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, 19050127ef0fSEd Maste { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, 19060127ef0fSEd Maste { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 19070127ef0fSEd Maste { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1908ac7ddfbfSEd Maste }; 1909ac7ddfbfSEd Maste 1910ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1911ac7ddfbfSEd Maste // CommandObjectMultiwordProcess 1912ac7ddfbfSEd Maste //------------------------------------------------------------------------- 1913ac7ddfbfSEd Maste 1914ac7ddfbfSEd Maste CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1915ac7ddfbfSEd Maste CommandObjectMultiword (interpreter, 1916ac7ddfbfSEd Maste "process", 1917ac7ddfbfSEd Maste "A set of commands for operating on a process.", 1918ac7ddfbfSEd Maste "process <subcommand> [<subcommand-options>]") 1919ac7ddfbfSEd Maste { 1920ac7ddfbfSEd Maste LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1921ac7ddfbfSEd Maste LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1922ac7ddfbfSEd Maste LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1923ac7ddfbfSEd Maste LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); 1924ac7ddfbfSEd Maste LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1925ac7ddfbfSEd Maste LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 1926ac7ddfbfSEd Maste LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1927ac7ddfbfSEd Maste LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 1928ac7ddfbfSEd Maste LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1929ac7ddfbfSEd Maste LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1930ac7ddfbfSEd Maste LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1931ac7ddfbfSEd Maste LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 1932ac7ddfbfSEd Maste LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter))); 19330127ef0fSEd Maste LoadSubCommand ("save-core", CommandObjectSP (new CommandObjectProcessSaveCore (interpreter))); 1934ac7ddfbfSEd Maste } 1935ac7ddfbfSEd Maste 1936ac7ddfbfSEd Maste CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 1937ac7ddfbfSEd Maste { 1938ac7ddfbfSEd Maste } 1939ac7ddfbfSEd Maste 1940