xref: /llvm-project/lldb/source/Commands/CommandObjectProcess.cpp (revision 2634ec6ce9007f2406545ca28b4c72961f1e8f67)
1 //===-- CommandObjectProcess.cpp ------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
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"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
33 public:
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) {}
40 
41   ~CommandObjectProcessLaunchOrAttach() override = default;
42 
43 protected:
44   bool StopProcessIfNecessary(Process *process, StateType &state,
45                               CommandReturnObject &result) {
46     state = eStateInvalid;
47     if (process) {
48       state = process->GetState();
49 
50       if (process->IsAlive() && state != eStateConnected) {
51         std::string message;
52         if (process->GetState() == eStateAttaching)
53           message =
54               llvm::formatv("There is a pending attach, abort it and {0}?",
55                             m_new_process_action);
56         else if (process->GetShouldDetach())
57           message = llvm::formatv(
58               "There is a running process, detach from it and {0}?",
59               m_new_process_action);
60         else
61           message =
62               llvm::formatv("There is a running process, kill it and {0}?",
63                             m_new_process_action);
64 
65         if (!m_interpreter.Confirm(message, true)) {
66           result.SetStatus(eReturnStatusFailed);
67           return false;
68         } else {
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);
74               process = nullptr;
75             } else {
76               result.AppendErrorWithFormat(
77                   "Failed to detach from process: %s\n",
78                   detach_error.AsCString());
79               result.SetStatus(eReturnStatusFailed);
80             }
81           } else {
82             Status destroy_error(process->Destroy(false));
83             if (destroy_error.Success()) {
84               result.SetStatus(eReturnStatusSuccessFinishResult);
85               process = nullptr;
86             } else {
87               result.AppendErrorWithFormat("Failed to kill process: %s\n",
88                                            destroy_error.AsCString());
89               result.SetStatus(eReturnStatusFailed);
90             }
91           }
92         }
93       }
94     }
95     return result.Succeeded();
96   }
97 
98   std::string m_new_process_action;
99 };
100 
101 // CommandObjectProcessLaunch
102 #pragma mark CommandObjectProcessLaunch
103 class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
104 public:
105   CommandObjectProcessLaunch(CommandInterpreter &interpreter)
106       : CommandObjectProcessLaunchOrAttach(
107             interpreter, "process launch",
108             "Launch the executable in the debugger.", nullptr,
109             eCommandRequiresTarget, "restart"),
110         m_options() {
111     CommandArgumentEntry arg;
112     CommandArgumentData run_args_arg;
113 
114     // Define the first (and only) variant of this arg.
115     run_args_arg.arg_type = eArgTypeRunArgs;
116     run_args_arg.arg_repetition = eArgRepeatOptional;
117 
118     // There is only one variant this argument could be; put it into the
119     // argument entry.
120     arg.push_back(run_args_arg);
121 
122     // Push the data for the first argument into the m_arguments vector.
123     m_arguments.push_back(arg);
124   }
125 
126   ~CommandObjectProcessLaunch() override = default;
127 
128   void
129   HandleArgumentCompletion(CompletionRequest &request,
130                            OptionElementVector &opt_element_vector) override {
131 
132     CommandCompletions::InvokeCommonCompletionCallbacks(
133         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
134         request, nullptr);
135   }
136 
137   Options *GetOptions() override { return &m_options; }
138 
139   const char *GetRepeatCommand(Args &current_command_args,
140                                uint32_t index) override {
141     // No repeat for "process launch"...
142     return "";
143   }
144 
145 protected:
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();
151 
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);
156       return false;
157     }
158 
159     StateType state = eStateInvalid;
160 
161     if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
162       return false;
163 
164     llvm::StringRef target_settings_argv0 = target->GetArg0();
165 
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.
174       // Use it.
175       disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
176     } else {
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();
180     }
181 
182     if (disable_aslr)
183       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
184     else
185       m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
186 
187     if (target->GetInheritTCC())
188       m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
189 
190     if (target->GetDetachOnError())
191       m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
192 
193     if (target->GetDisableSTDIO())
194       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
195 
196     // Merge the launch info environment with the target environment.
197     Environment target_env = target->GetEnvironment();
198     m_options.launch_info.GetEnvironment().insert(target_env.begin(),
199                                                   target_env.end());
200 
201     if (!target_settings_argv0.empty()) {
202       m_options.launch_info.GetArguments().AppendArgument(
203           target_settings_argv0);
204       m_options.launch_info.SetExecutableFile(
205           exe_module_sp->GetPlatformFileSpec(), false);
206     } else {
207       m_options.launch_info.SetExecutableFile(
208           exe_module_sp->GetPlatformFileSpec(), true);
209     }
210 
211     if (launch_args.GetArgumentCount() == 0) {
212       m_options.launch_info.GetArguments().AppendArguments(
213           target->GetProcessLaunchInfo().GetArguments());
214     } else {
215       m_options.launch_info.GetArguments().AppendArguments(launch_args);
216       // Save the arguments for subsequent runs in the current target.
217       target->SetRunArguments(launch_args);
218     }
219 
220     StreamString stream;
221     Status error = target->Launch(m_options.launch_info, &stream);
222 
223     if (error.Success()) {
224       ProcessSP process_sp(target->GetProcessSP());
225       if (process_sp) {
226         // There is a race condition where this thread will return up the call
227         // stack to the main command handler and show an (lldb) prompt before
228         // HandlePrivateEvent (from PrivateStateThread) has a chance to call
229         // PushProcessIOHandler().
230         process_sp->SyncIOHandler(0, std::chrono::seconds(2));
231 
232         llvm::StringRef data = stream.GetString();
233         if (!data.empty())
234           result.AppendMessage(data);
235         const char *archname =
236             exe_module_sp->GetArchitecture().GetArchitectureName();
237         result.AppendMessageWithFormat(
238             "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
239             exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
240         result.SetStatus(eReturnStatusSuccessFinishResult);
241         result.SetDidChangeProcessState(true);
242       } else {
243         result.AppendError(
244             "no error returned from Target::Launch, and target has no process");
245         result.SetStatus(eReturnStatusFailed);
246       }
247     } else {
248       result.AppendError(error.AsCString());
249       result.SetStatus(eReturnStatusFailed);
250     }
251     return result.Succeeded();
252   }
253 
254   ProcessLaunchCommandOptions m_options;
255 };
256 
257 #define LLDB_OPTIONS_process_attach
258 #include "CommandOptions.inc"
259 
260 #pragma mark CommandObjectProcessAttach
261 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
262 public:
263   class CommandOptions : public Options {
264   public:
265     CommandOptions() : Options() {
266       // Keep default values of all options in one place: OptionParsingStarting
267       // ()
268       OptionParsingStarting(nullptr);
269     }
270 
271     ~CommandOptions() override = default;
272 
273     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
274                           ExecutionContext *execution_context) override {
275       Status error;
276       const int short_option = m_getopt_table[option_idx].val;
277       switch (short_option) {
278       case 'c':
279         attach_info.SetContinueOnceAttached(true);
280         break;
281 
282       case 'p': {
283         lldb::pid_t pid;
284         if (option_arg.getAsInteger(0, pid)) {
285           error.SetErrorStringWithFormat("invalid process ID '%s'",
286                                          option_arg.str().c_str());
287         } else {
288           attach_info.SetProcessID(pid);
289         }
290       } break;
291 
292       case 'P':
293         attach_info.SetProcessPluginName(option_arg);
294         break;
295 
296       case 'n':
297         attach_info.GetExecutableFile().SetFile(option_arg,
298                                                 FileSpec::Style::native);
299         break;
300 
301       case 'w':
302         attach_info.SetWaitForLaunch(true);
303         break;
304 
305       case 'i':
306         attach_info.SetIgnoreExisting(false);
307         break;
308 
309       default:
310         llvm_unreachable("Unimplemented option");
311       }
312       return error;
313     }
314 
315     void OptionParsingStarting(ExecutionContext *execution_context) override {
316       attach_info.Clear();
317     }
318 
319     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
320       return llvm::makeArrayRef(g_process_attach_options);
321     }
322 
323     ProcessAttachInfo attach_info;
324   };
325 
326   CommandObjectProcessAttach(CommandInterpreter &interpreter)
327       : CommandObjectProcessLaunchOrAttach(
328             interpreter, "process attach", "Attach to a process.",
329             "process attach <cmd-options>", 0, "attach"),
330         m_options() {}
331 
332   ~CommandObjectProcessAttach() override = default;
333 
334   Options *GetOptions() override { return &m_options; }
335 
336 protected:
337   bool DoExecute(Args &command, CommandReturnObject &result) override {
338     PlatformSP platform_sp(
339         GetDebugger().GetPlatformList().GetSelectedPlatform());
340 
341     Target *target = GetDebugger().GetSelectedTarget().get();
342     // N.B. The attach should be synchronous.  It doesn't help much to get the
343     // prompt back between initiating the attach and the target actually
344     // stopping.  So even if the interpreter is set to be asynchronous, we wait
345     // for the stop ourselves here.
346 
347     StateType state = eStateInvalid;
348     Process *process = m_exe_ctx.GetProcessPtr();
349 
350     if (!StopProcessIfNecessary(process, state, result))
351       return false;
352 
353     if (target == nullptr) {
354       // If there isn't a current target create one.
355       TargetSP new_target_sp;
356       Status error;
357 
358       error = GetDebugger().GetTargetList().CreateTarget(
359           GetDebugger(), "", "", eLoadDependentsNo,
360           nullptr, // No platform options
361           new_target_sp);
362       target = new_target_sp.get();
363       if (target == nullptr || error.Fail()) {
364         result.AppendError(error.AsCString("Error creating target"));
365         return false;
366       }
367     }
368 
369     // Record the old executable module, we want to issue a warning if the
370     // process of attaching changed the current executable (like somebody said
371     // "file foo" then attached to a PID whose executable was bar.)
372 
373     ModuleSP old_exec_module_sp = target->GetExecutableModule();
374     ArchSpec old_arch_spec = target->GetArchitecture();
375 
376     if (command.GetArgumentCount()) {
377       result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n",
378                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
379       result.SetStatus(eReturnStatusFailed);
380       return false;
381     }
382 
383     m_interpreter.UpdateExecutionContext(nullptr);
384     StreamString stream;
385     const auto error = target->Attach(m_options.attach_info, &stream);
386     if (error.Success()) {
387       ProcessSP process_sp(target->GetProcessSP());
388       if (process_sp) {
389         result.AppendMessage(stream.GetString());
390         result.SetStatus(eReturnStatusSuccessFinishNoResult);
391         result.SetDidChangeProcessState(true);
392       } else {
393         result.AppendError(
394             "no error returned from Target::Attach, and target has no process");
395         result.SetStatus(eReturnStatusFailed);
396       }
397     } else {
398       result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
399       result.SetStatus(eReturnStatusFailed);
400     }
401 
402     if (!result.Succeeded())
403       return false;
404 
405     // Okay, we're done.  Last step is to warn if the executable module has
406     // changed:
407     char new_path[PATH_MAX];
408     ModuleSP new_exec_module_sp(target->GetExecutableModule());
409     if (!old_exec_module_sp) {
410       // We might not have a module if we attached to a raw pid...
411       if (new_exec_module_sp) {
412         new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
413         result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
414                                        new_path);
415       }
416     } else if (old_exec_module_sp->GetFileSpec() !=
417                new_exec_module_sp->GetFileSpec()) {
418       char old_path[PATH_MAX];
419 
420       old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
421       new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
422 
423       result.AppendWarningWithFormat(
424           "Executable module changed from \"%s\" to \"%s\".\n", old_path,
425           new_path);
426     }
427 
428     if (!old_arch_spec.IsValid()) {
429       result.AppendMessageWithFormat(
430           "Architecture set to: %s.\n",
431           target->GetArchitecture().GetTriple().getTriple().c_str());
432     } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
433       result.AppendWarningWithFormat(
434           "Architecture changed from %s to %s.\n",
435           old_arch_spec.GetTriple().getTriple().c_str(),
436           target->GetArchitecture().GetTriple().getTriple().c_str());
437     }
438 
439     // This supports the use-case scenario of immediately continuing the
440     // process once attached.
441     if (m_options.attach_info.GetContinueOnceAttached())
442       m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
443 
444     return result.Succeeded();
445   }
446 
447   CommandOptions m_options;
448 };
449 
450 // CommandObjectProcessContinue
451 
452 #define LLDB_OPTIONS_process_continue
453 #include "CommandOptions.inc"
454 
455 #pragma mark CommandObjectProcessContinue
456 
457 class CommandObjectProcessContinue : public CommandObjectParsed {
458 public:
459   CommandObjectProcessContinue(CommandInterpreter &interpreter)
460       : CommandObjectParsed(
461             interpreter, "process continue",
462             "Continue execution of all threads in the current process.",
463             "process continue",
464             eCommandRequiresProcess | eCommandTryTargetAPILock |
465                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
466         m_options() {}
467 
468   ~CommandObjectProcessContinue() override = default;
469 
470 protected:
471   class CommandOptions : public Options {
472   public:
473     CommandOptions() : Options() {
474       // Keep default values of all options in one place: OptionParsingStarting
475       // ()
476       OptionParsingStarting(nullptr);
477     }
478 
479     ~CommandOptions() override = default;
480 
481     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
482                           ExecutionContext *execution_context) override {
483       Status error;
484       const int short_option = m_getopt_table[option_idx].val;
485       switch (short_option) {
486       case 'i':
487         if (option_arg.getAsInteger(0, m_ignore))
488           error.SetErrorStringWithFormat(
489               "invalid value for ignore option: \"%s\", should be a number.",
490               option_arg.str().c_str());
491         break;
492 
493       default:
494         llvm_unreachable("Unimplemented option");
495       }
496       return error;
497     }
498 
499     void OptionParsingStarting(ExecutionContext *execution_context) override {
500       m_ignore = 0;
501     }
502 
503     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
504       return llvm::makeArrayRef(g_process_continue_options);
505     }
506 
507     uint32_t m_ignore;
508   };
509 
510   bool DoExecute(Args &command, CommandReturnObject &result) override {
511     Process *process = m_exe_ctx.GetProcessPtr();
512     bool synchronous_execution = m_interpreter.GetSynchronous();
513     StateType state = process->GetState();
514     if (state == eStateStopped) {
515       if (command.GetArgumentCount() != 0) {
516         result.AppendErrorWithFormat(
517             "The '%s' command does not take any arguments.\n",
518             m_cmd_name.c_str());
519         result.SetStatus(eReturnStatusFailed);
520         return false;
521       }
522 
523       if (m_options.m_ignore > 0) {
524         ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
525         if (sel_thread_sp) {
526           StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
527           if (stop_info_sp &&
528               stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
529             lldb::break_id_t bp_site_id =
530                 (lldb::break_id_t)stop_info_sp->GetValue();
531             BreakpointSiteSP bp_site_sp(
532                 process->GetBreakpointSiteList().FindByID(bp_site_id));
533             if (bp_site_sp) {
534               const size_t num_owners = bp_site_sp->GetNumberOfOwners();
535               for (size_t i = 0; i < num_owners; i++) {
536                 Breakpoint &bp_ref =
537                     bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
538                 if (!bp_ref.IsInternal()) {
539                   bp_ref.SetIgnoreCount(m_options.m_ignore);
540                 }
541               }
542             }
543           }
544         }
545       }
546 
547       { // Scope for thread list mutex:
548         std::lock_guard<std::recursive_mutex> guard(
549             process->GetThreadList().GetMutex());
550         const uint32_t num_threads = process->GetThreadList().GetSize();
551 
552         // Set the actions that the threads should each take when resuming
553         for (uint32_t idx = 0; idx < num_threads; ++idx) {
554           const bool override_suspend = false;
555           process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
556               eStateRunning, override_suspend);
557         }
558       }
559 
560       const uint32_t iohandler_id = process->GetIOHandlerID();
561 
562       StreamString stream;
563       Status error;
564       if (synchronous_execution)
565         error = process->ResumeSynchronous(&stream);
566       else
567         error = process->Resume();
568 
569       if (error.Success()) {
570         // There is a race condition where this thread will return up the call
571         // stack to the main command handler and show an (lldb) prompt before
572         // HandlePrivateEvent (from PrivateStateThread) has a chance to call
573         // PushProcessIOHandler().
574         process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
575 
576         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
577                                        process->GetID());
578         if (synchronous_execution) {
579           // If any state changed events had anything to say, add that to the
580           // result
581           result.AppendMessage(stream.GetString());
582 
583           result.SetDidChangeProcessState(true);
584           result.SetStatus(eReturnStatusSuccessFinishNoResult);
585         } else {
586           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
587         }
588       } else {
589         result.AppendErrorWithFormat("Failed to resume process: %s.\n",
590                                      error.AsCString());
591         result.SetStatus(eReturnStatusFailed);
592       }
593     } else {
594       result.AppendErrorWithFormat(
595           "Process cannot be continued from its current state (%s).\n",
596           StateAsCString(state));
597       result.SetStatus(eReturnStatusFailed);
598     }
599     return result.Succeeded();
600   }
601 
602   Options *GetOptions() override { return &m_options; }
603 
604   CommandOptions m_options;
605 };
606 
607 // CommandObjectProcessDetach
608 #define LLDB_OPTIONS_process_detach
609 #include "CommandOptions.inc"
610 
611 #pragma mark CommandObjectProcessDetach
612 
613 class CommandObjectProcessDetach : public CommandObjectParsed {
614 public:
615   class CommandOptions : public Options {
616   public:
617     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
618 
619     ~CommandOptions() override = default;
620 
621     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
622                           ExecutionContext *execution_context) override {
623       Status error;
624       const int short_option = m_getopt_table[option_idx].val;
625 
626       switch (short_option) {
627       case 's':
628         bool tmp_result;
629         bool success;
630         tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success);
631         if (!success)
632           error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
633                                          option_arg.str().c_str());
634         else {
635           if (tmp_result)
636             m_keep_stopped = eLazyBoolYes;
637           else
638             m_keep_stopped = eLazyBoolNo;
639         }
640         break;
641       default:
642         llvm_unreachable("Unimplemented option");
643       }
644       return error;
645     }
646 
647     void OptionParsingStarting(ExecutionContext *execution_context) override {
648       m_keep_stopped = eLazyBoolCalculate;
649     }
650 
651     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
652       return llvm::makeArrayRef(g_process_detach_options);
653     }
654 
655     // Instance variables to hold the values for command options.
656     LazyBool m_keep_stopped;
657   };
658 
659   CommandObjectProcessDetach(CommandInterpreter &interpreter)
660       : CommandObjectParsed(interpreter, "process detach",
661                             "Detach from the current target process.",
662                             "process detach",
663                             eCommandRequiresProcess | eCommandTryTargetAPILock |
664                                 eCommandProcessMustBeLaunched),
665         m_options() {}
666 
667   ~CommandObjectProcessDetach() override = default;
668 
669   Options *GetOptions() override { return &m_options; }
670 
671 protected:
672   bool DoExecute(Args &command, CommandReturnObject &result) override {
673     Process *process = m_exe_ctx.GetProcessPtr();
674     // FIXME: This will be a Command Option:
675     bool keep_stopped;
676     if (m_options.m_keep_stopped == eLazyBoolCalculate) {
677       // Check the process default:
678       keep_stopped = process->GetDetachKeepsStopped();
679     } else if (m_options.m_keep_stopped == eLazyBoolYes)
680       keep_stopped = true;
681     else
682       keep_stopped = false;
683 
684     Status error(process->Detach(keep_stopped));
685     if (error.Success()) {
686       result.SetStatus(eReturnStatusSuccessFinishResult);
687     } else {
688       result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
689       result.SetStatus(eReturnStatusFailed);
690       return false;
691     }
692     return result.Succeeded();
693   }
694 
695   CommandOptions m_options;
696 };
697 
698 // CommandObjectProcessConnect
699 #define LLDB_OPTIONS_process_connect
700 #include "CommandOptions.inc"
701 
702 #pragma mark CommandObjectProcessConnect
703 
704 class CommandObjectProcessConnect : public CommandObjectParsed {
705 public:
706   class CommandOptions : public Options {
707   public:
708     CommandOptions() : Options() {
709       // Keep default values of all options in one place: OptionParsingStarting
710       // ()
711       OptionParsingStarting(nullptr);
712     }
713 
714     ~CommandOptions() override = default;
715 
716     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
717                           ExecutionContext *execution_context) override {
718       Status error;
719       const int short_option = m_getopt_table[option_idx].val;
720 
721       switch (short_option) {
722       case 'p':
723         plugin_name.assign(std::string(option_arg));
724         break;
725 
726       default:
727         llvm_unreachable("Unimplemented option");
728       }
729       return error;
730     }
731 
732     void OptionParsingStarting(ExecutionContext *execution_context) override {
733       plugin_name.clear();
734     }
735 
736     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
737       return llvm::makeArrayRef(g_process_connect_options);
738     }
739 
740     // Instance variables to hold the values for command options.
741 
742     std::string plugin_name;
743   };
744 
745   CommandObjectProcessConnect(CommandInterpreter &interpreter)
746       : CommandObjectParsed(interpreter, "process connect",
747                             "Connect to a remote debug service.",
748                             "process connect <remote-url>", 0),
749         m_options() {}
750 
751   ~CommandObjectProcessConnect() override = default;
752 
753   Options *GetOptions() override { return &m_options; }
754 
755 protected:
756   bool DoExecute(Args &command, CommandReturnObject &result) override {
757     if (command.GetArgumentCount() != 1) {
758       result.AppendErrorWithFormat(
759           "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
760           m_cmd_syntax.c_str());
761       result.SetStatus(eReturnStatusFailed);
762       return false;
763     }
764 
765     Process *process = m_exe_ctx.GetProcessPtr();
766     if (process && process->IsAlive()) {
767       result.AppendErrorWithFormat(
768           "Process %" PRIu64
769           " is currently being debugged, kill the process before connecting.\n",
770           process->GetID());
771       result.SetStatus(eReturnStatusFailed);
772       return false;
773     }
774 
775     const char *plugin_name = nullptr;
776     if (!m_options.plugin_name.empty())
777       plugin_name = m_options.plugin_name.c_str();
778 
779     Status error;
780     Debugger &debugger = GetDebugger();
781     PlatformSP platform_sp = m_interpreter.GetPlatform(true);
782     ProcessSP process_sp =
783         debugger.GetAsyncExecution()
784             ? platform_sp->ConnectProcess(
785                   command.GetArgumentAtIndex(0), plugin_name, debugger,
786                   debugger.GetSelectedTarget().get(), error)
787             : platform_sp->ConnectProcessSynchronous(
788                   command.GetArgumentAtIndex(0), plugin_name, debugger,
789                   result.GetOutputStream(), debugger.GetSelectedTarget().get(),
790                   error);
791     if (error.Fail() || process_sp == nullptr) {
792       result.AppendError(error.AsCString("Error connecting to the process"));
793       result.SetStatus(eReturnStatusFailed);
794       return false;
795     }
796     return true;
797   }
798 
799   CommandOptions m_options;
800 };
801 
802 // CommandObjectProcessPlugin
803 #pragma mark CommandObjectProcessPlugin
804 
805 class CommandObjectProcessPlugin : public CommandObjectProxy {
806 public:
807   CommandObjectProcessPlugin(CommandInterpreter &interpreter)
808       : CommandObjectProxy(
809             interpreter, "process plugin",
810             "Send a custom command to the current target process plug-in.",
811             "process plugin <args>", 0) {}
812 
813   ~CommandObjectProcessPlugin() override = default;
814 
815   CommandObject *GetProxyCommandObject() override {
816     Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
817     if (process)
818       return process->GetPluginCommandObject();
819     return nullptr;
820   }
821 };
822 
823 // CommandObjectProcessLoad
824 #define LLDB_OPTIONS_process_load
825 #include "CommandOptions.inc"
826 
827 #pragma mark CommandObjectProcessLoad
828 
829 class CommandObjectProcessLoad : public CommandObjectParsed {
830 public:
831   class CommandOptions : public Options {
832   public:
833     CommandOptions() : Options() {
834       // Keep default values of all options in one place: OptionParsingStarting
835       // ()
836       OptionParsingStarting(nullptr);
837     }
838 
839     ~CommandOptions() override = default;
840 
841     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
842                           ExecutionContext *execution_context) override {
843       Status error;
844       const int short_option = m_getopt_table[option_idx].val;
845       switch (short_option) {
846       case 'i':
847         do_install = true;
848         if (!option_arg.empty())
849           install_path.SetFile(option_arg, FileSpec::Style::native);
850         break;
851       default:
852         llvm_unreachable("Unimplemented option");
853       }
854       return error;
855     }
856 
857     void OptionParsingStarting(ExecutionContext *execution_context) override {
858       do_install = false;
859       install_path.Clear();
860     }
861 
862     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
863       return llvm::makeArrayRef(g_process_load_options);
864     }
865 
866     // Instance variables to hold the values for command options.
867     bool do_install;
868     FileSpec install_path;
869   };
870 
871   CommandObjectProcessLoad(CommandInterpreter &interpreter)
872       : CommandObjectParsed(interpreter, "process load",
873                             "Load a shared library into the current process.",
874                             "process load <filename> [<filename> ...]",
875                             eCommandRequiresProcess | eCommandTryTargetAPILock |
876                                 eCommandProcessMustBeLaunched |
877                                 eCommandProcessMustBePaused),
878         m_options() {}
879 
880   ~CommandObjectProcessLoad() override = default;
881 
882   void
883   HandleArgumentCompletion(CompletionRequest &request,
884                            OptionElementVector &opt_element_vector) override {
885     if (!m_exe_ctx.HasProcessScope())
886       return;
887 
888     CommandCompletions::InvokeCommonCompletionCallbacks(
889         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
890         request, nullptr);
891   }
892 
893   Options *GetOptions() override { return &m_options; }
894 
895 protected:
896   bool DoExecute(Args &command, CommandReturnObject &result) override {
897     Process *process = m_exe_ctx.GetProcessPtr();
898 
899     for (auto &entry : command.entries()) {
900       Status error;
901       PlatformSP platform = process->GetTarget().GetPlatform();
902       llvm::StringRef image_path = entry.ref();
903       uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
904 
905       if (!m_options.do_install) {
906         FileSpec image_spec(image_path);
907         platform->ResolveRemotePath(image_spec, image_spec);
908         image_token =
909             platform->LoadImage(process, FileSpec(), image_spec, error);
910       } else if (m_options.install_path) {
911         FileSpec image_spec(image_path);
912         FileSystem::Instance().Resolve(image_spec);
913         platform->ResolveRemotePath(m_options.install_path,
914                                     m_options.install_path);
915         image_token = platform->LoadImage(process, image_spec,
916                                           m_options.install_path, error);
917       } else {
918         FileSpec image_spec(image_path);
919         FileSystem::Instance().Resolve(image_spec);
920         image_token =
921             platform->LoadImage(process, image_spec, FileSpec(), error);
922       }
923 
924       if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
925         result.AppendMessageWithFormat(
926             "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
927             image_token);
928         result.SetStatus(eReturnStatusSuccessFinishResult);
929       } else {
930         result.AppendErrorWithFormat("failed to load '%s': %s",
931                                      image_path.str().c_str(),
932                                      error.AsCString());
933         result.SetStatus(eReturnStatusFailed);
934       }
935     }
936     return result.Succeeded();
937   }
938 
939   CommandOptions m_options;
940 };
941 
942 // CommandObjectProcessUnload
943 #pragma mark CommandObjectProcessUnload
944 
945 class CommandObjectProcessUnload : public CommandObjectParsed {
946 public:
947   CommandObjectProcessUnload(CommandInterpreter &interpreter)
948       : CommandObjectParsed(
949             interpreter, "process unload",
950             "Unload a shared library from the current process using the index "
951             "returned by a previous call to \"process load\".",
952             "process unload <index>",
953             eCommandRequiresProcess | eCommandTryTargetAPILock |
954                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
955 
956   ~CommandObjectProcessUnload() override = default;
957 
958   void
959   HandleArgumentCompletion(CompletionRequest &request,
960                            OptionElementVector &opt_element_vector) override {
961 
962     if (request.GetCursorIndex() || !m_exe_ctx.HasProcessScope())
963       return;
964 
965     Process *process = m_exe_ctx.GetProcessPtr();
966 
967     const std::vector<lldb::addr_t> &tokens = process->GetImageTokens();
968     const size_t token_num = tokens.size();
969     for (size_t i = 0; i < token_num; ++i) {
970       if (tokens[i] == LLDB_INVALID_IMAGE_TOKEN)
971         continue;
972       request.TryCompleteCurrentArg(std::to_string(i));
973     }
974   }
975 
976 protected:
977   bool DoExecute(Args &command, CommandReturnObject &result) override {
978     Process *process = m_exe_ctx.GetProcessPtr();
979 
980     for (auto &entry : command.entries()) {
981       uint32_t image_token;
982       if (entry.ref().getAsInteger(0, image_token)) {
983         result.AppendErrorWithFormat("invalid image index argument '%s'",
984                                      entry.ref().str().c_str());
985         result.SetStatus(eReturnStatusFailed);
986         break;
987       } else {
988         Status error(process->GetTarget().GetPlatform()->UnloadImage(
989             process, image_token));
990         if (error.Success()) {
991           result.AppendMessageWithFormat(
992               "Unloading shared library with index %u...ok\n", image_token);
993           result.SetStatus(eReturnStatusSuccessFinishResult);
994         } else {
995           result.AppendErrorWithFormat("failed to unload image: %s",
996                                        error.AsCString());
997           result.SetStatus(eReturnStatusFailed);
998           break;
999         }
1000       }
1001     }
1002     return result.Succeeded();
1003   }
1004 };
1005 
1006 // CommandObjectProcessSignal
1007 #pragma mark CommandObjectProcessSignal
1008 
1009 class CommandObjectProcessSignal : public CommandObjectParsed {
1010 public:
1011   CommandObjectProcessSignal(CommandInterpreter &interpreter)
1012       : CommandObjectParsed(
1013             interpreter, "process signal",
1014             "Send a UNIX signal to the current target process.", nullptr,
1015             eCommandRequiresProcess | eCommandTryTargetAPILock) {
1016     CommandArgumentEntry arg;
1017     CommandArgumentData signal_arg;
1018 
1019     // Define the first (and only) variant of this arg.
1020     signal_arg.arg_type = eArgTypeUnixSignal;
1021     signal_arg.arg_repetition = eArgRepeatPlain;
1022 
1023     // There is only one variant this argument could be; put it into the
1024     // argument entry.
1025     arg.push_back(signal_arg);
1026 
1027     // Push the data for the first argument into the m_arguments vector.
1028     m_arguments.push_back(arg);
1029   }
1030 
1031   ~CommandObjectProcessSignal() override = default;
1032 
1033   void
1034   HandleArgumentCompletion(CompletionRequest &request,
1035                            OptionElementVector &opt_element_vector) override {
1036     if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
1037       return;
1038 
1039     UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals();
1040     int signo = signals->GetFirstSignalNumber();
1041     while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1042       request.AddCompletion(signals->GetSignalAsCString(signo), "");
1043       signo = signals->GetNextSignalNumber(signo);
1044     }
1045   }
1046 
1047 protected:
1048   bool DoExecute(Args &command, CommandReturnObject &result) override {
1049     Process *process = m_exe_ctx.GetProcessPtr();
1050 
1051     if (command.GetArgumentCount() == 1) {
1052       int signo = LLDB_INVALID_SIGNAL_NUMBER;
1053 
1054       const char *signal_name = command.GetArgumentAtIndex(0);
1055       if (::isxdigit(signal_name[0])) {
1056         if (!llvm::to_integer(signal_name, signo))
1057           signo = LLDB_INVALID_SIGNAL_NUMBER;
1058       } else
1059         signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1060 
1061       if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
1062         result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
1063                                      command.GetArgumentAtIndex(0));
1064         result.SetStatus(eReturnStatusFailed);
1065       } else {
1066         Status error(process->Signal(signo));
1067         if (error.Success()) {
1068           result.SetStatus(eReturnStatusSuccessFinishResult);
1069         } else {
1070           result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
1071                                        error.AsCString());
1072           result.SetStatus(eReturnStatusFailed);
1073         }
1074       }
1075     } else {
1076       result.AppendErrorWithFormat(
1077           "'%s' takes exactly one signal number argument:\nUsage: %s\n",
1078           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1079       result.SetStatus(eReturnStatusFailed);
1080     }
1081     return result.Succeeded();
1082   }
1083 };
1084 
1085 // CommandObjectProcessInterrupt
1086 #pragma mark CommandObjectProcessInterrupt
1087 
1088 class CommandObjectProcessInterrupt : public CommandObjectParsed {
1089 public:
1090   CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1091       : CommandObjectParsed(interpreter, "process interrupt",
1092                             "Interrupt the current target process.",
1093                             "process interrupt",
1094                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1095                                 eCommandProcessMustBeLaunched) {}
1096 
1097   ~CommandObjectProcessInterrupt() override = default;
1098 
1099 protected:
1100   bool DoExecute(Args &command, CommandReturnObject &result) override {
1101     Process *process = m_exe_ctx.GetProcessPtr();
1102     if (process == nullptr) {
1103       result.AppendError("no process to halt");
1104       result.SetStatus(eReturnStatusFailed);
1105       return false;
1106     }
1107 
1108     if (command.GetArgumentCount() == 0) {
1109       bool clear_thread_plans = true;
1110       Status error(process->Halt(clear_thread_plans));
1111       if (error.Success()) {
1112         result.SetStatus(eReturnStatusSuccessFinishResult);
1113       } else {
1114         result.AppendErrorWithFormat("Failed to halt process: %s\n",
1115                                      error.AsCString());
1116         result.SetStatus(eReturnStatusFailed);
1117       }
1118     } else {
1119       result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1120                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
1121       result.SetStatus(eReturnStatusFailed);
1122     }
1123     return result.Succeeded();
1124   }
1125 };
1126 
1127 // CommandObjectProcessKill
1128 #pragma mark CommandObjectProcessKill
1129 
1130 class CommandObjectProcessKill : public CommandObjectParsed {
1131 public:
1132   CommandObjectProcessKill(CommandInterpreter &interpreter)
1133       : CommandObjectParsed(interpreter, "process kill",
1134                             "Terminate the current target process.",
1135                             "process kill",
1136                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1137                                 eCommandProcessMustBeLaunched) {}
1138 
1139   ~CommandObjectProcessKill() override = default;
1140 
1141 protected:
1142   bool DoExecute(Args &command, CommandReturnObject &result) override {
1143     Process *process = m_exe_ctx.GetProcessPtr();
1144     if (process == nullptr) {
1145       result.AppendError("no process to kill");
1146       result.SetStatus(eReturnStatusFailed);
1147       return false;
1148     }
1149 
1150     if (command.GetArgumentCount() == 0) {
1151       Status error(process->Destroy(true));
1152       if (error.Success()) {
1153         result.SetStatus(eReturnStatusSuccessFinishResult);
1154       } else {
1155         result.AppendErrorWithFormat("Failed to kill process: %s\n",
1156                                      error.AsCString());
1157         result.SetStatus(eReturnStatusFailed);
1158       }
1159     } else {
1160       result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
1161                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
1162       result.SetStatus(eReturnStatusFailed);
1163     }
1164     return result.Succeeded();
1165   }
1166 };
1167 
1168 // CommandObjectProcessSaveCore
1169 #pragma mark CommandObjectProcessSaveCore
1170 
1171 class CommandObjectProcessSaveCore : public CommandObjectParsed {
1172 public:
1173   CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1174       : CommandObjectParsed(interpreter, "process save-core",
1175                             "Save the current process as a core file using an "
1176                             "appropriate file type.",
1177                             "process save-core FILE",
1178                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1179                                 eCommandProcessMustBeLaunched) {}
1180 
1181   ~CommandObjectProcessSaveCore() override = default;
1182 
1183 protected:
1184   bool DoExecute(Args &command, CommandReturnObject &result) override {
1185     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1186     if (process_sp) {
1187       if (command.GetArgumentCount() == 1) {
1188         FileSpec output_file(command.GetArgumentAtIndex(0));
1189         Status error = PluginManager::SaveCore(process_sp, output_file);
1190         if (error.Success()) {
1191           result.SetStatus(eReturnStatusSuccessFinishResult);
1192         } else {
1193           result.AppendErrorWithFormat(
1194               "Failed to save core file for process: %s\n", error.AsCString());
1195           result.SetStatus(eReturnStatusFailed);
1196         }
1197       } else {
1198         result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1199                                      m_cmd_name.c_str(), m_cmd_syntax.c_str());
1200         result.SetStatus(eReturnStatusFailed);
1201       }
1202     } else {
1203       result.AppendError("invalid process");
1204       result.SetStatus(eReturnStatusFailed);
1205       return false;
1206     }
1207 
1208     return result.Succeeded();
1209   }
1210 };
1211 
1212 // CommandObjectProcessStatus
1213 #pragma mark CommandObjectProcessStatus
1214 #define LLDB_OPTIONS_process_status
1215 #include "CommandOptions.inc"
1216 
1217 class CommandObjectProcessStatus : public CommandObjectParsed {
1218 public:
1219   CommandObjectProcessStatus(CommandInterpreter &interpreter)
1220       : CommandObjectParsed(
1221             interpreter, "process status",
1222             "Show status and stop location for the current target process.",
1223             "process status",
1224             eCommandRequiresProcess | eCommandTryTargetAPILock),
1225         m_options() {}
1226 
1227   ~CommandObjectProcessStatus() override = default;
1228 
1229   Options *GetOptions() override { return &m_options; }
1230 
1231   class CommandOptions : public Options {
1232   public:
1233     CommandOptions() : Options(), m_verbose(false) {}
1234 
1235     ~CommandOptions() override = default;
1236 
1237     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1238                           ExecutionContext *execution_context) override {
1239       const int short_option = m_getopt_table[option_idx].val;
1240 
1241       switch (short_option) {
1242       case 'v':
1243         m_verbose = true;
1244         break;
1245       default:
1246         llvm_unreachable("Unimplemented option");
1247       }
1248 
1249       return {};
1250     }
1251 
1252     void OptionParsingStarting(ExecutionContext *execution_context) override {
1253       m_verbose = false;
1254     }
1255 
1256     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1257       return llvm::makeArrayRef(g_process_status_options);
1258     }
1259 
1260     // Instance variables to hold the values for command options.
1261     bool m_verbose;
1262   };
1263 
1264 protected:
1265   bool DoExecute(Args &command, CommandReturnObject &result) override {
1266     Stream &strm = result.GetOutputStream();
1267     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1268 
1269     if (command.GetArgumentCount()) {
1270       result.AppendError("'process status' takes no arguments");
1271       result.SetStatus(eReturnStatusFailed);
1272       return result.Succeeded();
1273     }
1274 
1275     // No need to check "process" for validity as eCommandRequiresProcess
1276     // ensures it is valid
1277     Process *process = m_exe_ctx.GetProcessPtr();
1278     const bool only_threads_with_stop_reason = true;
1279     const uint32_t start_frame = 0;
1280     const uint32_t num_frames = 1;
1281     const uint32_t num_frames_with_source = 1;
1282     const bool stop_format = true;
1283     process->GetStatus(strm);
1284     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1285                              num_frames, num_frames_with_source, stop_format);
1286 
1287     if (m_options.m_verbose) {
1288       PlatformSP platform_sp = process->GetTarget().GetPlatform();
1289       if (!platform_sp) {
1290         result.AppendError("Couldn'retrieve the target's platform");
1291         result.SetStatus(eReturnStatusFailed);
1292         return result.Succeeded();
1293       }
1294 
1295       auto expected_crash_info =
1296           platform_sp->FetchExtendedCrashInformation(*process);
1297 
1298       if (!expected_crash_info) {
1299         result.AppendError(llvm::toString(expected_crash_info.takeError()));
1300         result.SetStatus(eReturnStatusFailed);
1301         return result.Succeeded();
1302       }
1303 
1304       StructuredData::DictionarySP crash_info_sp = *expected_crash_info;
1305 
1306       if (crash_info_sp) {
1307         strm.PutCString("Extended Crash Information:\n");
1308         crash_info_sp->Dump(strm);
1309       }
1310     }
1311 
1312     return result.Succeeded();
1313   }
1314 
1315 private:
1316   CommandOptions m_options;
1317 };
1318 
1319 // CommandObjectProcessHandle
1320 #define LLDB_OPTIONS_process_handle
1321 #include "CommandOptions.inc"
1322 
1323 #pragma mark CommandObjectProcessHandle
1324 
1325 class CommandObjectProcessHandle : public CommandObjectParsed {
1326 public:
1327   class CommandOptions : public Options {
1328   public:
1329     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1330 
1331     ~CommandOptions() override = default;
1332 
1333     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1334                           ExecutionContext *execution_context) override {
1335       Status error;
1336       const int short_option = m_getopt_table[option_idx].val;
1337 
1338       switch (short_option) {
1339       case 's':
1340         stop = std::string(option_arg);
1341         break;
1342       case 'n':
1343         notify = std::string(option_arg);
1344         break;
1345       case 'p':
1346         pass = std::string(option_arg);
1347         break;
1348       default:
1349         llvm_unreachable("Unimplemented option");
1350       }
1351       return error;
1352     }
1353 
1354     void OptionParsingStarting(ExecutionContext *execution_context) override {
1355       stop.clear();
1356       notify.clear();
1357       pass.clear();
1358     }
1359 
1360     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1361       return llvm::makeArrayRef(g_process_handle_options);
1362     }
1363 
1364     // Instance variables to hold the values for command options.
1365 
1366     std::string stop;
1367     std::string notify;
1368     std::string pass;
1369   };
1370 
1371   CommandObjectProcessHandle(CommandInterpreter &interpreter)
1372       : CommandObjectParsed(interpreter, "process handle",
1373                             "Manage LLDB handling of OS signals for the "
1374                             "current target process.  Defaults to showing "
1375                             "current policy.",
1376                             nullptr, eCommandRequiresTarget),
1377         m_options() {
1378     SetHelpLong("\nIf no signals are specified, update them all.  If no update "
1379                 "option is specified, list the current values.");
1380     CommandArgumentEntry arg;
1381     CommandArgumentData signal_arg;
1382 
1383     signal_arg.arg_type = eArgTypeUnixSignal;
1384     signal_arg.arg_repetition = eArgRepeatStar;
1385 
1386     arg.push_back(signal_arg);
1387 
1388     m_arguments.push_back(arg);
1389   }
1390 
1391   ~CommandObjectProcessHandle() override = default;
1392 
1393   Options *GetOptions() override { return &m_options; }
1394 
1395   bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
1396     bool okay = true;
1397     bool success = false;
1398     bool tmp_value = OptionArgParser::ToBoolean(option, false, &success);
1399 
1400     if (success && tmp_value)
1401       real_value = 1;
1402     else if (success && !tmp_value)
1403       real_value = 0;
1404     else {
1405       // If the value isn't 'true' or 'false', it had better be 0 or 1.
1406       if (!llvm::to_integer(option, real_value))
1407         real_value = 3;
1408       if (real_value != 0 && real_value != 1)
1409         okay = false;
1410     }
1411 
1412     return okay;
1413   }
1414 
1415   void PrintSignalHeader(Stream &str) {
1416     str.Printf("NAME         PASS   STOP   NOTIFY\n");
1417     str.Printf("===========  =====  =====  ======\n");
1418   }
1419 
1420   void PrintSignal(Stream &str, int32_t signo, const char *sig_name,
1421                    const UnixSignalsSP &signals_sp) {
1422     bool stop;
1423     bool suppress;
1424     bool notify;
1425 
1426     str.Printf("%-11s  ", sig_name);
1427     if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
1428       bool pass = !suppress;
1429       str.Printf("%s  %s  %s", (pass ? "true " : "false"),
1430                  (stop ? "true " : "false"), (notify ? "true " : "false"));
1431     }
1432     str.Printf("\n");
1433   }
1434 
1435   void PrintSignalInformation(Stream &str, Args &signal_args,
1436                               int num_valid_signals,
1437                               const UnixSignalsSP &signals_sp) {
1438     PrintSignalHeader(str);
1439 
1440     if (num_valid_signals > 0) {
1441       size_t num_args = signal_args.GetArgumentCount();
1442       for (size_t i = 0; i < num_args; ++i) {
1443         int32_t signo = signals_sp->GetSignalNumberFromName(
1444             signal_args.GetArgumentAtIndex(i));
1445         if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1446           PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1447                       signals_sp);
1448       }
1449     } else // Print info for ALL signals
1450     {
1451       int32_t signo = signals_sp->GetFirstSignalNumber();
1452       while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1453         PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo),
1454                     signals_sp);
1455         signo = signals_sp->GetNextSignalNumber(signo);
1456       }
1457     }
1458   }
1459 
1460 protected:
1461   bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
1462     Target *target_sp = &GetSelectedTarget();
1463 
1464     ProcessSP process_sp = target_sp->GetProcessSP();
1465 
1466     if (!process_sp) {
1467       result.AppendError("No current process; cannot handle signals until you "
1468                          "have a valid process.\n");
1469       result.SetStatus(eReturnStatusFailed);
1470       return false;
1471     }
1472 
1473     int stop_action = -1;   // -1 means leave the current setting alone
1474     int pass_action = -1;   // -1 means leave the current setting alone
1475     int notify_action = -1; // -1 means leave the current setting alone
1476 
1477     if (!m_options.stop.empty() &&
1478         !VerifyCommandOptionValue(m_options.stop, stop_action)) {
1479       result.AppendError("Invalid argument for command option --stop; must be "
1480                          "true or false.\n");
1481       result.SetStatus(eReturnStatusFailed);
1482       return false;
1483     }
1484 
1485     if (!m_options.notify.empty() &&
1486         !VerifyCommandOptionValue(m_options.notify, notify_action)) {
1487       result.AppendError("Invalid argument for command option --notify; must "
1488                          "be true or false.\n");
1489       result.SetStatus(eReturnStatusFailed);
1490       return false;
1491     }
1492 
1493     if (!m_options.pass.empty() &&
1494         !VerifyCommandOptionValue(m_options.pass, pass_action)) {
1495       result.AppendError("Invalid argument for command option --pass; must be "
1496                          "true or false.\n");
1497       result.SetStatus(eReturnStatusFailed);
1498       return false;
1499     }
1500 
1501     size_t num_args = signal_args.GetArgumentCount();
1502     UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
1503     int num_signals_set = 0;
1504 
1505     if (num_args > 0) {
1506       for (const auto &arg : signal_args) {
1507         int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1508         if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1509           // Casting the actions as bools here should be okay, because
1510           // VerifyCommandOptionValue guarantees the value is either 0 or 1.
1511           if (stop_action != -1)
1512             signals_sp->SetShouldStop(signo, stop_action);
1513           if (pass_action != -1) {
1514             bool suppress = !pass_action;
1515             signals_sp->SetShouldSuppress(signo, suppress);
1516           }
1517           if (notify_action != -1)
1518             signals_sp->SetShouldNotify(signo, notify_action);
1519           ++num_signals_set;
1520         } else {
1521           result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1522                                        arg.c_str());
1523         }
1524       }
1525     } else {
1526       // No signal specified, if any command options were specified, update ALL
1527       // signals.
1528       if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) {
1529         if (m_interpreter.Confirm(
1530                 "Do you really want to update all the signals?", false)) {
1531           int32_t signo = signals_sp->GetFirstSignalNumber();
1532           while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1533             if (notify_action != -1)
1534               signals_sp->SetShouldNotify(signo, notify_action);
1535             if (stop_action != -1)
1536               signals_sp->SetShouldStop(signo, stop_action);
1537             if (pass_action != -1) {
1538               bool suppress = !pass_action;
1539               signals_sp->SetShouldSuppress(signo, suppress);
1540             }
1541             signo = signals_sp->GetNextSignalNumber(signo);
1542           }
1543         }
1544       }
1545     }
1546 
1547     PrintSignalInformation(result.GetOutputStream(), signal_args,
1548                            num_signals_set, signals_sp);
1549 
1550     if (num_signals_set > 0)
1551       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1552     else
1553       result.SetStatus(eReturnStatusFailed);
1554 
1555     return result.Succeeded();
1556   }
1557 
1558   CommandOptions m_options;
1559 };
1560 
1561 // CommandObjectMultiwordProcess
1562 
1563 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1564     CommandInterpreter &interpreter)
1565     : CommandObjectMultiword(
1566           interpreter, "process",
1567           "Commands for interacting with processes on the current platform.",
1568           "process <subcommand> [<subcommand-options>]") {
1569   LoadSubCommand("attach",
1570                  CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1571   LoadSubCommand("launch",
1572                  CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1573   LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1574                                  interpreter)));
1575   LoadSubCommand("connect",
1576                  CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1577   LoadSubCommand("detach",
1578                  CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1579   LoadSubCommand("load",
1580                  CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1581   LoadSubCommand("unload",
1582                  CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1583   LoadSubCommand("signal",
1584                  CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1585   LoadSubCommand("handle",
1586                  CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1587   LoadSubCommand("status",
1588                  CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1589   LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1590                                   interpreter)));
1591   LoadSubCommand("kill",
1592                  CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1593   LoadSubCommand("plugin",
1594                  CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1595   LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1596                                   interpreter)));
1597 }
1598 
1599 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1600