130fdc8d8SChris Lattner //===-- CommandObjectProcess.cpp --------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 949bcfd80SEugene Zelenko #include "CommandObjectProcess.h" 100e41084aSJim Ingham #include "lldb/Breakpoint/Breakpoint.h" 110e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 120e41084aSJim Ingham #include "lldb/Breakpoint/BreakpointSite.h" 131f746071SGreg Clayton #include "lldb/Core/Module.h" 14a2715cf1SGreg Clayton #include "lldb/Core/PluginManager.h" 157260f620SGreg Clayton #include "lldb/Host/Host.h" 163eb2b44dSZachary Turner #include "lldb/Host/OptionParser.h" 175275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 1830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h" 1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 2047cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h" 21b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h" 22e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2330fdc8d8SChris Lattner #include "lldb/Target/Process.h" 240e41084aSJim Ingham #include "lldb/Target/StopInfo.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Target.h" 2630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2793749ab3SZachary Turner #include "lldb/Target/UnixSignals.h" 28145d95c9SPavel Labath #include "lldb/Utility/Args.h" 29d821c997SPavel Labath #include "lldb/Utility/State.h" 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner using namespace lldb; 3230fdc8d8SChris Lattner using namespace lldb_private; 3330fdc8d8SChris Lattner 34b9c1b51eSKate Stone class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed { 35dcb1d856SJim Ingham public: 36dcb1d856SJim Ingham CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter, 37b9c1b51eSKate Stone const char *name, const char *help, 38b9c1b51eSKate Stone const char *syntax, uint32_t flags, 39b9c1b51eSKate Stone const char *new_process_action) 40b9c1b51eSKate Stone : CommandObjectParsed(interpreter, name, help, syntax, flags), 41dcb1d856SJim Ingham m_new_process_action(new_process_action) {} 42dcb1d856SJim Ingham 4349bcfd80SEugene Zelenko ~CommandObjectProcessLaunchOrAttach() override = default; 4449bcfd80SEugene Zelenko 45dcb1d856SJim Ingham protected: 46b9c1b51eSKate Stone bool StopProcessIfNecessary(Process *process, StateType &state, 47b9c1b51eSKate Stone CommandReturnObject &result) { 48dcb1d856SJim Ingham state = eStateInvalid; 49b9c1b51eSKate Stone if (process) { 50dcb1d856SJim Ingham state = process->GetState(); 51dcb1d856SJim Ingham 52b9c1b51eSKate Stone if (process->IsAlive() && state != eStateConnected) { 53dcb1d856SJim Ingham char message[1024]; 54dcb1d856SJim Ingham if (process->GetState() == eStateAttaching) 55b9c1b51eSKate Stone ::snprintf(message, sizeof(message), 56b9c1b51eSKate Stone "There is a pending attach, abort it and %s?", 57b9c1b51eSKate Stone m_new_process_action.c_str()); 58dcb1d856SJim Ingham else if (process->GetShouldDetach()) 59b9c1b51eSKate Stone ::snprintf(message, sizeof(message), 60b9c1b51eSKate Stone "There is a running process, detach from it and %s?", 61b9c1b51eSKate Stone m_new_process_action.c_str()); 62dcb1d856SJim Ingham else 63b9c1b51eSKate Stone ::snprintf(message, sizeof(message), 64b9c1b51eSKate Stone "There is a running process, kill it and %s?", 65b9c1b51eSKate Stone m_new_process_action.c_str()); 66dcb1d856SJim Ingham 67b9c1b51eSKate Stone if (!m_interpreter.Confirm(message, true)) { 68dcb1d856SJim Ingham result.SetStatus(eReturnStatusFailed); 69dcb1d856SJim Ingham return false; 70b9c1b51eSKate Stone } else { 71b9c1b51eSKate Stone if (process->GetShouldDetach()) { 72acff8950SJim Ingham bool keep_stopped = false; 7397206d57SZachary Turner Status detach_error(process->Detach(keep_stopped)); 74b9c1b51eSKate Stone if (detach_error.Success()) { 75dcb1d856SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 7649bcfd80SEugene Zelenko process = nullptr; 77b9c1b51eSKate Stone } else { 78b9c1b51eSKate Stone result.AppendErrorWithFormat( 79b9c1b51eSKate Stone "Failed to detach from process: %s\n", 80b9c1b51eSKate Stone detach_error.AsCString()); 81dcb1d856SJim Ingham result.SetStatus(eReturnStatusFailed); 82dcb1d856SJim Ingham } 83b9c1b51eSKate Stone } else { 8497206d57SZachary Turner Status destroy_error(process->Destroy(false)); 85b9c1b51eSKate Stone if (destroy_error.Success()) { 86dcb1d856SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 8749bcfd80SEugene Zelenko process = nullptr; 88b9c1b51eSKate Stone } else { 89b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to kill process: %s\n", 90b9c1b51eSKate Stone destroy_error.AsCString()); 91dcb1d856SJim Ingham result.SetStatus(eReturnStatusFailed); 92dcb1d856SJim Ingham } 93dcb1d856SJim Ingham } 94dcb1d856SJim Ingham } 95dcb1d856SJim Ingham } 96dcb1d856SJim Ingham } 97dcb1d856SJim Ingham return result.Succeeded(); 98dcb1d856SJim Ingham } 9949bcfd80SEugene Zelenko 100dcb1d856SJim Ingham std::string m_new_process_action; 101dcb1d856SJim Ingham }; 10249bcfd80SEugene Zelenko 10330fdc8d8SChris Lattner // CommandObjectProcessLaunch 1044bddaeb5SJim Ingham #pragma mark CommandObjectProcessLaunch 105b9c1b51eSKate Stone class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { 10630fdc8d8SChris Lattner public: 107b9c1b51eSKate Stone CommandObjectProcessLaunch(CommandInterpreter &interpreter) 108b9c1b51eSKate Stone : CommandObjectProcessLaunchOrAttach( 109b9c1b51eSKate Stone interpreter, "process launch", 110b9c1b51eSKate Stone "Launch the executable in the debugger.", nullptr, 111b9c1b51eSKate Stone eCommandRequiresTarget, "restart"), 112b9c1b51eSKate Stone m_options() { 113405fe67fSCaroline Tice CommandArgumentEntry arg; 114405fe67fSCaroline Tice CommandArgumentData run_args_arg; 115405fe67fSCaroline Tice 116405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 117405fe67fSCaroline Tice run_args_arg.arg_type = eArgTypeRunArgs; 118405fe67fSCaroline Tice run_args_arg.arg_repetition = eArgRepeatOptional; 119405fe67fSCaroline Tice 120b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 121b9c1b51eSKate Stone // argument entry. 122405fe67fSCaroline Tice arg.push_back(run_args_arg); 123405fe67fSCaroline Tice 124405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 125405fe67fSCaroline Tice m_arguments.push_back(arg); 12630fdc8d8SChris Lattner } 12730fdc8d8SChris Lattner 12849bcfd80SEugene Zelenko ~CommandObjectProcessLaunch() override = default; 12930fdc8d8SChris Lattner 130ae34ed2cSRaphael Isemann void 131ae34ed2cSRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 1322443bbd4SRaphael Isemann OptionElementVector &opt_element_vector) override { 133e9ce62b6SJim Ingham 134b9c1b51eSKate Stone CommandCompletions::InvokeCommonCompletionCallbacks( 135b9c1b51eSKate Stone GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, 136a2e76c0bSRaphael Isemann request, nullptr); 137e9ce62b6SJim Ingham } 138e9ce62b6SJim Ingham 139b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 14030fdc8d8SChris Lattner 141b9c1b51eSKate Stone const char *GetRepeatCommand(Args ¤t_command_args, 142b9c1b51eSKate Stone uint32_t index) override { 1435a988416SJim Ingham // No repeat for "process launch"... 1445a988416SJim Ingham return ""; 1455a988416SJim Ingham } 1465a988416SJim Ingham 1475a988416SJim Ingham protected: 148b9c1b51eSKate Stone bool DoExecute(Args &launch_args, CommandReturnObject &result) override { 14957179860SJonas Devlieghere Debugger &debugger = GetDebugger(); 1501d885966SGreg Clayton Target *target = debugger.GetSelectedTarget().get(); 15149bcfd80SEugene Zelenko // If our listener is nullptr, users aren't allows to launch 152b09c5384SGreg Clayton ModuleSP exe_module_sp = target->GetExecutableModule(); 15371337622SGreg Clayton 154b9c1b51eSKate Stone if (exe_module_sp == nullptr) { 155b9c1b51eSKate Stone result.AppendError("no file in target, create a debug target using the " 156b9c1b51eSKate Stone "'target create' command"); 15771337622SGreg Clayton result.SetStatus(eReturnStatusFailed); 15871337622SGreg Clayton return false; 15971337622SGreg Clayton } 16071337622SGreg Clayton 16171337622SGreg Clayton StateType state = eStateInvalid; 16271337622SGreg Clayton 163b09c5384SGreg Clayton if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result)) 16430fdc8d8SChris Lattner return false; 16530fdc8d8SChris Lattner 16631d97a5cSZachary Turner llvm::StringRef target_settings_argv0 = target->GetArg0(); 16745392553SGreg Clayton 168b9c1b51eSKate Stone // Determine whether we will disable ASLR or leave it in the default state 16905097246SAdrian Prantl // (i.e. enabled if the platform supports it). First check if the process 17005097246SAdrian Prantl // launch options explicitly turn on/off 171b9c1b51eSKate Stone // disabling ASLR. If so, use that setting; 1725163792bSTodd Fiala // otherwise, use the 'settings target.disable-aslr' setting. 1735163792bSTodd Fiala bool disable_aslr = false; 174b9c1b51eSKate Stone if (m_options.disable_aslr != eLazyBoolCalculate) { 17505097246SAdrian Prantl // The user specified an explicit setting on the process launch line. 17605097246SAdrian Prantl // Use it. 1775163792bSTodd Fiala disable_aslr = (m_options.disable_aslr == eLazyBoolYes); 178b9c1b51eSKate Stone } else { 17905097246SAdrian Prantl // The user did not explicitly specify whether to disable ASLR. Fall 18005097246SAdrian Prantl // back to the target.disable-aslr setting. 1815163792bSTodd Fiala disable_aslr = target->GetDisableASLR(); 1825163792bSTodd Fiala } 1835163792bSTodd Fiala 1845163792bSTodd Fiala if (disable_aslr) 185b09c5384SGreg Clayton m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR); 1865163792bSTodd Fiala else 1875163792bSTodd Fiala m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR); 188b09c5384SGreg Clayton 189106d0286SJim Ingham if (target->GetDetachOnError()) 190106d0286SJim Ingham m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError); 191106d0286SJim Ingham 192b09c5384SGreg Clayton if (target->GetDisableSTDIO()) 193b09c5384SGreg Clayton m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO); 194b09c5384SGreg Clayton 195ae54fc9fSJonas Devlieghere // Merge the launch info environment with the target environment. 196ae54fc9fSJonas Devlieghere Environment target_env = target->GetEnvironment(); 197ae54fc9fSJonas Devlieghere m_options.launch_info.GetEnvironment().insert(target_env.begin(), 198ae54fc9fSJonas Devlieghere target_env.end()); 19945392553SGreg Clayton 20031d97a5cSZachary Turner if (!target_settings_argv0.empty()) { 201b9c1b51eSKate Stone m_options.launch_info.GetArguments().AppendArgument( 20231d97a5cSZachary Turner target_settings_argv0); 203b9c1b51eSKate Stone m_options.launch_info.SetExecutableFile( 204b9c1b51eSKate Stone exe_module_sp->GetPlatformFileSpec(), false); 205b9c1b51eSKate Stone } else { 206b9c1b51eSKate Stone m_options.launch_info.SetExecutableFile( 207b9c1b51eSKate Stone exe_module_sp->GetPlatformFileSpec(), true); 20845392553SGreg Clayton } 20945392553SGreg Clayton 210b9c1b51eSKate Stone if (launch_args.GetArgumentCount() == 0) { 211b9c1b51eSKate Stone m_options.launch_info.GetArguments().AppendArguments( 212b9c1b51eSKate Stone target->GetProcessLaunchInfo().GetArguments()); 213b9c1b51eSKate Stone } else { 21445392553SGreg Clayton m_options.launch_info.GetArguments().AppendArguments(launch_args); 215162b597cSGreg Clayton // Save the arguments for subsequent runs in the current target. 216162b597cSGreg Clayton target->SetRunArguments(launch_args); 217982c9762SGreg Clayton } 2181d885966SGreg Clayton 219dc6224e0SGreg Clayton StreamString stream; 22097206d57SZachary Turner Status error = target->Launch(m_options.launch_info, &stream); 22130fdc8d8SChris Lattner 222b9c1b51eSKate Stone if (error.Success()) { 223b09c5384SGreg Clayton ProcessSP process_sp(target->GetProcessSP()); 224b9c1b51eSKate Stone if (process_sp) { 225b9c1b51eSKate Stone // There is a race condition where this thread will return up the call 22605097246SAdrian Prantl // stack to the main command handler and show an (lldb) prompt before 22705097246SAdrian Prantl // HandlePrivateEvent (from PrivateStateThread) has a chance to call 22805097246SAdrian Prantl // PushProcessIOHandler(). 2293879fe00SPavel Labath process_sp->SyncIOHandler(0, std::chrono::seconds(2)); 2308f0db3e1SIlia K 231c156427dSZachary Turner llvm::StringRef data = stream.GetString(); 232c156427dSZachary Turner if (!data.empty()) 233c156427dSZachary Turner result.AppendMessage(data); 234b9c1b51eSKate Stone const char *archname = 235b9c1b51eSKate Stone exe_module_sp->GetArchitecture().GetArchitectureName(); 236b9c1b51eSKate Stone result.AppendMessageWithFormat( 237b9c1b51eSKate Stone "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), 238b9c1b51eSKate Stone exe_module_sp->GetFileSpec().GetPath().c_str(), archname); 23905faeb71SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult); 240b09c5384SGreg Clayton result.SetDidChangeProcessState(true); 241b9c1b51eSKate Stone } else { 242b9c1b51eSKate Stone result.AppendError( 243b9c1b51eSKate Stone "no error returned from Target::Launch, and target has no process"); 244514487e8SGreg Clayton result.SetStatus(eReturnStatusFailed); 24530fdc8d8SChris Lattner } 246b9c1b51eSKate Stone } else { 247b09c5384SGreg Clayton result.AppendError(error.AsCString()); 248514487e8SGreg Clayton result.SetStatus(eReturnStatusFailed); 249514487e8SGreg Clayton } 25030fdc8d8SChris Lattner return result.Succeeded(); 25130fdc8d8SChris Lattner } 25230fdc8d8SChris Lattner 25330fdc8d8SChris Lattner protected: 254982c9762SGreg Clayton ProcessLaunchCommandOptions m_options; 25530fdc8d8SChris Lattner }; 25630fdc8d8SChris Lattner 257438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_attach 258438dfcffSRaphael Isemann #include "CommandOptions.inc" 2591f0f5b5bSZachary Turner 260bb9caf73SJim Ingham #pragma mark CommandObjectProcessAttach 261b9c1b51eSKate Stone class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach { 26230fdc8d8SChris Lattner public: 263b9c1b51eSKate Stone class CommandOptions : public Options { 26430fdc8d8SChris Lattner public: 265b9c1b51eSKate Stone CommandOptions() : Options() { 266b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting 267b9c1b51eSKate Stone // () 268e1cfbc79STodd Fiala OptionParsingStarting(nullptr); 26930fdc8d8SChris Lattner } 27030fdc8d8SChris Lattner 27149bcfd80SEugene Zelenko ~CommandOptions() override = default; 27230fdc8d8SChris Lattner 27397206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 274b9c1b51eSKate Stone ExecutionContext *execution_context) override { 27597206d57SZachary Turner Status error; 2763bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 277b9c1b51eSKate Stone switch (short_option) { 278a95ce623SJohnny Chen case 'c': 279a95ce623SJohnny Chen attach_info.SetContinueOnceAttached(true); 280a95ce623SJohnny Chen break; 281a95ce623SJohnny Chen 282b9c1b51eSKate Stone case 'p': { 283fe11483bSZachary Turner lldb::pid_t pid; 284fe11483bSZachary Turner if (option_arg.getAsInteger(0, pid)) { 285fe11483bSZachary Turner error.SetErrorStringWithFormat("invalid process ID '%s'", 286fe11483bSZachary Turner option_arg.str().c_str()); 287b9c1b51eSKate Stone } else { 288144f3a9cSGreg Clayton attach_info.SetProcessID(pid); 289144f3a9cSGreg Clayton } 290b9c1b51eSKate Stone } break; 29130fdc8d8SChris Lattner 29230fdc8d8SChris Lattner case 'P': 293144f3a9cSGreg Clayton attach_info.SetProcessPluginName(option_arg); 29430fdc8d8SChris Lattner break; 29530fdc8d8SChris Lattner 29630fdc8d8SChris Lattner case 'n': 2978f3be7a3SJonas Devlieghere attach_info.GetExecutableFile().SetFile(option_arg, 298937348cdSJonas Devlieghere FileSpec::Style::native); 29930fdc8d8SChris Lattner break; 30030fdc8d8SChris Lattner 30130fdc8d8SChris Lattner case 'w': 302144f3a9cSGreg Clayton attach_info.SetWaitForLaunch(true); 30330fdc8d8SChris Lattner break; 30430fdc8d8SChris Lattner 305cd16df91SJim Ingham case 'i': 306cd16df91SJim Ingham attach_info.SetIgnoreExisting(false); 307cd16df91SJim Ingham break; 308cd16df91SJim Ingham 30930fdc8d8SChris Lattner default: 31036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 31130fdc8d8SChris Lattner } 31230fdc8d8SChris Lattner return error; 31330fdc8d8SChris Lattner } 31430fdc8d8SChris Lattner 315b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 316144f3a9cSGreg Clayton attach_info.Clear(); 31730fdc8d8SChris Lattner } 31830fdc8d8SChris Lattner 3191f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 32070602439SZachary Turner return llvm::makeArrayRef(g_process_attach_options); 3211f0f5b5bSZachary Turner } 32230fdc8d8SChris Lattner 323494370c1SRaphael Isemann void HandleOptionArgumentCompletion( 324a2e76c0bSRaphael Isemann CompletionRequest &request, OptionElementVector &opt_element_vector, 325a2e76c0bSRaphael Isemann int opt_element_index, CommandInterpreter &interpreter) override { 3265aee162fSJim Ingham int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 3275aee162fSJim Ingham int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 3285aee162fSJim Ingham 3295aee162fSJim Ingham // We are only completing the name option for now... 3305aee162fSJim Ingham 3315aee162fSJim Ingham // Are we in the name? 3321153dc96SRaphael Isemann if (GetDefinitions()[opt_defs_index].short_option != 'n') 333494370c1SRaphael Isemann return; 3345aee162fSJim Ingham 335b9c1b51eSKate Stone // Look to see if there is a -P argument provided, and if so use that 33605097246SAdrian Prantl // plugin, otherwise use the default plugin. 3375aee162fSJim Ingham 33849bcfd80SEugene Zelenko const char *partial_name = nullptr; 339a2e76c0bSRaphael Isemann partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); 3405aee162fSJim Ingham 341e1cfbc79STodd Fiala PlatformSP platform_sp(interpreter.GetPlatform(true)); 3421153dc96SRaphael Isemann if (!platform_sp) 343494370c1SRaphael Isemann return; 3448b82f087SGreg Clayton ProcessInstanceInfoList process_infos; 3458b82f087SGreg Clayton ProcessInstanceInfoMatch match_info; 346b9c1b51eSKate Stone if (partial_name) { 347b9c1b51eSKate Stone match_info.GetProcessInfo().GetExecutableFile().SetFile( 3488f3be7a3SJonas Devlieghere partial_name, FileSpec::Style::native); 349c4a33951SPavel Labath match_info.SetNameMatchType(NameMatch::StartsWith); 35032e0a750SGreg Clayton } 35132e0a750SGreg Clayton platform_sp->FindProcesses(match_info, process_infos); 352c7bece56SGreg Clayton const size_t num_matches = process_infos.GetSize(); 3531153dc96SRaphael Isemann if (num_matches == 0) 354494370c1SRaphael Isemann return; 355b9c1b51eSKate Stone for (size_t i = 0; i < num_matches; ++i) { 35672ca5f36SRaphael Isemann request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); 3575aee162fSJim Ingham } 3585aee162fSJim Ingham } 3595aee162fSJim Ingham 36030fdc8d8SChris Lattner // Instance variables to hold the values for command options. 36130fdc8d8SChris Lattner 362144f3a9cSGreg Clayton ProcessAttachInfo attach_info; 36330fdc8d8SChris Lattner }; 36430fdc8d8SChris Lattner 365b9c1b51eSKate Stone CommandObjectProcessAttach(CommandInterpreter &interpreter) 366b9c1b51eSKate Stone : CommandObjectProcessLaunchOrAttach( 367b9c1b51eSKate Stone interpreter, "process attach", "Attach to a process.", 368b9c1b51eSKate Stone "process attach <cmd-options>", 0, "attach"), 369b9c1b51eSKate Stone m_options() {} 3705aee162fSJim Ingham 37149bcfd80SEugene Zelenko ~CommandObjectProcessAttach() override = default; 3725aee162fSJim Ingham 373b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 3745a988416SJim Ingham 3755a988416SJim Ingham protected: 376b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 377b9c1b51eSKate Stone PlatformSP platform_sp( 37857179860SJonas Devlieghere GetDebugger().GetPlatformList().GetSelectedPlatform()); 379926af0cdSOleksiy Vyalov 38057179860SJonas Devlieghere Target *target = GetDebugger().GetSelectedTarget().get(); 381b9c1b51eSKate Stone // N.B. The attach should be synchronous. It doesn't help much to get the 38205097246SAdrian Prantl // prompt back between initiating the attach and the target actually 38305097246SAdrian Prantl // stopping. So even if the interpreter is set to be asynchronous, we wait 38405097246SAdrian Prantl // for the stop ourselves here. 3855aee162fSJim Ingham 38671337622SGreg Clayton StateType state = eStateInvalid; 387dcb1d856SJim Ingham Process *process = m_exe_ctx.GetProcessPtr(); 388dcb1d856SJim Ingham 389dcb1d856SJim Ingham if (!StopProcessIfNecessary(process, state, result)) 3905aee162fSJim Ingham return false; 3915aee162fSJim Ingham 392b9c1b51eSKate Stone if (target == nullptr) { 3935aee162fSJim Ingham // If there isn't a current target create one. 3945aee162fSJim Ingham TargetSP new_target_sp; 39597206d57SZachary Turner Status error; 3965aee162fSJim Ingham 39757179860SJonas Devlieghere error = GetDebugger().GetTargetList().CreateTarget( 39857179860SJonas Devlieghere GetDebugger(), "", "", eLoadDependentsNo, 39949bcfd80SEugene Zelenko nullptr, // No platform options 4005aee162fSJim Ingham new_target_sp); 4015aee162fSJim Ingham target = new_target_sp.get(); 402b9c1b51eSKate Stone if (target == nullptr || error.Fail()) { 403b766a73dSGreg Clayton result.AppendError(error.AsCString("Error creating target")); 4045aee162fSJim Ingham return false; 4055aee162fSJim Ingham } 40657179860SJonas Devlieghere GetDebugger().GetTargetList().SetSelectedTarget(target); 4075aee162fSJim Ingham } 4085aee162fSJim Ingham 409b9c1b51eSKate Stone // Record the old executable module, we want to issue a warning if the 41005097246SAdrian Prantl // process of attaching changed the current executable (like somebody said 41105097246SAdrian Prantl // "file foo" then attached to a PID whose executable was bar.) 4125aee162fSJim Ingham 4135aee162fSJim Ingham ModuleSP old_exec_module_sp = target->GetExecutableModule(); 4145aee162fSJim Ingham ArchSpec old_arch_spec = target->GetArchitecture(); 4155aee162fSJim Ingham 416b9c1b51eSKate Stone if (command.GetArgumentCount()) { 417b9c1b51eSKate Stone result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", 418b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str()); 4195aee162fSJim Ingham result.SetStatus(eReturnStatusFailed); 420926af0cdSOleksiy Vyalov return false; 42171337622SGreg Clayton } 4225aee162fSJim Ingham 423926af0cdSOleksiy Vyalov m_interpreter.UpdateExecutionContext(nullptr); 42437386143SOleksiy Vyalov StreamString stream; 42537386143SOleksiy Vyalov const auto error = target->Attach(m_options.attach_info, &stream); 426b9c1b51eSKate Stone if (error.Success()) { 42737386143SOleksiy Vyalov ProcessSP process_sp(target->GetProcessSP()); 428b9c1b51eSKate Stone if (process_sp) { 429c156427dSZachary Turner result.AppendMessage(stream.GetString()); 430bb3a283bSJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 43137386143SOleksiy Vyalov result.SetDidChangeProcessState(true); 432b9c1b51eSKate Stone } else { 433b9c1b51eSKate Stone result.AppendError( 434b9c1b51eSKate Stone "no error returned from Target::Attach, and target has no process"); 435aa739093SJohnny Chen result.SetStatus(eReturnStatusFailed); 43644d93782SGreg Clayton } 437b9c1b51eSKate Stone } else { 43844d93782SGreg Clayton result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString()); 43944d93782SGreg Clayton result.SetStatus(eReturnStatusFailed); 440aa739093SJohnny Chen } 4415aee162fSJim Ingham 442926af0cdSOleksiy Vyalov if (!result.Succeeded()) 443926af0cdSOleksiy Vyalov return false; 444926af0cdSOleksiy Vyalov 445b9c1b51eSKate Stone // Okay, we're done. Last step is to warn if the executable module has 446b9c1b51eSKate Stone // changed: 447513c26ceSGreg Clayton char new_path[PATH_MAX]; 448aa149cbdSGreg Clayton ModuleSP new_exec_module_sp(target->GetExecutableModule()); 449b9c1b51eSKate Stone if (!old_exec_module_sp) { 450513c26ceSGreg Clayton // We might not have a module if we attached to a raw pid... 451b9c1b51eSKate Stone if (new_exec_module_sp) { 452aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 453b9c1b51eSKate Stone result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 454b9c1b51eSKate Stone new_path); 455513c26ceSGreg Clayton } 456b9c1b51eSKate Stone } else if (old_exec_module_sp->GetFileSpec() != 457b9c1b51eSKate Stone new_exec_module_sp->GetFileSpec()) { 458513c26ceSGreg Clayton char old_path[PATH_MAX]; 4595aee162fSJim Ingham 4605aee162fSJim Ingham old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 461aa149cbdSGreg Clayton new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); 4625aee162fSJim Ingham 463b9c1b51eSKate Stone result.AppendWarningWithFormat( 464b9c1b51eSKate Stone "Executable module changed from \"%s\" to \"%s\".\n", old_path, 465b9c1b51eSKate Stone new_path); 4665aee162fSJim Ingham } 4675aee162fSJim Ingham 468b9c1b51eSKate Stone if (!old_arch_spec.IsValid()) { 469b9c1b51eSKate Stone result.AppendMessageWithFormat( 470b9c1b51eSKate Stone "Architecture set to: %s.\n", 471b9c1b51eSKate Stone target->GetArchitecture().GetTriple().getTriple().c_str()); 472b9c1b51eSKate Stone } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) { 473b9c1b51eSKate Stone result.AppendWarningWithFormat( 474b9c1b51eSKate Stone "Architecture changed from %s to %s.\n", 475c1b1f1eaSGreg Clayton old_arch_spec.GetTriple().getTriple().c_str(), 476c1b1f1eaSGreg Clayton target->GetArchitecture().GetTriple().getTriple().c_str()); 4775aee162fSJim Ingham } 478a95ce623SJohnny Chen 47905097246SAdrian Prantl // This supports the use-case scenario of immediately continuing the 48005097246SAdrian Prantl // process once attached. 481a95ce623SJohnny Chen if (m_options.attach_info.GetContinueOnceAttached()) 4825bcaf583SSean Callanan m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); 483926af0cdSOleksiy Vyalov 4845aee162fSJim Ingham return result.Succeeded(); 4855aee162fSJim Ingham } 4865aee162fSJim Ingham 48730fdc8d8SChris Lattner CommandOptions m_options; 48830fdc8d8SChris Lattner }; 48930fdc8d8SChris Lattner 49030fdc8d8SChris Lattner // CommandObjectProcessContinue 4911f0f5b5bSZachary Turner 492438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_continue 493438dfcffSRaphael Isemann #include "CommandOptions.inc" 4941f0f5b5bSZachary Turner 495bb9caf73SJim Ingham #pragma mark CommandObjectProcessContinue 49630fdc8d8SChris Lattner 497b9c1b51eSKate Stone class CommandObjectProcessContinue : public CommandObjectParsed { 49830fdc8d8SChris Lattner public: 499b9c1b51eSKate Stone CommandObjectProcessContinue(CommandInterpreter &interpreter) 500b9c1b51eSKate Stone : CommandObjectParsed( 501b9c1b51eSKate Stone interpreter, "process continue", 502e3d26315SCaroline Tice "Continue execution of all threads in the current process.", 50330fdc8d8SChris Lattner "process continue", 504b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 505b9c1b51eSKate Stone eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), 506b9c1b51eSKate Stone m_options() {} 50730fdc8d8SChris Lattner 50849bcfd80SEugene Zelenko ~CommandObjectProcessContinue() override = default; 50930fdc8d8SChris Lattner 5105a988416SJim Ingham protected: 511b9c1b51eSKate Stone class CommandOptions : public Options { 5120e41084aSJim Ingham public: 513b9c1b51eSKate Stone CommandOptions() : Options() { 514b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting 515b9c1b51eSKate Stone // () 516e1cfbc79STodd Fiala OptionParsingStarting(nullptr); 5170e41084aSJim Ingham } 5180e41084aSJim Ingham 51949bcfd80SEugene Zelenko ~CommandOptions() override = default; 5200e41084aSJim Ingham 52197206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 522b9c1b51eSKate Stone ExecutionContext *execution_context) override { 52397206d57SZachary Turner Status error; 5243bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 525b9c1b51eSKate Stone switch (short_option) { 5260e41084aSJim Ingham case 'i': 527fe11483bSZachary Turner if (option_arg.getAsInteger(0, m_ignore)) 528b9c1b51eSKate Stone error.SetErrorStringWithFormat( 529b9c1b51eSKate Stone "invalid value for ignore option: \"%s\", should be a number.", 530fe11483bSZachary Turner option_arg.str().c_str()); 5310e41084aSJim Ingham break; 5320e41084aSJim Ingham 5330e41084aSJim Ingham default: 53436162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 5350e41084aSJim Ingham } 5360e41084aSJim Ingham return error; 5370e41084aSJim Ingham } 5380e41084aSJim Ingham 539b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 5400e41084aSJim Ingham m_ignore = 0; 5410e41084aSJim Ingham } 5420e41084aSJim Ingham 5431f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 54470602439SZachary Turner return llvm::makeArrayRef(g_process_continue_options); 5451f0f5b5bSZachary Turner } 5460e41084aSJim Ingham 5470e41084aSJim Ingham uint32_t m_ignore; 5480e41084aSJim Ingham }; 5490e41084aSJim Ingham 550b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 551f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 552a7015092SGreg Clayton bool synchronous_execution = m_interpreter.GetSynchronous(); 55330fdc8d8SChris Lattner StateType state = process->GetState(); 554b9c1b51eSKate Stone if (state == eStateStopped) { 555b9c1b51eSKate Stone if (command.GetArgumentCount() != 0) { 556b9c1b51eSKate Stone result.AppendErrorWithFormat( 557b9c1b51eSKate Stone "The '%s' command does not take any arguments.\n", 558b9c1b51eSKate Stone m_cmd_name.c_str()); 55930fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 56030fdc8d8SChris Lattner return false; 56130fdc8d8SChris Lattner } 56230fdc8d8SChris Lattner 563b9c1b51eSKate Stone if (m_options.m_ignore > 0) { 5648d94ba0fSJim Ingham ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this()); 565b9c1b51eSKate Stone if (sel_thread_sp) { 5660e41084aSJim Ingham StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo(); 567b9c1b51eSKate Stone if (stop_info_sp && 568b9c1b51eSKate Stone stop_info_sp->GetStopReason() == eStopReasonBreakpoint) { 569b9c1b51eSKate Stone lldb::break_id_t bp_site_id = 570b9c1b51eSKate Stone (lldb::break_id_t)stop_info_sp->GetValue(); 571b9c1b51eSKate Stone BreakpointSiteSP bp_site_sp( 572b9c1b51eSKate Stone process->GetBreakpointSiteList().FindByID(bp_site_id)); 573b9c1b51eSKate Stone if (bp_site_sp) { 574c7bece56SGreg Clayton const size_t num_owners = bp_site_sp->GetNumberOfOwners(); 575b9c1b51eSKate Stone for (size_t i = 0; i < num_owners; i++) { 576b9c1b51eSKate Stone Breakpoint &bp_ref = 577b9c1b51eSKate Stone bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 578b9c1b51eSKate Stone if (!bp_ref.IsInternal()) { 5790e41084aSJim Ingham bp_ref.SetIgnoreCount(m_options.m_ignore); 5800e41084aSJim Ingham } 5810e41084aSJim Ingham } 5820e41084aSJim Ingham } 5830e41084aSJim Ingham } 5840e41084aSJim Ingham } 5850e41084aSJim Ingham } 5860e41084aSJim Ingham 58741f2b940SJim Ingham { // Scope for thread list mutex: 588b9c1b51eSKate Stone std::lock_guard<std::recursive_mutex> guard( 589b9c1b51eSKate Stone process->GetThreadList().GetMutex()); 59030fdc8d8SChris Lattner const uint32_t num_threads = process->GetThreadList().GetSize(); 59130fdc8d8SChris Lattner 59230fdc8d8SChris Lattner // Set the actions that the threads should each take when resuming 593b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_threads; ++idx) { 5946c9ed91cSJim Ingham const bool override_suspend = false; 595b9c1b51eSKate Stone process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState( 596b9c1b51eSKate Stone eStateRunning, override_suspend); 59730fdc8d8SChris Lattner } 59841f2b940SJim Ingham } 59930fdc8d8SChris Lattner 6004446487dSPavel Labath const uint32_t iohandler_id = process->GetIOHandlerID(); 6014446487dSPavel Labath 602dc6224e0SGreg Clayton StreamString stream; 60397206d57SZachary Turner Status error; 604dc6224e0SGreg Clayton if (synchronous_execution) 605dc6224e0SGreg Clayton error = process->ResumeSynchronous(&stream); 606dc6224e0SGreg Clayton else 607dc6224e0SGreg Clayton error = process->Resume(); 608a3b89e27STodd Fiala 609b9c1b51eSKate Stone if (error.Success()) { 610b9c1b51eSKate Stone // There is a race condition where this thread will return up the call 61105097246SAdrian Prantl // stack to the main command handler and show an (lldb) prompt before 61205097246SAdrian Prantl // HandlePrivateEvent (from PrivateStateThread) has a chance to call 61305097246SAdrian Prantl // PushProcessIOHandler(). 6143879fe00SPavel Labath process->SyncIOHandler(iohandler_id, std::chrono::seconds(2)); 615a3b89e27STodd Fiala 616b9c1b51eSKate Stone result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n", 617b9c1b51eSKate Stone process->GetID()); 618b9c1b51eSKate Stone if (synchronous_execution) { 619b9c1b51eSKate Stone // If any state changed events had anything to say, add that to the 620b9c1b51eSKate Stone // result 621c156427dSZachary Turner result.AppendMessage(stream.GetString()); 62230fdc8d8SChris Lattner 62330fdc8d8SChris Lattner result.SetDidChangeProcessState(true); 62430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 625b9c1b51eSKate Stone } else { 62630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessContinuingNoResult); 62730fdc8d8SChris Lattner } 628b9c1b51eSKate Stone } else { 629b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to resume process: %s.\n", 630b9c1b51eSKate Stone error.AsCString()); 63130fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 63230fdc8d8SChris Lattner } 633b9c1b51eSKate Stone } else { 634b9c1b51eSKate Stone result.AppendErrorWithFormat( 635b9c1b51eSKate Stone "Process cannot be continued from its current state (%s).\n", 63630fdc8d8SChris Lattner StateAsCString(state)); 63730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 63830fdc8d8SChris Lattner } 63930fdc8d8SChris Lattner return result.Succeeded(); 64030fdc8d8SChris Lattner } 6410e41084aSJim Ingham 642b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 6430e41084aSJim Ingham 6440e41084aSJim Ingham CommandOptions m_options; 6450e41084aSJim Ingham }; 6460e41084aSJim Ingham 64730fdc8d8SChris Lattner // CommandObjectProcessDetach 648438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_detach 649438dfcffSRaphael Isemann #include "CommandOptions.inc" 6501f0f5b5bSZachary Turner 651bb9caf73SJim Ingham #pragma mark CommandObjectProcessDetach 65230fdc8d8SChris Lattner 653b9c1b51eSKate Stone class CommandObjectProcessDetach : public CommandObjectParsed { 65430fdc8d8SChris Lattner public: 655b9c1b51eSKate Stone class CommandOptions : public Options { 656acff8950SJim Ingham public: 657b9c1b51eSKate Stone CommandOptions() : Options() { OptionParsingStarting(nullptr); } 658acff8950SJim Ingham 65949bcfd80SEugene Zelenko ~CommandOptions() override = default; 660acff8950SJim Ingham 66197206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 662b9c1b51eSKate Stone ExecutionContext *execution_context) override { 66397206d57SZachary Turner Status error; 664acff8950SJim Ingham const int short_option = m_getopt_table[option_idx].val; 665acff8950SJim Ingham 666b9c1b51eSKate Stone switch (short_option) { 667acff8950SJim Ingham case 's': 668acff8950SJim Ingham bool tmp_result; 669acff8950SJim Ingham bool success; 67047cbf4a0SPavel Labath tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success); 671acff8950SJim Ingham if (!success) 672b9c1b51eSKate Stone error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", 673fe11483bSZachary Turner option_arg.str().c_str()); 674b9c1b51eSKate Stone else { 675acff8950SJim Ingham if (tmp_result) 676acff8950SJim Ingham m_keep_stopped = eLazyBoolYes; 677acff8950SJim Ingham else 678acff8950SJim Ingham m_keep_stopped = eLazyBoolNo; 679acff8950SJim Ingham } 680acff8950SJim Ingham break; 681acff8950SJim Ingham default: 68236162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 683acff8950SJim Ingham } 684acff8950SJim Ingham return error; 685acff8950SJim Ingham } 686acff8950SJim Ingham 687b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 688acff8950SJim Ingham m_keep_stopped = eLazyBoolCalculate; 689acff8950SJim Ingham } 690acff8950SJim Ingham 6911f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 69270602439SZachary Turner return llvm::makeArrayRef(g_process_detach_options); 6931f0f5b5bSZachary Turner } 694acff8950SJim Ingham 695acff8950SJim Ingham // Instance variables to hold the values for command options. 696acff8950SJim Ingham LazyBool m_keep_stopped; 697acff8950SJim Ingham }; 69830fdc8d8SChris Lattner 6997428a18cSKate Stone CommandObjectProcessDetach(CommandInterpreter &interpreter) 700b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process detach", 701b9c1b51eSKate Stone "Detach from the current target process.", 702a7015092SGreg Clayton "process detach", 703b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 704b9c1b51eSKate Stone eCommandProcessMustBeLaunched), 705b9c1b51eSKate Stone m_options() {} 70630fdc8d8SChris Lattner 70749bcfd80SEugene Zelenko ~CommandObjectProcessDetach() override = default; 70830fdc8d8SChris Lattner 709b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 710acff8950SJim Ingham 7115a988416SJim Ingham protected: 712b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 713f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 714acff8950SJim Ingham // FIXME: This will be a Command Option: 715acff8950SJim Ingham bool keep_stopped; 716b9c1b51eSKate Stone if (m_options.m_keep_stopped == eLazyBoolCalculate) { 717acff8950SJim Ingham // Check the process default: 71849bcfd80SEugene Zelenko keep_stopped = process->GetDetachKeepsStopped(); 719b9c1b51eSKate Stone } else if (m_options.m_keep_stopped == eLazyBoolYes) 720acff8950SJim Ingham keep_stopped = true; 721acff8950SJim Ingham else 722acff8950SJim Ingham keep_stopped = false; 723acff8950SJim Ingham 72497206d57SZachary Turner Status error(process->Detach(keep_stopped)); 725b9c1b51eSKate Stone if (error.Success()) { 72630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 727b9c1b51eSKate Stone } else { 72830fdc8d8SChris Lattner result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString()); 72930fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 73030fdc8d8SChris Lattner return false; 73130fdc8d8SChris Lattner } 73230fdc8d8SChris Lattner return result.Succeeded(); 73330fdc8d8SChris Lattner } 734acff8950SJim Ingham 735acff8950SJim Ingham CommandOptions m_options; 736acff8950SJim Ingham }; 737acff8950SJim Ingham 738b766a73dSGreg Clayton // CommandObjectProcessConnect 739438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_connect 740438dfcffSRaphael Isemann #include "CommandOptions.inc" 7411f0f5b5bSZachary Turner 742b766a73dSGreg Clayton #pragma mark CommandObjectProcessConnect 743b766a73dSGreg Clayton 744b9c1b51eSKate Stone class CommandObjectProcessConnect : public CommandObjectParsed { 745b766a73dSGreg Clayton public: 746b9c1b51eSKate Stone class CommandOptions : public Options { 747b766a73dSGreg Clayton public: 748b9c1b51eSKate Stone CommandOptions() : Options() { 749b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting 750b9c1b51eSKate Stone // () 751e1cfbc79STodd Fiala OptionParsingStarting(nullptr); 752b766a73dSGreg Clayton } 753b766a73dSGreg Clayton 75449bcfd80SEugene Zelenko ~CommandOptions() override = default; 755b766a73dSGreg Clayton 75697206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 757b9c1b51eSKate Stone ExecutionContext *execution_context) override { 75897206d57SZachary Turner Status error; 7593bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 760b766a73dSGreg Clayton 761b9c1b51eSKate Stone switch (short_option) { 762b766a73dSGreg Clayton case 'p': 763b766a73dSGreg Clayton plugin_name.assign(option_arg); 764b766a73dSGreg Clayton break; 765b766a73dSGreg Clayton 766b766a73dSGreg Clayton default: 76736162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 768b766a73dSGreg Clayton } 769b766a73dSGreg Clayton return error; 770b766a73dSGreg Clayton } 771b766a73dSGreg Clayton 772b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 773b766a73dSGreg Clayton plugin_name.clear(); 774b766a73dSGreg Clayton } 775b766a73dSGreg Clayton 7761f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 77770602439SZachary Turner return llvm::makeArrayRef(g_process_connect_options); 7781f0f5b5bSZachary Turner } 779b766a73dSGreg Clayton 780b766a73dSGreg Clayton // Instance variables to hold the values for command options. 781b766a73dSGreg Clayton 782b766a73dSGreg Clayton std::string plugin_name; 783b766a73dSGreg Clayton }; 784b766a73dSGreg Clayton 785b9c1b51eSKate Stone CommandObjectProcessConnect(CommandInterpreter &interpreter) 786b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process connect", 787b766a73dSGreg Clayton "Connect to a remote debug service.", 788b9c1b51eSKate Stone "process connect <remote-url>", 0), 789b9c1b51eSKate Stone m_options() {} 790b766a73dSGreg Clayton 79149bcfd80SEugene Zelenko ~CommandObjectProcessConnect() override = default; 792b766a73dSGreg Clayton 793b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 7945a988416SJim Ingham 7955a988416SJim Ingham protected: 796b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 797b9c1b51eSKate Stone if (command.GetArgumentCount() != 1) { 798b9c1b51eSKate Stone result.AppendErrorWithFormat( 799b9c1b51eSKate Stone "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(), 800ccd6cffbSTamas Berghammer m_cmd_syntax.c_str()); 801ccd6cffbSTamas Berghammer result.SetStatus(eReturnStatusFailed); 802ccd6cffbSTamas Berghammer return false; 803ccd6cffbSTamas Berghammer } 804ccd6cffbSTamas Berghammer 805ccd6cffbSTamas Berghammer Process *process = m_exe_ctx.GetProcessPtr(); 806b9c1b51eSKate Stone if (process && process->IsAlive()) { 807b9c1b51eSKate Stone result.AppendErrorWithFormat( 808b9c1b51eSKate Stone "Process %" PRIu64 809b9c1b51eSKate Stone " is currently being debugged, kill the process before connecting.\n", 810b766a73dSGreg Clayton process->GetID()); 811b766a73dSGreg Clayton result.SetStatus(eReturnStatusFailed); 812b766a73dSGreg Clayton return false; 813b766a73dSGreg Clayton } 814b766a73dSGreg Clayton 815ccd6cffbSTamas Berghammer const char *plugin_name = nullptr; 816b766a73dSGreg Clayton if (!m_options.plugin_name.empty()) 817b766a73dSGreg Clayton plugin_name = m_options.plugin_name.c_str(); 818b766a73dSGreg Clayton 81997206d57SZachary Turner Status error; 82057179860SJonas Devlieghere Debugger &debugger = GetDebugger(); 821ccd6cffbSTamas Berghammer PlatformSP platform_sp = m_interpreter.GetPlatform(true); 822b9c1b51eSKate Stone ProcessSP process_sp = platform_sp->ConnectProcess( 823b9c1b51eSKate Stone command.GetArgumentAtIndex(0), plugin_name, debugger, 824b9c1b51eSKate Stone debugger.GetSelectedTarget().get(), error); 825b9c1b51eSKate Stone if (error.Fail() || process_sp == nullptr) { 826ccd6cffbSTamas Berghammer result.AppendError(error.AsCString("Error connecting to the process")); 827b766a73dSGreg Clayton result.SetStatus(eReturnStatusFailed); 828b766a73dSGreg Clayton return false; 829b766a73dSGreg Clayton } 830ccd6cffbSTamas Berghammer return true; 831b766a73dSGreg Clayton } 832b766a73dSGreg Clayton 833b766a73dSGreg Clayton CommandOptions m_options; 834b766a73dSGreg Clayton }; 835b766a73dSGreg Clayton 836998255bfSGreg Clayton // CommandObjectProcessPlugin 837998255bfSGreg Clayton #pragma mark CommandObjectProcessPlugin 838998255bfSGreg Clayton 839b9c1b51eSKate Stone class CommandObjectProcessPlugin : public CommandObjectProxy { 840998255bfSGreg Clayton public: 8417428a18cSKate Stone CommandObjectProcessPlugin(CommandInterpreter &interpreter) 842b9c1b51eSKate Stone : CommandObjectProxy( 843b9c1b51eSKate Stone interpreter, "process plugin", 844b9c1b51eSKate Stone "Send a custom command to the current target process plug-in.", 845b9c1b51eSKate Stone "process plugin <args>", 0) {} 846998255bfSGreg Clayton 84749bcfd80SEugene Zelenko ~CommandObjectProcessPlugin() override = default; 848998255bfSGreg Clayton 849b9c1b51eSKate Stone CommandObject *GetProxyCommandObject() override { 850e05b2efeSGreg Clayton Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 851998255bfSGreg Clayton if (process) 852998255bfSGreg Clayton return process->GetPluginCommandObject(); 85349bcfd80SEugene Zelenko return nullptr; 854998255bfSGreg Clayton } 855998255bfSGreg Clayton }; 856998255bfSGreg Clayton 8578f343b09SGreg Clayton // CommandObjectProcessLoad 858438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_load 859438dfcffSRaphael Isemann #include "CommandOptions.inc" 8601f0f5b5bSZachary Turner 861bb9caf73SJim Ingham #pragma mark CommandObjectProcessLoad 8628f343b09SGreg Clayton 863b9c1b51eSKate Stone class CommandObjectProcessLoad : public CommandObjectParsed { 8648f343b09SGreg Clayton public: 865b9c1b51eSKate Stone class CommandOptions : public Options { 8664fbd67acSTamas Berghammer public: 867b9c1b51eSKate Stone CommandOptions() : Options() { 868b9c1b51eSKate Stone // Keep default values of all options in one place: OptionParsingStarting 869b9c1b51eSKate Stone // () 870e1cfbc79STodd Fiala OptionParsingStarting(nullptr); 8714fbd67acSTamas Berghammer } 8724fbd67acSTamas Berghammer 8734fbd67acSTamas Berghammer ~CommandOptions() override = default; 8744fbd67acSTamas Berghammer 87597206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 876b9c1b51eSKate Stone ExecutionContext *execution_context) override { 87797206d57SZachary Turner Status error; 8784fbd67acSTamas Berghammer const int short_option = m_getopt_table[option_idx].val; 879b9c1b51eSKate Stone switch (short_option) { 8804fbd67acSTamas Berghammer case 'i': 8814fbd67acSTamas Berghammer do_install = true; 882fe11483bSZachary Turner if (!option_arg.empty()) 8838f3be7a3SJonas Devlieghere install_path.SetFile(option_arg, FileSpec::Style::native); 8844fbd67acSTamas Berghammer break; 8854fbd67acSTamas Berghammer default: 88636162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 8874fbd67acSTamas Berghammer } 8884fbd67acSTamas Berghammer return error; 8894fbd67acSTamas Berghammer } 8904fbd67acSTamas Berghammer 891b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 8924fbd67acSTamas Berghammer do_install = false; 8934fbd67acSTamas Berghammer install_path.Clear(); 8944fbd67acSTamas Berghammer } 8954fbd67acSTamas Berghammer 8961f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 89770602439SZachary Turner return llvm::makeArrayRef(g_process_load_options); 8981f0f5b5bSZachary Turner } 8994fbd67acSTamas Berghammer 9004fbd67acSTamas Berghammer // Instance variables to hold the values for command options. 9014fbd67acSTamas Berghammer bool do_install; 9024fbd67acSTamas Berghammer FileSpec install_path; 9034fbd67acSTamas Berghammer }; 9048f343b09SGreg Clayton 905b9c1b51eSKate Stone CommandObjectProcessLoad(CommandInterpreter &interpreter) 906b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process load", 9078f343b09SGreg Clayton "Load a shared library into the current process.", 9088f343b09SGreg Clayton "process load <filename> [<filename> ...]", 909b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 910e87764f2SEnrico Granata eCommandProcessMustBeLaunched | 9114fbd67acSTamas Berghammer eCommandProcessMustBePaused), 912b9c1b51eSKate Stone m_options() {} 9138f343b09SGreg Clayton 9144fbd67acSTamas Berghammer ~CommandObjectProcessLoad() override = default; 9154fbd67acSTamas Berghammer 916b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 9178f343b09SGreg Clayton 9185a988416SJim Ingham protected: 919b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 920f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 9218f343b09SGreg Clayton 92297d2c401SZachary Turner for (auto &entry : command.entries()) { 92397206d57SZachary Turner Status error; 9243cb132a0STamas Berghammer PlatformSP platform = process->GetTarget().GetPlatform(); 9250d9a201eSRaphael Isemann llvm::StringRef image_path = entry.ref(); 9264fbd67acSTamas Berghammer uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN; 9274fbd67acSTamas Berghammer 928b9c1b51eSKate Stone if (!m_options.do_install) { 9298f3be7a3SJonas Devlieghere FileSpec image_spec(image_path); 9303cb132a0STamas Berghammer platform->ResolveRemotePath(image_spec, image_spec); 931b9c1b51eSKate Stone image_token = 932b9c1b51eSKate Stone platform->LoadImage(process, FileSpec(), image_spec, error); 933b9c1b51eSKate Stone } else if (m_options.install_path) { 9348f3be7a3SJonas Devlieghere FileSpec image_spec(image_path); 9358f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(image_spec); 936b9c1b51eSKate Stone platform->ResolveRemotePath(m_options.install_path, 937b9c1b51eSKate Stone m_options.install_path); 938b9c1b51eSKate Stone image_token = platform->LoadImage(process, image_spec, 939b9c1b51eSKate Stone m_options.install_path, error); 940b9c1b51eSKate Stone } else { 9418f3be7a3SJonas Devlieghere FileSpec image_spec(image_path); 9428f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(image_spec); 943b9c1b51eSKate Stone image_token = 944b9c1b51eSKate Stone platform->LoadImage(process, image_spec, FileSpec(), error); 9454fbd67acSTamas Berghammer } 9464fbd67acSTamas Berghammer 947b9c1b51eSKate Stone if (image_token != LLDB_INVALID_IMAGE_TOKEN) { 948b9c1b51eSKate Stone result.AppendMessageWithFormat( 94997d2c401SZachary Turner "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(), 95097d2c401SZachary Turner image_token); 9518f343b09SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult); 952b9c1b51eSKate Stone } else { 95397d2c401SZachary Turner result.AppendErrorWithFormat("failed to load '%s': %s", 95497d2c401SZachary Turner image_path.str().c_str(), 955b9c1b51eSKate Stone error.AsCString()); 9568f343b09SGreg Clayton result.SetStatus(eReturnStatusFailed); 9578f343b09SGreg Clayton } 9588f343b09SGreg Clayton } 9598f343b09SGreg Clayton return result.Succeeded(); 9608f343b09SGreg Clayton } 9614fbd67acSTamas Berghammer 9624fbd67acSTamas Berghammer CommandOptions m_options; 9638f343b09SGreg Clayton }; 9648f343b09SGreg Clayton 9658f343b09SGreg Clayton // CommandObjectProcessUnload 966bb9caf73SJim Ingham #pragma mark CommandObjectProcessUnload 9678f343b09SGreg Clayton 968b9c1b51eSKate Stone class CommandObjectProcessUnload : public CommandObjectParsed { 9698f343b09SGreg Clayton public: 970b9c1b51eSKate Stone CommandObjectProcessUnload(CommandInterpreter &interpreter) 971b9c1b51eSKate Stone : CommandObjectParsed( 972b9c1b51eSKate Stone interpreter, "process unload", 973b9c1b51eSKate Stone "Unload a shared library from the current process using the index " 974b9c1b51eSKate Stone "returned by a previous call to \"process load\".", 9758f343b09SGreg Clayton "process unload <index>", 976b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 977b9c1b51eSKate Stone eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} 9788f343b09SGreg Clayton 97949bcfd80SEugene Zelenko ~CommandObjectProcessUnload() override = default; 9808f343b09SGreg Clayton 9815a988416SJim Ingham protected: 982b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 983f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 9848f343b09SGreg Clayton 98597d2c401SZachary Turner for (auto &entry : command.entries()) { 98697d2c401SZachary Turner uint32_t image_token; 9870d9a201eSRaphael Isemann if (entry.ref().getAsInteger(0, image_token)) { 988b9c1b51eSKate Stone result.AppendErrorWithFormat("invalid image index argument '%s'", 9890d9a201eSRaphael Isemann entry.ref().str().c_str()); 9908f343b09SGreg Clayton result.SetStatus(eReturnStatusFailed); 9918f343b09SGreg Clayton break; 992b9c1b51eSKate Stone } else { 99397206d57SZachary Turner Status error(process->GetTarget().GetPlatform()->UnloadImage( 994b9c1b51eSKate Stone process, image_token)); 995b9c1b51eSKate Stone if (error.Success()) { 996b9c1b51eSKate Stone result.AppendMessageWithFormat( 997b9c1b51eSKate Stone "Unloading shared library with index %u...ok\n", image_token); 9988f343b09SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult); 999b9c1b51eSKate Stone } else { 1000b9c1b51eSKate Stone result.AppendErrorWithFormat("failed to unload image: %s", 1001b9c1b51eSKate Stone error.AsCString()); 10028f343b09SGreg Clayton result.SetStatus(eReturnStatusFailed); 10038f343b09SGreg Clayton break; 10048f343b09SGreg Clayton } 10058f343b09SGreg Clayton } 10068f343b09SGreg Clayton } 10078f343b09SGreg Clayton return result.Succeeded(); 10088f343b09SGreg Clayton } 10098f343b09SGreg Clayton }; 10108f343b09SGreg Clayton 101130fdc8d8SChris Lattner // CommandObjectProcessSignal 1012bb9caf73SJim Ingham #pragma mark CommandObjectProcessSignal 101330fdc8d8SChris Lattner 1014b9c1b51eSKate Stone class CommandObjectProcessSignal : public CommandObjectParsed { 101530fdc8d8SChris Lattner public: 10167428a18cSKate Stone CommandObjectProcessSignal(CommandInterpreter &interpreter) 1017*a925974bSAdrian Prantl : CommandObjectParsed( 1018*a925974bSAdrian Prantl interpreter, "process signal", 1019*a925974bSAdrian Prantl "Send a UNIX signal to the current target process.", nullptr, 1020*a925974bSAdrian Prantl eCommandRequiresProcess | eCommandTryTargetAPILock) { 1021405fe67fSCaroline Tice CommandArgumentEntry arg; 1022405fe67fSCaroline Tice CommandArgumentData signal_arg; 1023405fe67fSCaroline Tice 1024405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 1025c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1026405fe67fSCaroline Tice signal_arg.arg_repetition = eArgRepeatPlain; 1027405fe67fSCaroline Tice 1028b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 1029b9c1b51eSKate Stone // argument entry. 1030405fe67fSCaroline Tice arg.push_back(signal_arg); 1031405fe67fSCaroline Tice 1032405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 1033405fe67fSCaroline Tice m_arguments.push_back(arg); 103430fdc8d8SChris Lattner } 103530fdc8d8SChris Lattner 103649bcfd80SEugene Zelenko ~CommandObjectProcessSignal() override = default; 103730fdc8d8SChris Lattner 10385a988416SJim Ingham protected: 1039b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1040f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 104130fdc8d8SChris Lattner 1042b9c1b51eSKate Stone if (command.GetArgumentCount() == 1) { 1043237cd906SGreg Clayton int signo = LLDB_INVALID_SIGNAL_NUMBER; 1044237cd906SGreg Clayton 1045237cd906SGreg Clayton const char *signal_name = command.GetArgumentAtIndex(0); 1046237cd906SGreg Clayton if (::isxdigit(signal_name[0])) 1047b9c1b51eSKate Stone signo = 1048b9c1b51eSKate Stone StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1049237cd906SGreg Clayton else 105098d0a4b3SChaoren Lin signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); 1051237cd906SGreg Clayton 1052b9c1b51eSKate Stone if (signo == LLDB_INVALID_SIGNAL_NUMBER) { 1053b9c1b51eSKate Stone result.AppendErrorWithFormat("Invalid signal argument '%s'.\n", 1054b9c1b51eSKate Stone command.GetArgumentAtIndex(0)); 105530fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 1056b9c1b51eSKate Stone } else { 105797206d57SZachary Turner Status error(process->Signal(signo)); 1058b9c1b51eSKate Stone if (error.Success()) { 105930fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 1060b9c1b51eSKate Stone } else { 1061b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo, 1062b9c1b51eSKate Stone error.AsCString()); 106330fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 106430fdc8d8SChris Lattner } 106530fdc8d8SChris Lattner } 1066b9c1b51eSKate Stone } else { 1067b9c1b51eSKate Stone result.AppendErrorWithFormat( 1068b9c1b51eSKate Stone "'%s' takes exactly one signal number argument:\nUsage: %s\n", 1069b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str()); 107030fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 107130fdc8d8SChris Lattner } 107230fdc8d8SChris Lattner return result.Succeeded(); 107330fdc8d8SChris Lattner } 107430fdc8d8SChris Lattner }; 107530fdc8d8SChris Lattner 107630fdc8d8SChris Lattner // CommandObjectProcessInterrupt 1077bb9caf73SJim Ingham #pragma mark CommandObjectProcessInterrupt 107830fdc8d8SChris Lattner 1079b9c1b51eSKate Stone class CommandObjectProcessInterrupt : public CommandObjectParsed { 108030fdc8d8SChris Lattner public: 10817428a18cSKate Stone CommandObjectProcessInterrupt(CommandInterpreter &interpreter) 1082b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process interrupt", 1083b9c1b51eSKate Stone "Interrupt the current target process.", 1084a7015092SGreg Clayton "process interrupt", 1085b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 1086b9c1b51eSKate Stone eCommandProcessMustBeLaunched) {} 108730fdc8d8SChris Lattner 108849bcfd80SEugene Zelenko ~CommandObjectProcessInterrupt() override = default; 108930fdc8d8SChris Lattner 10905a988416SJim Ingham protected: 1091b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1092f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 1093b9c1b51eSKate Stone if (process == nullptr) { 109430fdc8d8SChris Lattner result.AppendError("no process to halt"); 109530fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 109630fdc8d8SChris Lattner return false; 109730fdc8d8SChris Lattner } 109830fdc8d8SChris Lattner 1099b9c1b51eSKate Stone if (command.GetArgumentCount() == 0) { 1100f9b57b9dSGreg Clayton bool clear_thread_plans = true; 110197206d57SZachary Turner Status error(process->Halt(clear_thread_plans)); 1102b9c1b51eSKate Stone if (error.Success()) { 110330fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 1104b9c1b51eSKate Stone } else { 1105b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to halt process: %s\n", 1106b9c1b51eSKate Stone error.AsCString()); 110730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 110830fdc8d8SChris Lattner } 1109b9c1b51eSKate Stone } else { 1110fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1111b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str()); 111230fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 111330fdc8d8SChris Lattner } 111430fdc8d8SChris Lattner return result.Succeeded(); 111530fdc8d8SChris Lattner } 111630fdc8d8SChris Lattner }; 111730fdc8d8SChris Lattner 111830fdc8d8SChris Lattner // CommandObjectProcessKill 1119bb9caf73SJim Ingham #pragma mark CommandObjectProcessKill 112030fdc8d8SChris Lattner 1121b9c1b51eSKate Stone class CommandObjectProcessKill : public CommandObjectParsed { 112230fdc8d8SChris Lattner public: 11237428a18cSKate Stone CommandObjectProcessKill(CommandInterpreter &interpreter) 1124b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process kill", 1125b9c1b51eSKate Stone "Terminate the current target process.", 1126b9c1b51eSKate Stone "process kill", 1127b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 1128b9c1b51eSKate Stone eCommandProcessMustBeLaunched) {} 112930fdc8d8SChris Lattner 113049bcfd80SEugene Zelenko ~CommandObjectProcessKill() override = default; 113130fdc8d8SChris Lattner 11325a988416SJim Ingham protected: 1133b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1134f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 1135b9c1b51eSKate Stone if (process == nullptr) { 113630fdc8d8SChris Lattner result.AppendError("no process to kill"); 113730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 113830fdc8d8SChris Lattner return false; 113930fdc8d8SChris Lattner } 114030fdc8d8SChris Lattner 1141b9c1b51eSKate Stone if (command.GetArgumentCount() == 0) { 114297206d57SZachary Turner Status error(process->Destroy(true)); 1143b9c1b51eSKate Stone if (error.Success()) { 114430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 1145b9c1b51eSKate Stone } else { 1146b9c1b51eSKate Stone result.AppendErrorWithFormat("Failed to kill process: %s\n", 1147b9c1b51eSKate Stone error.AsCString()); 114830fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 114930fdc8d8SChris Lattner } 1150b9c1b51eSKate Stone } else { 1151fd54b368SJason Molenda result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1152b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str()); 115330fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 115430fdc8d8SChris Lattner } 115530fdc8d8SChris Lattner return result.Succeeded(); 115630fdc8d8SChris Lattner } 115730fdc8d8SChris Lattner }; 115830fdc8d8SChris Lattner 1159a2715cf1SGreg Clayton // CommandObjectProcessSaveCore 1160a2715cf1SGreg Clayton #pragma mark CommandObjectProcessSaveCore 1161a2715cf1SGreg Clayton 1162b9c1b51eSKate Stone class CommandObjectProcessSaveCore : public CommandObjectParsed { 1163a2715cf1SGreg Clayton public: 1164b9c1b51eSKate Stone CommandObjectProcessSaveCore(CommandInterpreter &interpreter) 1165b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process save-core", 1166b9c1b51eSKate Stone "Save the current process as a core file using an " 1167b9c1b51eSKate Stone "appropriate file type.", 1168a2715cf1SGreg Clayton "process save-core FILE", 1169b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock | 1170b9c1b51eSKate Stone eCommandProcessMustBeLaunched) {} 1171a2715cf1SGreg Clayton 117249bcfd80SEugene Zelenko ~CommandObjectProcessSaveCore() override = default; 1173a2715cf1SGreg Clayton 1174a2715cf1SGreg Clayton protected: 1175b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 1176a2715cf1SGreg Clayton ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 1177b9c1b51eSKate Stone if (process_sp) { 1178b9c1b51eSKate Stone if (command.GetArgumentCount() == 1) { 11798f3be7a3SJonas Devlieghere FileSpec output_file(command.GetArgumentAtIndex(0)); 118097206d57SZachary Turner Status error = PluginManager::SaveCore(process_sp, output_file); 1181b9c1b51eSKate Stone if (error.Success()) { 1182a2715cf1SGreg Clayton result.SetStatus(eReturnStatusSuccessFinishResult); 1183b9c1b51eSKate Stone } else { 1184b9c1b51eSKate Stone result.AppendErrorWithFormat( 1185b9c1b51eSKate Stone "Failed to save core file for process: %s\n", error.AsCString()); 1186a2715cf1SGreg Clayton result.SetStatus(eReturnStatusFailed); 1187a2715cf1SGreg Clayton } 1188b9c1b51eSKate Stone } else { 1189a2715cf1SGreg Clayton result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n", 1190b9c1b51eSKate Stone m_cmd_name.c_str(), m_cmd_syntax.c_str()); 1191a2715cf1SGreg Clayton result.SetStatus(eReturnStatusFailed); 1192a2715cf1SGreg Clayton } 1193b9c1b51eSKate Stone } else { 1194a2715cf1SGreg Clayton result.AppendError("invalid process"); 1195a2715cf1SGreg Clayton result.SetStatus(eReturnStatusFailed); 1196a2715cf1SGreg Clayton return false; 1197a2715cf1SGreg Clayton } 1198a2715cf1SGreg Clayton 1199a2715cf1SGreg Clayton return result.Succeeded(); 1200a2715cf1SGreg Clayton } 1201a2715cf1SGreg Clayton }; 1202a2715cf1SGreg Clayton 12034b9bea87SJim Ingham // CommandObjectProcessStatus 1204bb9caf73SJim Ingham #pragma mark CommandObjectProcessStatus 1205bb9caf73SJim Ingham 1206b9c1b51eSKate Stone class CommandObjectProcessStatus : public CommandObjectParsed { 12074b9bea87SJim Ingham public: 12087428a18cSKate Stone CommandObjectProcessStatus(CommandInterpreter &interpreter) 1209b9c1b51eSKate Stone : CommandObjectParsed( 1210b9c1b51eSKate Stone interpreter, "process status", 1211b9c1b51eSKate Stone "Show status and stop location for the current target process.", 1212b9c1b51eSKate Stone "process status", 1213b9c1b51eSKate Stone eCommandRequiresProcess | eCommandTryTargetAPILock) {} 12144b9bea87SJim Ingham 121549bcfd80SEugene Zelenko ~CommandObjectProcessStatus() override = default; 12164b9bea87SJim Ingham 1217b9c1b51eSKate Stone bool DoExecute(Args &command, CommandReturnObject &result) override { 12187260f620SGreg Clayton Stream &strm = result.GetOutputStream(); 12194b9bea87SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1220b9c1b51eSKate Stone // No need to check "process" for validity as eCommandRequiresProcess 1221b9c1b51eSKate Stone // ensures it is valid 1222f9fc609fSGreg Clayton Process *process = m_exe_ctx.GetProcessPtr(); 12237260f620SGreg Clayton const bool only_threads_with_stop_reason = true; 12247260f620SGreg Clayton const uint32_t start_frame = 0; 12257260f620SGreg Clayton const uint32_t num_frames = 1; 12267260f620SGreg Clayton const uint32_t num_frames_with_source = 1; 12276a9767c7SJim Ingham const bool stop_format = true; 1228c14ee32dSGreg Clayton process->GetStatus(strm); 1229b9c1b51eSKate Stone process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, 12306a9767c7SJim Ingham num_frames, num_frames_with_source, stop_format); 12314b9bea87SJim Ingham return result.Succeeded(); 12324b9bea87SJim Ingham } 12334b9bea87SJim Ingham }; 12344b9bea87SJim Ingham 123535731357SCaroline Tice // CommandObjectProcessHandle 1236438dfcffSRaphael Isemann #define LLDB_OPTIONS_process_handle 1237438dfcffSRaphael Isemann #include "CommandOptions.inc" 12381f0f5b5bSZachary Turner 1239bb9caf73SJim Ingham #pragma mark CommandObjectProcessHandle 124035731357SCaroline Tice 1241b9c1b51eSKate Stone class CommandObjectProcessHandle : public CommandObjectParsed { 124235731357SCaroline Tice public: 1243b9c1b51eSKate Stone class CommandOptions : public Options { 124435731357SCaroline Tice public: 1245b9c1b51eSKate Stone CommandOptions() : Options() { OptionParsingStarting(nullptr); } 124635731357SCaroline Tice 124749bcfd80SEugene Zelenko ~CommandOptions() override = default; 124835731357SCaroline Tice 124997206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1250b9c1b51eSKate Stone ExecutionContext *execution_context) override { 125197206d57SZachary Turner Status error; 12523bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 125335731357SCaroline Tice 1254b9c1b51eSKate Stone switch (short_option) { 125535731357SCaroline Tice case 's': 125635731357SCaroline Tice stop = option_arg; 125735731357SCaroline Tice break; 125835731357SCaroline Tice case 'n': 125935731357SCaroline Tice notify = option_arg; 126035731357SCaroline Tice break; 126135731357SCaroline Tice case 'p': 126235731357SCaroline Tice pass = option_arg; 126335731357SCaroline Tice break; 126435731357SCaroline Tice default: 126536162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 126635731357SCaroline Tice } 126735731357SCaroline Tice return error; 126835731357SCaroline Tice } 126935731357SCaroline Tice 1270b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 127135731357SCaroline Tice stop.clear(); 127235731357SCaroline Tice notify.clear(); 127335731357SCaroline Tice pass.clear(); 127435731357SCaroline Tice } 127535731357SCaroline Tice 12761f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 127770602439SZachary Turner return llvm::makeArrayRef(g_process_handle_options); 12781f0f5b5bSZachary Turner } 127935731357SCaroline Tice 128035731357SCaroline Tice // Instance variables to hold the values for command options. 128135731357SCaroline Tice 128235731357SCaroline Tice std::string stop; 128335731357SCaroline Tice std::string notify; 128435731357SCaroline Tice std::string pass; 128535731357SCaroline Tice }; 128635731357SCaroline Tice 12877428a18cSKate Stone CommandObjectProcessHandle(CommandInterpreter &interpreter) 1288b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "process handle", 1289b9c1b51eSKate Stone "Manage LLDB handling of OS signals for the " 1290b9c1b51eSKate Stone "current target process. Defaults to showing " 1291b9c1b51eSKate Stone "current policy.", 129204a4c091SRaphael Isemann nullptr, eCommandRequiresTarget), 1293b9c1b51eSKate Stone m_options() { 1294ea671fbdSKate Stone SetHelpLong("\nIf no signals are specified, update them all. If no update " 1295ea671fbdSKate Stone "option is specified, list the current values."); 129635731357SCaroline Tice CommandArgumentEntry arg; 1297c0dbdfb6SCaroline Tice CommandArgumentData signal_arg; 129835731357SCaroline Tice 1299c0dbdfb6SCaroline Tice signal_arg.arg_type = eArgTypeUnixSignal; 1300c0dbdfb6SCaroline Tice signal_arg.arg_repetition = eArgRepeatStar; 130135731357SCaroline Tice 1302c0dbdfb6SCaroline Tice arg.push_back(signal_arg); 130335731357SCaroline Tice 130435731357SCaroline Tice m_arguments.push_back(arg); 130535731357SCaroline Tice } 130635731357SCaroline Tice 130749bcfd80SEugene Zelenko ~CommandObjectProcessHandle() override = default; 130835731357SCaroline Tice 1309b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 131035731357SCaroline Tice 1311b9c1b51eSKate Stone bool VerifyCommandOptionValue(const std::string &option, int &real_value) { 131235731357SCaroline Tice bool okay = true; 131310ad7993SCaroline Tice bool success = false; 131447cbf4a0SPavel Labath bool tmp_value = OptionArgParser::ToBoolean(option, false, &success); 131510ad7993SCaroline Tice 131610ad7993SCaroline Tice if (success && tmp_value) 131710ad7993SCaroline Tice real_value = 1; 131810ad7993SCaroline Tice else if (success && !tmp_value) 131910ad7993SCaroline Tice real_value = 0; 1320b9c1b51eSKate Stone else { 132135731357SCaroline Tice // If the value isn't 'true' or 'false', it had better be 0 or 1. 13225275aaa0SVince Harron real_value = StringConvert::ToUInt32(option.c_str(), 3); 132310ad7993SCaroline Tice if (real_value != 0 && real_value != 1) 132435731357SCaroline Tice okay = false; 132535731357SCaroline Tice } 132635731357SCaroline Tice 132735731357SCaroline Tice return okay; 132835731357SCaroline Tice } 132935731357SCaroline Tice 1330b9c1b51eSKate Stone void PrintSignalHeader(Stream &str) { 133110ad7993SCaroline Tice str.Printf("NAME PASS STOP NOTIFY\n"); 1332b84141a6SPavel Labath str.Printf("=========== ===== ===== ======\n"); 133310ad7993SCaroline Tice } 133410ad7993SCaroline Tice 1335b9c1b51eSKate Stone void PrintSignal(Stream &str, int32_t signo, const char *sig_name, 1336b9c1b51eSKate Stone const UnixSignalsSP &signals_sp) { 133710ad7993SCaroline Tice bool stop; 133810ad7993SCaroline Tice bool suppress; 133910ad7993SCaroline Tice bool notify; 134010ad7993SCaroline Tice 1341b84141a6SPavel Labath str.Printf("%-11s ", sig_name); 1342b9c1b51eSKate Stone if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) { 134310ad7993SCaroline Tice bool pass = !suppress; 1344b9c1b51eSKate Stone str.Printf("%s %s %s", (pass ? "true " : "false"), 1345b9c1b51eSKate Stone (stop ? "true " : "false"), (notify ? "true " : "false")); 134610ad7993SCaroline Tice } 134710ad7993SCaroline Tice str.Printf("\n"); 134810ad7993SCaroline Tice } 134910ad7993SCaroline Tice 1350b9c1b51eSKate Stone void PrintSignalInformation(Stream &str, Args &signal_args, 1351b9c1b51eSKate Stone int num_valid_signals, 1352b9c1b51eSKate Stone const UnixSignalsSP &signals_sp) { 135310ad7993SCaroline Tice PrintSignalHeader(str); 135410ad7993SCaroline Tice 1355b9c1b51eSKate Stone if (num_valid_signals > 0) { 135610ad7993SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 1357b9c1b51eSKate Stone for (size_t i = 0; i < num_args; ++i) { 1358b9c1b51eSKate Stone int32_t signo = signals_sp->GetSignalNumberFromName( 1359b9c1b51eSKate Stone signal_args.GetArgumentAtIndex(i)); 136010ad7993SCaroline Tice if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1361b9c1b51eSKate Stone PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i), 1362b9c1b51eSKate Stone signals_sp); 136310ad7993SCaroline Tice } 1364b9c1b51eSKate Stone } else // Print info for ALL signals 136510ad7993SCaroline Tice { 136698d0a4b3SChaoren Lin int32_t signo = signals_sp->GetFirstSignalNumber(); 1367b9c1b51eSKate Stone while (signo != LLDB_INVALID_SIGNAL_NUMBER) { 1368b9c1b51eSKate Stone PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), 1369b9c1b51eSKate Stone signals_sp); 137098d0a4b3SChaoren Lin signo = signals_sp->GetNextSignalNumber(signo); 137110ad7993SCaroline Tice } 137210ad7993SCaroline Tice } 137310ad7993SCaroline Tice } 137410ad7993SCaroline Tice 13755a988416SJim Ingham protected: 1376b9c1b51eSKate Stone bool DoExecute(Args &signal_args, CommandReturnObject &result) override { 137704a4c091SRaphael Isemann Target *target_sp = &GetSelectedTarget(); 137835731357SCaroline Tice 137935731357SCaroline Tice ProcessSP process_sp = target_sp->GetProcessSP(); 138035731357SCaroline Tice 1381b9c1b51eSKate Stone if (!process_sp) { 1382b9c1b51eSKate Stone result.AppendError("No current process; cannot handle signals until you " 1383b9c1b51eSKate Stone "have a valid process.\n"); 138435731357SCaroline Tice result.SetStatus(eReturnStatusFailed); 138535731357SCaroline Tice return false; 138635731357SCaroline Tice } 138735731357SCaroline Tice 138835731357SCaroline Tice int stop_action = -1; // -1 means leave the current setting alone 138935731357SCaroline Tice int pass_action = -1; // -1 means leave the current setting alone 139035731357SCaroline Tice int notify_action = -1; // -1 means leave the current setting alone 139135731357SCaroline Tice 1392b9c1b51eSKate Stone if (!m_options.stop.empty() && 1393b9c1b51eSKate Stone !VerifyCommandOptionValue(m_options.stop, stop_action)) { 1394b9c1b51eSKate Stone result.AppendError("Invalid argument for command option --stop; must be " 1395b9c1b51eSKate Stone "true or false.\n"); 139635731357SCaroline Tice result.SetStatus(eReturnStatusFailed); 139735731357SCaroline Tice return false; 139835731357SCaroline Tice } 139935731357SCaroline Tice 1400b9c1b51eSKate Stone if (!m_options.notify.empty() && 1401b9c1b51eSKate Stone !VerifyCommandOptionValue(m_options.notify, notify_action)) { 1402b9c1b51eSKate Stone result.AppendError("Invalid argument for command option --notify; must " 1403b9c1b51eSKate Stone "be true or false.\n"); 140435731357SCaroline Tice result.SetStatus(eReturnStatusFailed); 140535731357SCaroline Tice return false; 140635731357SCaroline Tice } 140735731357SCaroline Tice 1408b9c1b51eSKate Stone if (!m_options.pass.empty() && 1409b9c1b51eSKate Stone !VerifyCommandOptionValue(m_options.pass, pass_action)) { 1410b9c1b51eSKate Stone result.AppendError("Invalid argument for command option --pass; must be " 1411b9c1b51eSKate Stone "true or false.\n"); 141235731357SCaroline Tice result.SetStatus(eReturnStatusFailed); 141335731357SCaroline Tice return false; 141435731357SCaroline Tice } 141535731357SCaroline Tice 141635731357SCaroline Tice size_t num_args = signal_args.GetArgumentCount(); 141798d0a4b3SChaoren Lin UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); 141835731357SCaroline Tice int num_signals_set = 0; 141935731357SCaroline Tice 1420b9c1b51eSKate Stone if (num_args > 0) { 1421d6a24757SZachary Turner for (const auto &arg : signal_args) { 1422d6a24757SZachary Turner int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str()); 1423b9c1b51eSKate Stone if (signo != LLDB_INVALID_SIGNAL_NUMBER) { 1424b9c1b51eSKate Stone // Casting the actions as bools here should be okay, because 142505097246SAdrian Prantl // VerifyCommandOptionValue guarantees the value is either 0 or 1. 142635731357SCaroline Tice if (stop_action != -1) 142798d0a4b3SChaoren Lin signals_sp->SetShouldStop(signo, stop_action); 1428b9c1b51eSKate Stone if (pass_action != -1) { 142998d0a4b3SChaoren Lin bool suppress = !pass_action; 143098d0a4b3SChaoren Lin signals_sp->SetShouldSuppress(signo, suppress); 143135731357SCaroline Tice } 143235731357SCaroline Tice if (notify_action != -1) 143398d0a4b3SChaoren Lin signals_sp->SetShouldNotify(signo, notify_action); 143435731357SCaroline Tice ++num_signals_set; 1435b9c1b51eSKate Stone } else { 1436b9c1b51eSKate Stone result.AppendErrorWithFormat("Invalid signal name '%s'\n", 1437d6a24757SZachary Turner arg.c_str()); 143835731357SCaroline Tice } 143935731357SCaroline Tice } 1440b9c1b51eSKate Stone } else { 1441b9c1b51eSKate Stone // No signal specified, if any command options were specified, update ALL 1442b9c1b51eSKate Stone // signals. 1443b9c1b51eSKate Stone if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) { 1444b9c1b51eSKate Stone if (m_interpreter.Confirm( 1445b9c1b51eSKate Stone "Do you really want to update all the signals?", false)) { 144698d0a4b3SChaoren Lin int32_t signo = signals_sp->GetFirstSignalNumber(); 1447b9c1b51eSKate Stone while (signo != LLDB_INVALID_SIGNAL_NUMBER) { 144810ad7993SCaroline Tice if (notify_action != -1) 144998d0a4b3SChaoren Lin signals_sp->SetShouldNotify(signo, notify_action); 145010ad7993SCaroline Tice if (stop_action != -1) 145198d0a4b3SChaoren Lin signals_sp->SetShouldStop(signo, stop_action); 1452b9c1b51eSKate Stone if (pass_action != -1) { 145398d0a4b3SChaoren Lin bool suppress = !pass_action; 145498d0a4b3SChaoren Lin signals_sp->SetShouldSuppress(signo, suppress); 145510ad7993SCaroline Tice } 145698d0a4b3SChaoren Lin signo = signals_sp->GetNextSignalNumber(signo); 145710ad7993SCaroline Tice } 145810ad7993SCaroline Tice } 145910ad7993SCaroline Tice } 146010ad7993SCaroline Tice } 146110ad7993SCaroline Tice 1462b9c1b51eSKate Stone PrintSignalInformation(result.GetOutputStream(), signal_args, 1463b9c1b51eSKate Stone num_signals_set, signals_sp); 146435731357SCaroline Tice 146535731357SCaroline Tice if (num_signals_set > 0) 146635731357SCaroline Tice result.SetStatus(eReturnStatusSuccessFinishNoResult); 146735731357SCaroline Tice else 146835731357SCaroline Tice result.SetStatus(eReturnStatusFailed); 146935731357SCaroline Tice 147035731357SCaroline Tice return result.Succeeded(); 147135731357SCaroline Tice } 147235731357SCaroline Tice 147335731357SCaroline Tice CommandOptions m_options; 147435731357SCaroline Tice }; 147535731357SCaroline Tice 147630fdc8d8SChris Lattner // CommandObjectMultiwordProcess 147730fdc8d8SChris Lattner 1478b9c1b51eSKate Stone CommandObjectMultiwordProcess::CommandObjectMultiwordProcess( 1479b9c1b51eSKate Stone CommandInterpreter &interpreter) 1480b9c1b51eSKate Stone : CommandObjectMultiword( 1481b9c1b51eSKate Stone interpreter, "process", 1482b9c1b51eSKate Stone "Commands for interacting with processes on the current platform.", 1483b9c1b51eSKate Stone "process <subcommand> [<subcommand-options>]") { 1484b9c1b51eSKate Stone LoadSubCommand("attach", 1485b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessAttach(interpreter))); 1486b9c1b51eSKate Stone LoadSubCommand("launch", 1487b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessLaunch(interpreter))); 1488b9c1b51eSKate Stone LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue( 1489b9c1b51eSKate Stone interpreter))); 1490b9c1b51eSKate Stone LoadSubCommand("connect", 1491b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessConnect(interpreter))); 1492b9c1b51eSKate Stone LoadSubCommand("detach", 1493b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessDetach(interpreter))); 1494b9c1b51eSKate Stone LoadSubCommand("load", 1495b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessLoad(interpreter))); 1496b9c1b51eSKate Stone LoadSubCommand("unload", 1497b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessUnload(interpreter))); 1498b9c1b51eSKate Stone LoadSubCommand("signal", 1499b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessSignal(interpreter))); 1500b9c1b51eSKate Stone LoadSubCommand("handle", 1501b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessHandle(interpreter))); 1502b9c1b51eSKate Stone LoadSubCommand("status", 1503b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessStatus(interpreter))); 1504b9c1b51eSKate Stone LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt( 1505b9c1b51eSKate Stone interpreter))); 1506b9c1b51eSKate Stone LoadSubCommand("kill", 1507b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessKill(interpreter))); 1508b9c1b51eSKate Stone LoadSubCommand("plugin", 1509b9c1b51eSKate Stone CommandObjectSP(new CommandObjectProcessPlugin(interpreter))); 1510b9c1b51eSKate Stone LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore( 1511b9c1b51eSKate Stone interpreter))); 151230fdc8d8SChris Lattner } 151330fdc8d8SChris Lattner 151449bcfd80SEugene Zelenko CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default; 1515