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