xref: /llvm-project/lldb/source/Commands/CommandObjectProcess.cpp (revision 36254f1a0f32e8a1db353efbe1f8c3a290e5b084)
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 "CommandOptionsProcessLaunch.h"
11 #include "lldb/Breakpoint/Breakpoint.h"
12 #include "lldb/Breakpoint/BreakpointLocation.h"
13 #include "lldb/Breakpoint/BreakpointSite.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Host/OptionParser.h"
17 #include "lldb/Interpreter/CommandInterpreter.h"
18 #include "lldb/Interpreter/CommandReturnObject.h"
19 #include "lldb/Interpreter/OptionArgParser.h"
20 #include "lldb/Interpreter/Options.h"
21 #include "lldb/Target/Platform.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/StopInfo.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Target/UnixSignals.h"
27 #include "lldb/Utility/Args.h"
28 #include "lldb/Utility/State.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
34 public:
35   CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
36                                      const char *name, const char *help,
37                                      const char *syntax, uint32_t flags,
38                                      const char *new_process_action)
39       : CommandObjectParsed(interpreter, name, help, syntax, flags),
40         m_new_process_action(new_process_action) {}
41 
42   ~CommandObjectProcessLaunchOrAttach() override = default;
43 
44 protected:
45   bool StopProcessIfNecessary(Process *process, StateType &state,
46                               CommandReturnObject &result) {
47     state = eStateInvalid;
48     if (process) {
49       state = process->GetState();
50 
51       if (process->IsAlive() && state != eStateConnected) {
52         std::string message;
53         if (process->GetState() == eStateAttaching)
54           message =
55               llvm::formatv("There is a pending attach, abort it and {0}?",
56                             m_new_process_action);
57         else if (process->GetShouldDetach())
58           message = llvm::formatv(
59               "There is a running process, detach from it and {0}?",
60               m_new_process_action);
61         else
62           message =
63               llvm::formatv("There is a running process, kill it and {0}?",
64                             m_new_process_action);
65 
66         if (!m_interpreter.Confirm(message, true)) {
67           result.SetStatus(eReturnStatusFailed);
68           return false;
69         } else {
70           if (process->GetShouldDetach()) {
71             bool keep_stopped = false;
72             Status detach_error(process->Detach(keep_stopped));
73             if (detach_error.Success()) {
74               result.SetStatus(eReturnStatusSuccessFinishResult);
75               process = nullptr;
76             } else {
77               result.AppendErrorWithFormat(
78                   "Failed to detach from process: %s\n",
79                   detach_error.AsCString());
80               result.SetStatus(eReturnStatusFailed);
81             }
82           } else {
83             Status destroy_error(process->Destroy(false));
84             if (destroy_error.Success()) {
85               result.SetStatus(eReturnStatusSuccessFinishResult);
86               process = nullptr;
87             } else {
88               result.AppendErrorWithFormat("Failed to kill process: %s\n",
89                                            destroy_error.AsCString());
90               result.SetStatus(eReturnStatusFailed);
91             }
92           }
93         }
94       }
95     }
96     return result.Succeeded();
97   }
98 
99   std::string m_new_process_action;
100 };
101 
102 // CommandObjectProcessLaunch
103 #pragma mark CommandObjectProcessLaunch
104 class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
105 public:
106   CommandObjectProcessLaunch(CommandInterpreter &interpreter)
107       : CommandObjectProcessLaunchOrAttach(
108             interpreter, "process launch",
109             "Launch the executable in the debugger.", nullptr,
110             eCommandRequiresTarget, "restart"),
111         m_options() {
112     CommandArgumentEntry arg;
113     CommandArgumentData run_args_arg;
114 
115     // Define the first (and only) variant of this arg.
116     run_args_arg.arg_type = eArgTypeRunArgs;
117     run_args_arg.arg_repetition = eArgRepeatOptional;
118 
119     // There is only one variant this argument could be; put it into the
120     // argument entry.
121     arg.push_back(run_args_arg);
122 
123     // Push the data for the first argument into the m_arguments vector.
124     m_arguments.push_back(arg);
125   }
126 
127   ~CommandObjectProcessLaunch() override = default;
128 
129   void
130   HandleArgumentCompletion(CompletionRequest &request,
131                            OptionElementVector &opt_element_vector) override {
132 
133     CommandCompletions::InvokeCommonCompletionCallbacks(
134         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
135         request, nullptr);
136   }
137 
138   Options *GetOptions() override { return &m_options; }
139 
140   const char *GetRepeatCommand(Args &current_command_args,
141                                uint32_t index) override {
142     // No repeat for "process launch"...
143     return "";
144   }
145 
146 protected:
147   bool DoExecute(Args &launch_args, CommandReturnObject &result) override {
148     Debugger &debugger = GetDebugger();
149     Target *target = debugger.GetSelectedTarget().get();
150     // If our listener is nullptr, users aren't allows to launch
151     ModuleSP exe_module_sp = target->GetExecutableModule();
152 
153     if (exe_module_sp == nullptr) {
154       result.AppendError("no file in target, create a debug target using the "
155                          "'target create' command");
156       result.SetStatus(eReturnStatusFailed);
157       return false;
158     }
159 
160     StateType state = eStateInvalid;
161 
162     if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
163       return false;
164 
165     llvm::StringRef target_settings_argv0 = target->GetArg0();
166 
167     // Determine whether we will disable ASLR or leave it in the default state
168     // (i.e. enabled if the platform supports it). First check if the process
169     // launch options explicitly turn on/off
170     // disabling ASLR.  If so, use that setting;
171     // otherwise, use the 'settings target.disable-aslr' setting.
172     bool disable_aslr = false;
173     if (m_options.disable_aslr != eLazyBoolCalculate) {
174       // The user specified an explicit setting on the process launch line.
175       // Use it.
176       disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
177     } else {
178       // The user did not explicitly specify whether to disable ASLR.  Fall
179       // back to the target.disable-aslr setting.
180       disable_aslr = target->GetDisableASLR();
181     }
182 
183     if (disable_aslr)
184       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
185     else
186       m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
187 
188     if (target->GetInheritTCC())
189       m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
190 
191     if (target->GetDetachOnError())
192       m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
193 
194     if (target->GetDisableSTDIO())
195       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
196 
197     // Merge the launch info environment with the target environment.
198     Environment target_env = target->GetEnvironment();
199     m_options.launch_info.GetEnvironment().insert(target_env.begin(),
200                                                   target_env.end());
201 
202     if (!target_settings_argv0.empty()) {
203       m_options.launch_info.GetArguments().AppendArgument(
204           target_settings_argv0);
205       m_options.launch_info.SetExecutableFile(
206           exe_module_sp->GetPlatformFileSpec(), false);
207     } else {
208       m_options.launch_info.SetExecutableFile(
209           exe_module_sp->GetPlatformFileSpec(), true);
210     }
211 
212     if (launch_args.GetArgumentCount() == 0) {
213       m_options.launch_info.GetArguments().AppendArguments(
214           target->GetProcessLaunchInfo().GetArguments());
215     } else {
216       m_options.launch_info.GetArguments().AppendArguments(launch_args);
217       // Save the arguments for subsequent runs in the current target.
218       target->SetRunArguments(launch_args);
219     }
220 
221     StreamString stream;
222     Status error = target->Launch(m_options.launch_info, &stream);
223 
224     if (error.Success()) {
225       ProcessSP process_sp(target->GetProcessSP());
226       if (process_sp) {
227         // There is a race condition where this thread will return up the call
228         // stack to the main command handler and show an (lldb) prompt before
229         // HandlePrivateEvent (from PrivateStateThread) has a chance to call
230         // PushProcessIOHandler().
231         process_sp->SyncIOHandler(0, std::chrono::seconds(2));
232 
233         llvm::StringRef data = stream.GetString();
234         if (!data.empty())
235           result.AppendMessage(data);
236         const char *archname =
237             exe_module_sp->GetArchitecture().GetArchitectureName();
238         result.AppendMessageWithFormat(
239             "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
240             exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
241         result.SetStatus(eReturnStatusSuccessFinishResult);
242         result.SetDidChangeProcessState(true);
243       } else {
244         result.AppendError(
245             "no error returned from Target::Launch, and target has no process");
246         result.SetStatus(eReturnStatusFailed);
247       }
248     } else {
249       result.AppendError(error.AsCString());
250       result.SetStatus(eReturnStatusFailed);
251     }
252     return result.Succeeded();
253   }
254 
255   CommandOptionsProcessLaunch m_options;
256 };
257 
258 #define LLDB_OPTIONS_process_attach
259 #include "CommandOptions.inc"
260 
261 #pragma mark CommandObjectProcessAttach
262 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
263 public:
264   class CommandOptions : public Options {
265   public:
266     CommandOptions() : Options() {
267       // Keep default values of all options in one place: OptionParsingStarting
268       // ()
269       OptionParsingStarting(nullptr);
270     }
271 
272     ~CommandOptions() override = default;
273 
274     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
275                           ExecutionContext *execution_context) override {
276       Status error;
277       const int short_option = m_getopt_table[option_idx].val;
278       switch (short_option) {
279       case 'c':
280         attach_info.SetContinueOnceAttached(true);
281         break;
282 
283       case 'p': {
284         lldb::pid_t pid;
285         if (option_arg.getAsInteger(0, pid)) {
286           error.SetErrorStringWithFormat("invalid process ID '%s'",
287                                          option_arg.str().c_str());
288         } else {
289           attach_info.SetProcessID(pid);
290         }
291       } break;
292 
293       case 'P':
294         attach_info.SetProcessPluginName(option_arg);
295         break;
296 
297       case 'n':
298         attach_info.GetExecutableFile().SetFile(option_arg,
299                                                 FileSpec::Style::native);
300         break;
301 
302       case 'w':
303         attach_info.SetWaitForLaunch(true);
304         break;
305 
306       case 'i':
307         attach_info.SetIgnoreExisting(false);
308         break;
309 
310       default:
311         llvm_unreachable("Unimplemented option");
312       }
313       return error;
314     }
315 
316     void OptionParsingStarting(ExecutionContext *execution_context) override {
317       attach_info.Clear();
318     }
319 
320     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
321       return llvm::makeArrayRef(g_process_attach_options);
322     }
323 
324     ProcessAttachInfo attach_info;
325   };
326 
327   CommandObjectProcessAttach(CommandInterpreter &interpreter)
328       : CommandObjectProcessLaunchOrAttach(
329             interpreter, "process attach", "Attach to a process.",
330             "process attach <cmd-options>", 0, "attach"),
331         m_options() {}
332 
333   ~CommandObjectProcessAttach() override = default;
334 
335   Options *GetOptions() override { return &m_options; }
336 
337 protected:
338   bool DoExecute(Args &command, CommandReturnObject &result) override {
339     PlatformSP platform_sp(
340         GetDebugger().GetPlatformList().GetSelectedPlatform());
341 
342     Target *target = GetDebugger().GetSelectedTarget().get();
343     // N.B. The attach should be synchronous.  It doesn't help much to get the
344     // prompt back between initiating the attach and the target actually
345     // stopping.  So even if the interpreter is set to be asynchronous, we wait
346     // for the stop ourselves here.
347 
348     StateType state = eStateInvalid;
349     Process *process = m_exe_ctx.GetProcessPtr();
350 
351     if (!StopProcessIfNecessary(process, state, result))
352       return false;
353 
354     if (target == nullptr) {
355       // If there isn't a current target create one.
356       TargetSP new_target_sp;
357       Status error;
358 
359       error = GetDebugger().GetTargetList().CreateTarget(
360           GetDebugger(), "", "", eLoadDependentsNo,
361           nullptr, // No platform options
362           new_target_sp);
363       target = new_target_sp.get();
364       if (target == nullptr || error.Fail()) {
365         result.AppendError(error.AsCString("Error creating target"));
366         return false;
367       }
368     }
369 
370     // Record the old executable module, we want to issue a warning if the
371     // process of attaching changed the current executable (like somebody said
372     // "file foo" then attached to a PID whose executable was bar.)
373 
374     ModuleSP old_exec_module_sp = target->GetExecutableModule();
375     ArchSpec old_arch_spec = target->GetArchitecture();
376 
377     if (command.GetArgumentCount()) {
378       result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n",
379                                    m_cmd_name.c_str(), m_cmd_syntax.c_str());
380       result.SetStatus(eReturnStatusFailed);
381       return false;
382     }
383 
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