1 //===-- CommandObjectProcess.cpp ------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectProcess.h"
10 #include "lldb/Breakpoint/Breakpoint.h"
11 #include "lldb/Breakpoint/BreakpointLocation.h"
12 #include "lldb/Breakpoint/BreakpointSite.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Host/OptionParser.h"
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
18 #include "lldb/Interpreter/OptionArgParser.h"
19 #include "lldb/Interpreter/Options.h"
20 #include "lldb/Target/Platform.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/StopInfo.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Target/UnixSignals.h"
26 #include "lldb/Utility/Args.h"
27 #include "lldb/Utility/State.h"
30 using namespace lldb_private;
32 class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
34 CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
35 const char *name, const char *help,
36 const char *syntax, uint32_t flags,
37 const char *new_process_action)
38 : CommandObjectParsed(interpreter, name, help, syntax, flags),
39 m_new_process_action(new_process_action) {}
41 ~CommandObjectProcessLaunchOrAttach() override = default;
44 bool StopProcessIfNecessary(Process *process, StateType &state,
45 CommandReturnObject &result) {
46 state = eStateInvalid;
48 state = process->GetState();
50 if (process->IsAlive() && state != eStateConnected) {
52 if (process->GetState() == eStateAttaching)
53 ::snprintf(message, sizeof(message),
54 "There is a pending attach, abort it and %s?",
55 m_new_process_action.c_str());
56 else if (process->GetShouldDetach())
57 ::snprintf(message, sizeof(message),
58 "There is a running process, detach from it and %s?",
59 m_new_process_action.c_str());
61 ::snprintf(message, sizeof(message),
62 "There is a running process, kill it and %s?",
63 m_new_process_action.c_str());
65 if (!m_interpreter.Confirm(message, true)) {
66 result.SetStatus(eReturnStatusFailed);
69 if (process->GetShouldDetach()) {
70 bool keep_stopped = false;
71 Status detach_error(process->Detach(keep_stopped));
72 if (detach_error.Success()) {
73 result.SetStatus(eReturnStatusSuccessFinishResult);
76 result.AppendErrorWithFormat(
77 "Failed to detach from process: %s\n",
78 detach_error.AsCString());
79 result.SetStatus(eReturnStatusFailed);
82 Status destroy_error(process->Destroy(false));
83 if (destroy_error.Success()) {
84 result.SetStatus(eReturnStatusSuccessFinishResult);
87 result.AppendErrorWithFormat("Failed to kill process: %s\n",
88 destroy_error.AsCString());
89 result.SetStatus(eReturnStatusFailed);
95 return result.Succeeded();
98 std::string m_new_process_action;
101 // CommandObjectProcessLaunch
102 #pragma mark CommandObjectProcessLaunch
103 class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
105 CommandObjectProcessLaunch(CommandInterpreter &interpreter)
106 : CommandObjectProcessLaunchOrAttach(
107 interpreter, "process launch",
108 "Launch the executable in the debugger.", nullptr,
109 eCommandRequiresTarget, "restart"),
111 CommandArgumentEntry arg;
112 CommandArgumentData run_args_arg;
114 // Define the first (and only) variant of this arg.
115 run_args_arg.arg_type = eArgTypeRunArgs;
116 run_args_arg.arg_repetition = eArgRepeatOptional;
118 // There is only one variant this argument could be; put it into the
120 arg.push_back(run_args_arg);
122 // Push the data for the first argument into the m_arguments vector.
123 m_arguments.push_back(arg);
126 ~CommandObjectProcessLaunch() override = default;
129 HandleArgumentCompletion(CompletionRequest &request,
130 OptionElementVector &opt_element_vector) override {
132 CommandCompletions::InvokeCommonCompletionCallbacks(
133 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
137 Options *GetOptions() override { return &m_options; }
139 const char *GetRepeatCommand(Args ¤t_command_args,
140 uint32_t index) override {
141 // No repeat for "process launch"...
146 bool DoExecute(Args &launch_args, CommandReturnObject &result) override {
147 Debugger &debugger = GetDebugger();
148 Target *target = debugger.GetSelectedTarget().get();
149 // If our listener is nullptr, users aren't allows to launch
150 ModuleSP exe_module_sp = target->GetExecutableModule();
152 if (exe_module_sp == nullptr) {
153 result.AppendError("no file in target, create a debug target using the "
154 "'target create' command");
155 result.SetStatus(eReturnStatusFailed);
159 StateType state = eStateInvalid;
161 if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
164 llvm::StringRef target_settings_argv0 = target->GetArg0();
166 // Determine whether we will disable ASLR or leave it in the default state
167 // (i.e. enabled if the platform supports it). First check if the process
168 // launch options explicitly turn on/off
169 // disabling ASLR. If so, use that setting;
170 // otherwise, use the 'settings target.disable-aslr' setting.
171 bool disable_aslr = false;
172 if (m_options.disable_aslr != eLazyBoolCalculate) {
173 // The user specified an explicit setting on the process launch line.
175 disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
177 // The user did not explicitly specify whether to disable ASLR. Fall
178 // back to the target.disable-aslr setting.
179 disable_aslr = target->GetDisableASLR();
183 m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
185 m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
187 if (target->GetDetachOnError())
188 m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
190 if (target->GetDisableSTDIO())
191 m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
193 // Merge the launch info environment with the target environment.
194 Environment target_env = target->GetEnvironment();
195 m_options.launch_info.GetEnvironment().insert(target_env.begin(),
198 if (!target_settings_argv0.empty()) {
199 m_options.launch_info.GetArguments().AppendArgument(
200 target_settings_argv0);
201 m_options.launch_info.SetExecutableFile(
202 exe_module_sp->GetPlatformFileSpec(), false);
204 m_options.launch_info.SetExecutableFile(
205 exe_module_sp->GetPlatformFileSpec(), true);
208 if (launch_args.GetArgumentCount() == 0) {
209 m_options.launch_info.GetArguments().AppendArguments(
210 target->GetProcessLaunchInfo().GetArguments());
212 m_options.launch_info.GetArguments().AppendArguments(launch_args);
213 // Save the arguments for subsequent runs in the current target.
214 target->SetRunArguments(launch_args);
218 Status error = target->Launch(m_options.launch_info, &stream);
220 if (error.Success()) {
221 ProcessSP process_sp(target->GetProcessSP());
223 // There is a race condition where this thread will return up the call
224 // stack to the main command handler and show an (lldb) prompt before
225 // HandlePrivateEvent (from PrivateStateThread) has a chance to call
226 // PushProcessIOHandler().
227 process_sp->SyncIOHandler(0, std::chrono::seconds(2));
229 llvm::StringRef data = stream.GetString();
231 result.AppendMessage(data);
232 const char *archname =
233 exe_module_sp->GetArchitecture().GetArchitectureName();
234 result.AppendMessageWithFormat(
235 "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
236 exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
237 result.SetStatus(eReturnStatusSuccessFinishResult);
238 result.SetDidChangeProcessState(true);
241 "no error returned from Target::Launch, and target has no process");
242 result.SetStatus(eReturnStatusFailed);
245 result.AppendError(error.AsCString());
246 result.SetStatus(eReturnStatusFailed);
248 return result.Succeeded();
251 ProcessLaunchCommandOptions m_options;
254 #define LLDB_OPTIONS_process_attach
255 #include "CommandOptions.inc"
257 #pragma mark CommandObjectProcessAttach
258 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
260 class CommandOptions : public Options {
262 CommandOptions() : Options() {
263 // Keep default values of all options in one place: OptionParsingStarting
265 OptionParsingStarting(nullptr);
268 ~CommandOptions() override = default;
270 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
271 ExecutionContext *execution_context) override {
273 const int short_option = m_getopt_table[option_idx].val;
274 switch (short_option) {
276 attach_info.SetContinueOnceAttached(true);
281 if (option_arg.getAsInteger(0, pid)) {
282 error.SetErrorStringWithFormat("invalid process ID '%s'",
283 option_arg.str().c_str());
285 attach_info.SetProcessID(pid);
290 attach_info.SetProcessPluginName(option_arg);
294 attach_info.GetExecutableFile().SetFile(option_arg,
295 FileSpec::Style::native);
299 attach_info.SetWaitForLaunch(true);
303 attach_info.SetIgnoreExisting(false);
307 llvm_unreachable("Unimplemented option");
312 void OptionParsingStarting(ExecutionContext *execution_context) override {
316 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
317 return llvm::makeArrayRef(g_process_attach_options);
320 void HandleOptionArgumentCompletion(
321 CompletionRequest &request, OptionElementVector &opt_element_vector,
322 int opt_element_index, CommandInterpreter &interpreter) override {
323 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
324 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
326 switch (GetDefinitions()[opt_defs_index].short_option) {
328 // Look to see if there is a -P argument provided, and if so use that
329 // plugin, otherwise use the default plugin.
331 const char *partial_name = nullptr;
332 partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
334 PlatformSP platform_sp(interpreter.GetPlatform(true));
337 ProcessInstanceInfoList process_infos;
338 ProcessInstanceInfoMatch match_info;
340 match_info.GetProcessInfo().GetExecutableFile().SetFile(
341 partial_name, FileSpec::Style::native);
342 match_info.SetNameMatchType(NameMatch::StartsWith);
344 platform_sp->FindProcesses(match_info, process_infos);
345 const size_t num_matches = process_infos.size();
346 if (num_matches == 0)
348 for (size_t i = 0; i < num_matches; ++i) {
349 request.AddCompletion(process_infos[i].GetNameAsStringRef());
354 CommandCompletions::InvokeCommonCompletionCallbacks(
355 interpreter, CommandCompletions::eProcessPluginCompletion, request,
361 // Instance variables to hold the values for command options.
363 ProcessAttachInfo attach_info;
366 CommandObjectProcessAttach(CommandInterpreter &interpreter)
367 : CommandObjectProcessLaunchOrAttach(
368 interpreter, "process attach", "Attach to a process.",
369 "process attach <cmd-options>", 0, "attach"),
372 ~CommandObjectProcessAttach() override = default;
374 Options *GetOptions() override { return &m_options; }
377 bool DoExecute(Args &command, CommandReturnObject &result) override {
378 PlatformSP platform_sp(
379 GetDebugger().GetPlatformList().GetSelectedPlatform());
381 Target *target = GetDebugger().GetSelectedTarget().get();
382 // N.B. The attach should be synchronous. It doesn't help much to get the
383 // prompt back between initiating the attach and the target actually
384 // stopping. So even if the interpreter is set to be asynchronous, we wait
385 // for the stop ourselves here.
387 StateType state = eStateInvalid;
388 Process *process = m_exe_ctx.GetProcessPtr();
390 if (!StopProcessIfNecessary(process, state, result))
393 if (target == nullptr) {
394 // If there isn't a current target create one.
395 TargetSP new_target_sp;
398 error = GetDebugger().GetTargetList().CreateTarget(
399 GetDebugger(), "", "", eLoadDependentsNo,
400 nullptr, // No platform options
402 target = new_target_sp.get();
403 if (target == nullptr || error.Fail()) {
404 result.AppendError(error.AsCString("Error creating target"));
407 GetDebugger().GetTargetList().SetSelectedTarget(target);
410 // Record the old executable module, we want to issue a warning if the
411 // process of attaching changed the current executable (like somebody said
412 // "file foo" then attached to a PID whose executable was bar.)
414 ModuleSP old_exec_module_sp = target->GetExecutableModule();
415 ArchSpec old_arch_spec = target->GetArchitecture();
417 if (command.GetArgumentCount()) {
418 result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n",
419 m_cmd_name.c_str(), m_cmd_syntax.c_str());
420 result.SetStatus(eReturnStatusFailed);
424 m_interpreter.UpdateExecutionContext(nullptr);
426 const auto error = target->Attach(m_options.attach_info, &stream);
427 if (error.Success()) {
428 ProcessSP process_sp(target->GetProcessSP());
430 result.AppendMessage(stream.GetString());
431 result.SetStatus(eReturnStatusSuccessFinishNoResult);
432 result.SetDidChangeProcessState(true);
435 "no error returned from Target::Attach, and target has no process");
436 result.SetStatus(eReturnStatusFailed);
439 result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
440 result.SetStatus(eReturnStatusFailed);
443 if (!result.Succeeded())
446 // Okay, we're done. Last step is to warn if the executable module has
448 char new_path[PATH_MAX];
449 ModuleSP new_exec_module_sp(target->GetExecutableModule());
450 if (!old_exec_module_sp) {
451 // We might not have a module if we attached to a raw pid...
452 if (new_exec_module_sp) {
453 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
454 result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
457 } else if (old_exec_module_sp->GetFileSpec() !=
458 new_exec_module_sp->GetFileSpec()) {
459 char old_path[PATH_MAX];
461 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
462 new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
464 result.AppendWarningWithFormat(
465 "Executable module changed from \"%s\" to \"%s\".\n", old_path,
469 if (!old_arch_spec.IsValid()) {
470 result.AppendMessageWithFormat(
471 "Architecture set to: %s.\n",
472 target->GetArchitecture().GetTriple().getTriple().c_str());
473 } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
474 result.AppendWarningWithFormat(
475 "Architecture changed from %s to %s.\n",
476 old_arch_spec.GetTriple().getTriple().c_str(),
477 target->GetArchitecture().GetTriple().getTriple().c_str());
480 // This supports the use-case scenario of immediately continuing the
481 // process once attached.
482 if (m_options.attach_info.GetContinueOnceAttached())
483 m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
485 return result.Succeeded();
488 CommandOptions m_options;
491 // CommandObjectProcessContinue
493 #define LLDB_OPTIONS_process_continue
494 #include "CommandOptions.inc"
496 #pragma mark CommandObjectProcessContinue
498 class CommandObjectProcessContinue : public CommandObjectParsed {
500 CommandObjectProcessContinue(CommandInterpreter &interpreter)
501 : CommandObjectParsed(
502 interpreter, "process continue",
503 "Continue execution of all threads in the current process.",
505 eCommandRequiresProcess | eCommandTryTargetAPILock |
506 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
509 ~CommandObjectProcessContinue() override = default;
512 class CommandOptions : public Options {
514 CommandOptions() : Options() {
515 // Keep default values of all options in one place: OptionParsingStarting
517 OptionParsingStarting(nullptr);
520 ~CommandOptions() override = default;
522 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
523 ExecutionContext *execution_context) override {
525 const int short_option = m_getopt_table[option_idx].val;
526 switch (short_option) {
528 if (option_arg.getAsInteger(0, m_ignore))
529 error.SetErrorStringWithFormat(
530 "invalid value for ignore option: \"%s\", should be a number.",
531 option_arg.str().c_str());
535 llvm_unreachable("Unimplemented option");
540 void OptionParsingStarting(ExecutionContext *execution_context) override {
544 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
545 return llvm::makeArrayRef(g_process_continue_options);
551 bool DoExecute(Args &command, CommandReturnObject &result) override {
552 Process *process = m_exe_ctx.GetProcessPtr();
553 bool synchronous_execution = m_interpreter.GetSynchronous();
554 StateType state = process->GetState();
555 if (state == eStateStopped) {
556 if (command.GetArgumentCount() != 0) {
557 result.AppendErrorWithFormat(
558 "The '%s' command does not take any arguments.\n",
560 result.SetStatus(eReturnStatusFailed);
564 if (m_options.m_ignore > 0) {
565 ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
567 StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
569 stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
570 lldb::break_id_t bp_site_id =
571 (lldb::break_id_t)stop_info_sp->GetValue();
572 BreakpointSiteSP bp_site_sp(
573 process->GetBreakpointSiteList().FindByID(bp_site_id));
575 const size_t num_owners = bp_site_sp->GetNumberOfOwners();
576 for (size_t i = 0; i < num_owners; i++) {
578 bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
579 if (!bp_ref.IsInternal()) {
580 bp_ref.SetIgnoreCount(m_options.m_ignore);
588 { // Scope for thread list mutex:
589 std::lock_guard<std::recursive_mutex> guard(
590 process->GetThreadList().GetMutex());
591 const uint32_t num_threads = process->GetThreadList().GetSize();
593 // Set the actions that the threads should each take when resuming
594 for (uint32_t idx = 0; idx < num_threads; ++idx) {
595 const bool override_suspend = false;
596 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
597 eStateRunning, override_suspend);
601 const uint32_t iohandler_id = process->GetIOHandlerID();
605 if (synchronous_execution)
606 error = process->ResumeSynchronous(&stream);
608 error = process->Resume();
610 if (error.Success()) {
611 // There is a race condition where this thread will return up the call
612 // stack to the main command handler and show an (lldb) prompt before
613 // HandlePrivateEvent (from PrivateStateThread) has a chance to call
614 // PushProcessIOHandler().
615 process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
617 result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
619 if (synchronous_execution) {
620 // If any state changed events had anything to say, add that to the
622 result.AppendMessage(stream.GetString());
624 result.SetDidChangeProcessState(true);
625 result.SetStatus(eReturnStatusSuccessFinishNoResult);
627 result.SetStatus(eReturnStatusSuccessContinuingNoResult);
630 result.AppendErrorWithFormat("Failed to resume process: %s.\n",
632 result.SetStatus(eReturnStatusFailed);
635 result.AppendErrorWithFormat(
636 "Process cannot be continued from its current state (%s).\n",
637 StateAsCString(state));
638 result.SetStatus(eReturnStatusFailed);
640 return result.Succeeded();
643 Options *GetOptions() override { return &m_options; }
645 CommandOptions m_options;
648 // CommandObjectProcessDetach
649 #define LLDB_OPTIONS_process_detach
650 #include "CommandOptions.inc"
652 #pragma mark CommandObjectProcessDetach
654 class CommandObjectProcessDetach : public CommandObjectParsed {
656 class CommandOptions : public Options {
658 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
660 ~CommandOptions() override = default;
662 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
663 ExecutionContext *execution_context) override {
665 const int short_option = m_getopt_table[option_idx].val;
667 switch (short_option) {
671 tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success);
673 error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
674 option_arg.str().c_str());
677 m_keep_stopped = eLazyBoolYes;
679 m_keep_stopped = eLazyBoolNo;
683 llvm_unreachable("Unimplemented option");
688 void OptionParsingStarting(ExecutionContext *execution_context) override {
689 m_keep_stopped = eLazyBoolCalculate;
692 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
693 return llvm::makeArrayRef(g_process_detach_options);
696 // Instance variables to hold the values for command options.
697 LazyBool m_keep_stopped;
700 CommandObjectProcessDetach(CommandInterpreter &interpreter)
701 : CommandObjectParsed(interpreter, "process detach",
702 "Detach from the current target process.",
704 eCommandRequiresProcess | eCommandTryTargetAPILock |
705 eCommandProcessMustBeLaunched),
708 ~CommandObjectProcessDetach() override = default;
710 Options *GetOptions() override { return &m_options; }
713 bool DoExecute(Args &command, CommandReturnObject &result) override {
714 Process *process = m_exe_ctx.GetProcessPtr();
715 // FIXME: This will be a Command Option:
717 if (m_options.m_keep_stopped == eLazyBoolCalculate) {
718 // Check the process default:
719 keep_stopped = process->GetDetachKeepsStopped();
720 } else if (m_options.m_keep_stopped == eLazyBoolYes)
723 keep_stopped = false;
725 Status error(process->Detach(keep_stopped));
726 if (error.Success()) {
727 result.SetStatus(eReturnStatusSuccessFinishResult);
729 result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
730 result.SetStatus(eReturnStatusFailed);
733 return result.Succeeded();
736 CommandOptions m_options;
739 // CommandObjectProcessConnect
740 #define LLDB_OPTIONS_process_connect
741 #include "CommandOptions.inc"
743 #pragma mark CommandObjectProcessConnect
745 class CommandObjectProcessConnect : public CommandObjectParsed {
747 class CommandOptions : public Options {
749 CommandOptions() : Options() {
750 // Keep default values of all options in one place: OptionParsingStarting
752 OptionParsingStarting(nullptr);
755 ~CommandOptions() override = default;
757 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
758 ExecutionContext *execution_context) override {
760 const int short_option = m_getopt_table[option_idx].val;
762 switch (short_option) {
764 plugin_name.assign(std::string(option_arg));
768 llvm_unreachable("Unimplemented option");
773 void OptionParsingStarting(ExecutionContext *execution_context) override {
777 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
778 return llvm::makeArrayRef(g_process_connect_options);
781 // Instance variables to hold the values for command options.
783 std::string plugin_name;
786 CommandObjectProcessConnect(CommandInterpreter &interpreter)
787 : CommandObjectParsed(interpreter, "process connect",
788 "Connect to a remote debug service.",
789 "process connect <remote-url>", 0),
792 ~CommandObjectProcessConnect() override = default;
794 Options *GetOptions() override { return &m_options; }
797 bool DoExecute(Args &command, CommandReturnObject &result) override {
798 if (command.GetArgumentCount() != 1) {
799 result.AppendErrorWithFormat(
800 "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
801 m_cmd_syntax.c_str());
802 result.SetStatus(eReturnStatusFailed);
806 Process *process = m_exe_ctx.GetProcessPtr();
807 if (process && process->IsAlive()) {
808 result.AppendErrorWithFormat(
810 " is currently being debugged, kill the process before connecting.\n",
812 result.SetStatus(eReturnStatusFailed);
816 const char *plugin_name = nullptr;
817 if (!m_options.plugin_name.empty())
818 plugin_name = m_options.plugin_name.c_str();
821 Debugger &debugger = GetDebugger();
822 PlatformSP platform_sp = m_interpreter.GetPlatform(true);
823 ProcessSP process_sp =
824 debugger.GetAsyncExecution()
825 ? platform_sp->ConnectProcess(
826 command.GetArgumentAtIndex(0), plugin_name, debugger,
827 debugger.GetSelectedTarget().get(), error)
828 : platform_sp->ConnectProcessSynchronous(
829 command.GetArgumentAtIndex(0), plugin_name, debugger,
830 result.GetOutputStream(), debugger.GetSelectedTarget().get(),
832 if (error.Fail() || process_sp == nullptr) {
833 result.AppendError(error.AsCString("Error connecting to the process"));
834 result.SetStatus(eReturnStatusFailed);
840 CommandOptions m_options;
843 // CommandObjectProcessPlugin
844 #pragma mark CommandObjectProcessPlugin
846 class CommandObjectProcessPlugin : public CommandObjectProxy {
848 CommandObjectProcessPlugin(CommandInterpreter &interpreter)
849 : CommandObjectProxy(
850 interpreter, "process plugin",
851 "Send a custom command to the current target process plug-in.",
852 "process plugin <args>", 0) {}
854 ~CommandObjectProcessPlugin() override = default;
856 CommandObject *GetProxyCommandObject() override {
857 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
859 return process->GetPluginCommandObject();
864 // CommandObjectProcessLoad
865 #define LLDB_OPTIONS_process_load
866 #include "CommandOptions.inc"
868 #pragma mark CommandObjectProcessLoad
870 class CommandObjectProcessLoad : public CommandObjectParsed {
872 class CommandOptions : public Options {
874 CommandOptions() : Options() {
875 // Keep default values of all options in one place: OptionParsingStarting
877 OptionParsingStarting(nullptr);
880 ~CommandOptions() override = default;
882 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
883 ExecutionContext *execution_context) override {
885 const int short_option = m_getopt_table[option_idx].val;
886 switch (short_option) {
889 if (!option_arg.empty())
890 install_path.SetFile(option_arg, FileSpec::Style::native);
893 llvm_unreachable("Unimplemented option");
898 void OptionParsingStarting(ExecutionContext *execution_context) override {
900 install_path.Clear();
903 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
904 return llvm::makeArrayRef(g_process_load_options);
907 // Instance variables to hold the values for command options.
909 FileSpec install_path;
912 CommandObjectProcessLoad(CommandInterpreter &interpreter)
913 : CommandObjectParsed(interpreter, "process load",
914 "Load a shared library into the current process.",
915 "process load <filename> [<filename> ...]",
916 eCommandRequiresProcess | eCommandTryTargetAPILock |
917 eCommandProcessMustBeLaunched |
918 eCommandProcessMustBePaused),
921 ~CommandObjectProcessLoad() override = default;
923 Options *GetOptions() override { return &m_options; }
926 bool DoExecute(Args &command, CommandReturnObject &result) override {
927 Process *process = m_exe_ctx.GetProcessPtr();
929 for (auto &entry : command.entries()) {
931 PlatformSP platform = process->GetTarget().GetPlatform();
932 llvm::StringRef image_path = entry.ref();
933 uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
935 if (!m_options.do_install) {
936 FileSpec image_spec(image_path);
937 platform->ResolveRemotePath(image_spec, image_spec);
939 platform->LoadImage(process, FileSpec(), image_spec, error);
940 } else if (m_options.install_path) {
941 FileSpec image_spec(image_path);
942 FileSystem::Instance().Resolve(image_spec);
943 platform->ResolveRemotePath(m_options.install_path,
944 m_options.install_path);
945 image_token = platform->LoadImage(process, image_spec,
946 m_options.install_path, error);
948 FileSpec image_spec(image_path);
949 FileSystem::Instance().Resolve(image_spec);
951 platform->LoadImage(process, image_spec, FileSpec(), error);
954 if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
955 result.AppendMessageWithFormat(
956 "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
958 result.SetStatus(eReturnStatusSuccessFinishResult);
960 result.AppendErrorWithFormat("failed to load '%s': %s",
961 image_path.str().c_str(),
963 result.SetStatus(eReturnStatusFailed);
966 return result.Succeeded();
969 CommandOptions m_options;
972 // CommandObjectProcessUnload
973 #pragma mark CommandObjectProcessUnload
975 class CommandObjectProcessUnload : public CommandObjectParsed {
977 CommandObjectProcessUnload(CommandInterpreter &interpreter)
978 : CommandObjectParsed(
979 interpreter, "process unload",
980 "Unload a shared library from the current process using the index "
981 "returned by a previous call to \"process load\".",
982 "process unload <index>",
983 eCommandRequiresProcess | eCommandTryTargetAPILock |
984 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
986 ~CommandObjectProcessUnload() override = default;
989 bool DoExecute(Args &command, CommandReturnObject &result) override {
990 Process *process = m_exe_ctx.GetProcessPtr();
992 for (auto &entry : command.entries()) {
993 uint32_t image_token;
994 if (entry.ref().getAsInteger(0, image_token)) {
995 result.AppendErrorWithFormat("invalid image index argument '%s'",
996 entry.ref().str().c_str());
997 result.SetStatus(eReturnStatusFailed);
1000 Status error(process->GetTarget().GetPlatform()->UnloadImage(
1001 process, image_token));
1002 if (error.Success()) {
1003 result.AppendMessageWithFormat(
1004 "Unloading shared library with index %u...ok\n", image_token);
1005 result.SetStatus(eReturnStatusSuccessFinishResult);
1007 result.AppendErrorWithFormat("failed to unload image: %s",
1009 result.SetStatus(eReturnStatusFailed);
1014 return result.Succeeded();
1018 // CommandObjectProcessSignal
1019 #pragma mark CommandObjectProcessSignal
1021 class CommandObjectProcessSignal : public CommandObjectParsed {
1023 CommandObjectProcessSignal(CommandInterpreter &interpreter)
1024 : CommandObjectParsed(
1025 interpreter, "process signal",
1026 "Send a UNIX signal to the current target process.", nullptr,
1027 eCommandRequiresProcess | eCommandTryTargetAPILock) {
1028 CommandArgumentEntry arg;
1029 CommandArgumentData signal_arg;
1031 // Define the first (and only) variant of this arg.
1032 signal_arg.arg_type = eArgTypeUnixSignal;
1033 signal_arg.arg_repetition = eArgRepeatPlain;
1035 // There is only one variant this argument could be; put it into the
1037 arg.push_back(signal_arg);
1039 // Push the data for the first argument into the m_arguments vector.
1040 m_arguments.push_back(arg);
1043 ~CommandObjectProcessSignal() override = default;
1046 HandleArgumentCompletion(CompletionRequest &request,
1047 OptionElementVector &opt_element_vector) override {
1048 if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
1051 UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals();
1052 int signo = signals->GetFirstSignalNumber();
1053 while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1054 request.AddCompletion(signals->GetSignalAsCString(signo), "");
1055 signo = signals->GetNextSignalNumber(signo);
1060 bool DoExecute(Args &command, CommandReturnObject &result) override {
1061 Process *process = m_exe_ctx.GetProcessPtr();
1063 if (command.GetArgumentCount() == 1) {
1064 int signo = LLDB_INVALID_SIGNAL_NUMBER;
1066 const char *signal_name = command.GetArgumentAtIndex(0);
1067 if (::isxdigit(signal_name[0])) {
1068 if (!llvm::to_integer(signal_name, signo))
1069 signo = LLDB_INVALID_SIGNAL_NUMBER;
1071 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1073 if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
1074 result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
1075 command.GetArgumentAtIndex(0));
1076 result.SetStatus(eReturnStatusFailed);
1078 Status error(process->Signal(signo));
1079 if (error.Success()) {
1080 result.SetStatus(eReturnStatusSuccessFinishResult);
1082 result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
1084 result.SetStatus(eReturnStatusFailed);
1088 result.AppendErrorWithFormat(
1089 "'%s' takes exactly one signal number argument:\nUsage: %s\n",
1090 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1091 result.SetStatus(eReturnStatusFailed);
1093 return result.Succeeded();
1097 // CommandObjectProcessInterrupt
1098 #pragma mark CommandObjectProcessInterrupt
1100 class CommandObjectProcessInterrupt : public CommandObjectParsed {
1102 CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1103 : CommandObjectParsed(interpreter, "process interrupt",
1104 "Interrupt the current target process.",
1105 "process interrupt",
1106 eCommandRequiresProcess | eCommandTryTargetAPILock |
1107 eCommandProcessMustBeLaunched) {}
1109 ~CommandObjectProcessInterrupt() override = default;
1112 bool DoExecute(Args &command, CommandReturnObject &result) override {
1113 Process *process = m_exe_ctx.GetProcessPtr();
1114 if (process == nullptr) {
1115 result.AppendError("no process to halt");
1116 result.SetStatus(eReturnStatusFailed);
1120 if (command.GetArgumentCount() == 0) {
1121 bool clear_thread_plans = true;
1122 Status error(process->Halt(clear_thread_plans));
1123 if (error.Success()) {
1124 result.SetStatus(eReturnStatusSuccessFinishResult);
1126 result.AppendErrorWithFormat("Failed to halt process: %s\n",
1128 result.SetStatus(eReturnStatusFailed);
1131 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1132 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1133 result.SetStatus(eReturnStatusFailed);
1135 return result.Succeeded();
1139 // CommandObjectProcessKill
1140 #pragma mark CommandObjectProcessKill
1142 class CommandObjectProcessKill : public CommandObjectParsed {
1144 CommandObjectProcessKill(CommandInterpreter &interpreter)
1145 : CommandObjectParsed(interpreter, "process kill",
1146 "Terminate the current target process.",
1148 eCommandRequiresProcess | eCommandTryTargetAPILock |
1149 eCommandProcessMustBeLaunched) {}
1151 ~CommandObjectProcessKill() override = default;
1154 bool DoExecute(Args &command, CommandReturnObject &result) override {
1155 Process *process = m_exe_ctx.GetProcessPtr();
1156 if (process == nullptr) {
1157 result.AppendError("no process to kill");
1158 result.SetStatus(eReturnStatusFailed);
1162 if (command.GetArgumentCount() == 0) {
1163 Status error(process->Destroy(true));
1164 if (error.Success()) {
1165 result.SetStatus(eReturnStatusSuccessFinishResult);
1167 result.AppendErrorWithFormat("Failed to kill process: %s\n",
1169 result.SetStatus(eReturnStatusFailed);
1172 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1173 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1174 result.SetStatus(eReturnStatusFailed);
1176 return result.Succeeded();
1180 // CommandObjectProcessSaveCore
1181 #pragma mark CommandObjectProcessSaveCore
1183 class CommandObjectProcessSaveCore : public CommandObjectParsed {
1185 CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1186 : CommandObjectParsed(interpreter, "process save-core",
1187 "Save the current process as a core file using an "
1188 "appropriate file type.",
1189 "process save-core FILE",
1190 eCommandRequiresProcess | eCommandTryTargetAPILock |
1191 eCommandProcessMustBeLaunched) {}
1193 ~CommandObjectProcessSaveCore() override = default;
1196 bool DoExecute(Args &command, CommandReturnObject &result) override {
1197 ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1199 if (command.GetArgumentCount() == 1) {
1200 FileSpec output_file(command.GetArgumentAtIndex(0));
1201 Status error = PluginManager::SaveCore(process_sp, output_file);
1202 if (error.Success()) {
1203 result.SetStatus(eReturnStatusSuccessFinishResult);
1205 result.AppendErrorWithFormat(
1206 "Failed to save core file for process: %s\n", error.AsCString());
1207 result.SetStatus(eReturnStatusFailed);
1210 result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1211 m_cmd_name.c_str(), m_cmd_syntax.c_str());
1212 result.SetStatus(eReturnStatusFailed);
1215 result.AppendError("invalid process");
1216 result.SetStatus(eReturnStatusFailed);
1220 return result.Succeeded();
1224 // CommandObjectProcessStatus
1225 #pragma mark CommandObjectProcessStatus
1226 #define LLDB_OPTIONS_process_status
1227 #include "CommandOptions.inc"
1229 class CommandObjectProcessStatus : public CommandObjectParsed {
1231 CommandObjectProcessStatus(CommandInterpreter &interpreter)
1232 : CommandObjectParsed(
1233 interpreter, "process status",
1234 "Show status and stop location for the current target process.",
1236 eCommandRequiresProcess | eCommandTryTargetAPILock),
1239 ~CommandObjectProcessStatus() override = default;
1241 Options *GetOptions() override { return &m_options; }
1243 class CommandOptions : public Options {
1245 CommandOptions() : Options(), m_verbose(false) {}
1247 ~CommandOptions() override = default;
1249 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1250 ExecutionContext *execution_context) override {
1251 const int short_option = m_getopt_table[option_idx].val;
1253 switch (short_option) {
1258 llvm_unreachable("Unimplemented option");
1264 void OptionParsingStarting(ExecutionContext *execution_context) override {
1268 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1269 return llvm::makeArrayRef(g_process_status_options);
1272 // Instance variables to hold the values for command options.
1277 bool DoExecute(Args &command, CommandReturnObject &result) override {
1278 Stream &strm = result.GetOutputStream();
1279 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1281 if (command.GetArgumentCount()) {
1282 result.AppendError("'process status' takes no arguments");
1283 result.SetStatus(eReturnStatusFailed);
1284 return result.Succeeded();
1287 // No need to check "process" for validity as eCommandRequiresProcess
1288 // ensures it is valid
1289 Process *process = m_exe_ctx.GetProcessPtr();
1290 const bool only_threads_with_stop_reason = true;
1291 const uint32_t start_frame = 0;
1292 const uint32_t num_frames = 1;
1293 const uint32_t num_frames_with_source = 1;
1294 const bool stop_format = true;
1295 process->GetStatus(strm);
1296 process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1297 num_frames, num_frames_with_source, stop_format);
1299 if (m_options.m_verbose) {
1300 PlatformSP platform_sp = process->GetTarget().GetPlatform();
1302 result.AppendError("Couldn'retrieve the target's platform");
1303 result.SetStatus(eReturnStatusFailed);
1304 return result.Succeeded();
1307 auto expected_crash_info =
1308 platform_sp->FetchExtendedCrashInformation(*process);
1310 if (!expected_crash_info) {
1311 result.AppendError(llvm::toString(expected_crash_info.takeError()));
1312 result.SetStatus(eReturnStatusFailed);
1313 return result.Succeeded();
1316 StructuredData::DictionarySP crash_info_sp = *expected_crash_info;
1318 if (crash_info_sp) {
1319 strm.PutCString("Extended Crash Information:\n");
1320 crash_info_sp->Dump(strm);
1324 return result.Succeeded();
1328 CommandOptions m_options;
1331 // CommandObjectProcessHandle
1332 #define LLDB_OPTIONS_process_handle
1333 #include "CommandOptions.inc"
1335 #pragma mark CommandObjectProcessHandle
1337 class CommandObjectProcessHandle : public CommandObjectParsed {
1339 class CommandOptions : public Options {
1341 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1343 ~CommandOptions() override = default;
1345 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1346 ExecutionContext *execution_context) override {
1348 const int short_option = m_getopt_table[option_idx].val;
1350 switch (short_option) {
1352 stop = std::string(option_arg);
1355 notify = std::string(option_arg);
1358 pass = std::string(option_arg);
1361 llvm_unreachable("Unimplemented option");
1366 void OptionParsingStarting(ExecutionContext *execution_context) override {
1372 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1373 return llvm::makeArrayRef(g_process_handle_options);
1376 // Instance variables to hold the values for command options.
1383 CommandObjectProcessHandle(CommandInterpreter &interpreter)
1384 : CommandObjectParsed(interpreter, "process handle",
1385 "Manage LLDB handling of OS signals for the "
1386 "current target process. Defaults to showing "
1388 nullptr, eCommandRequiresTarget),
1390 SetHelpLong("\nIf no signals are specified, update them all. If no update "
1391 "option is specified, list the current values.");
1392 CommandArgumentEntry arg;
1393 CommandArgumentData signal_arg;
1395 signal_arg.arg_type = eArgTypeUnixSignal;
1396 signal_arg.arg_repetition = eArgRepeatStar;
1398 arg.push_back(signal_arg);
1400 m_arguments.push_back(arg);
1403 ~CommandObjectProcessHandle() override = default;
1405 Options *GetOptions() override { return &m_options; }
1407 bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
1409 bool success = false;
1410 bool tmp_value = OptionArgParser::ToBoolean(option, false, &success);
1412 if (success && tmp_value)
1414 else if (success && !tmp_value)
1417 // If the value isn't 'true' or 'false', it had better be 0 or 1.
1418 if (!llvm::to_integer(option, real_value))
1420 if (real_value != 0 && real_value != 1)
1427 void PrintSignalHeader(Stream &str) {
1428 str.Printf("NAME PASS STOP NOTIFY\n");
1429 str.Printf("=========== ===== ===== ======\n");
1432 void PrintSignal(Stream &str, int32_t signo, const char *sig_name,
1433 const UnixSignalsSP &signals_sp) {
1438 str.Printf("%-11s ", sig_name);
1439 if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
1440 bool pass = !suppress;
1441 str.Printf("%s %s %s", (pass ? "true " : "false"),
1442 (stop ? "true " : "false"), (notify ? "true " : "false"));
1447 void PrintSignalInformation(Stream &str, Args &signal_args,
1448 int num_valid_signals,
1449 const UnixSignalsSP &signals_sp) {
1450 PrintSignalHeader(str);
1452 if (num_valid_signals > 0) {
1453 size_t num_args = signal_args.GetArgumentCount();
1454 for (size_t i = 0; i < num_args; ++i) {
1455 int32_t signo = signals_sp->GetSignalNumberFromName(
1456 signal_args.GetArgumentAtIndex(i));
1457 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1458 PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1461 } else // Print info for ALL signals
1463 int32_t signo = signals_sp->GetFirstSignalNumber();
1464 while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1465 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo),
1467 signo = signals_sp->GetNextSignalNumber(signo);
1473 bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
1474 Target *target_sp = &GetSelectedTarget();
1476 ProcessSP process_sp = target_sp->GetProcessSP();
1479 result.AppendError("No current process; cannot handle signals until you "
1480 "have a valid process.\n");
1481 result.SetStatus(eReturnStatusFailed);
1485 int stop_action = -1; // -1 means leave the current setting alone
1486 int pass_action = -1; // -1 means leave the current setting alone
1487 int notify_action = -1; // -1 means leave the current setting alone
1489 if (!m_options.stop.empty() &&
1490 !VerifyCommandOptionValue(m_options.stop, stop_action)) {
1491 result.AppendError("Invalid argument for command option --stop; must be "
1492 "true or false.\n");
1493 result.SetStatus(eReturnStatusFailed);
1497 if (!m_options.notify.empty() &&
1498 !VerifyCommandOptionValue(m_options.notify, notify_action)) {
1499 result.AppendError("Invalid argument for command option --notify; must "
1500 "be true or false.\n");
1501 result.SetStatus(eReturnStatusFailed);
1505 if (!m_options.pass.empty() &&
1506 !VerifyCommandOptionValue(m_options.pass, pass_action)) {
1507 result.AppendError("Invalid argument for command option --pass; must be "
1508 "true or false.\n");
1509 result.SetStatus(eReturnStatusFailed);
1513 size_t num_args = signal_args.GetArgumentCount();
1514 UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
1515 int num_signals_set = 0;
1518 for (const auto &arg : signal_args) {
1519 int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1520 if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1521 // Casting the actions as bools here should be okay, because
1522 // VerifyCommandOptionValue guarantees the value is either 0 or 1.
1523 if (stop_action != -1)
1524 signals_sp->SetShouldStop(signo, stop_action);
1525 if (pass_action != -1) {
1526 bool suppress = !pass_action;
1527 signals_sp->SetShouldSuppress(signo, suppress);
1529 if (notify_action != -1)
1530 signals_sp->SetShouldNotify(signo, notify_action);
1533 result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1538 // No signal specified, if any command options were specified, update ALL
1540 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) {
1541 if (m_interpreter.Confirm(
1542 "Do you really want to update all the signals?", false)) {
1543 int32_t signo = signals_sp->GetFirstSignalNumber();
1544 while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1545 if (notify_action != -1)
1546 signals_sp->SetShouldNotify(signo, notify_action);
1547 if (stop_action != -1)
1548 signals_sp->SetShouldStop(signo, stop_action);
1549 if (pass_action != -1) {
1550 bool suppress = !pass_action;
1551 signals_sp->SetShouldSuppress(signo, suppress);
1553 signo = signals_sp->GetNextSignalNumber(signo);
1559 PrintSignalInformation(result.GetOutputStream(), signal_args,
1560 num_signals_set, signals_sp);
1562 if (num_signals_set > 0)
1563 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1565 result.SetStatus(eReturnStatusFailed);
1567 return result.Succeeded();
1570 CommandOptions m_options;
1573 // CommandObjectMultiwordProcess
1575 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1576 CommandInterpreter &interpreter)
1577 : CommandObjectMultiword(
1578 interpreter, "process",
1579 "Commands for interacting with processes on the current platform.",
1580 "process <subcommand> [<subcommand-options>]") {
1581 LoadSubCommand("attach",
1582 CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1583 LoadSubCommand("launch",
1584 CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1585 LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1587 LoadSubCommand("connect",
1588 CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1589 LoadSubCommand("detach",
1590 CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1591 LoadSubCommand("load",
1592 CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1593 LoadSubCommand("unload",
1594 CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1595 LoadSubCommand("signal",
1596 CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1597 LoadSubCommand("handle",
1598 CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1599 LoadSubCommand("status",
1600 CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1601 LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1603 LoadSubCommand("kill",
1604 CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1605 LoadSubCommand("plugin",
1606 CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1607 LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1611 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;