xref: /llvm-project/lldb/source/Commands/CommandObjectProcess.cpp (revision bf9f21a28be171dc500cc68b4cb1fcd3fc33f229)
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 class CommandObjectProcessSaveCore : public CommandObjectParsed {
1165 public:
1166   CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1167       : CommandObjectParsed(interpreter, "process save-core",
1168                             "Save the current process as a core file using an "
1169                             "appropriate file type.",
1170                             "process save-core FILE",
1171                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1172                                 eCommandProcessMustBeLaunched) {}
1173 
1174   ~CommandObjectProcessSaveCore() override = default;
1175 
1176 protected:
1177   bool DoExecute(Args &command, CommandReturnObject &result) override {
1178     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1179     if (process_sp) {
1180       if (command.GetArgumentCount() == 1) {
1181         FileSpec output_file(command.GetArgumentAtIndex(0));
1182         Status error = PluginManager::SaveCore(process_sp, output_file);
1183         if (error.Success()) {
1184           result.SetStatus(eReturnStatusSuccessFinishResult);
1185         } else {
1186           result.AppendErrorWithFormat(
1187               "Failed to save core file for process: %s\n", error.AsCString());
1188         }
1189       } else {
1190         result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1191                                      m_cmd_name.c_str(), m_cmd_syntax.c_str());
1192       }
1193     } else {
1194       result.AppendError("invalid process");
1195       return false;
1196     }
1197 
1198     return result.Succeeded();
1199   }
1200 };
1201 
1202 // CommandObjectProcessStatus
1203 #pragma mark CommandObjectProcessStatus
1204 #define LLDB_OPTIONS_process_status
1205 #include "CommandOptions.inc"
1206 
1207 class CommandObjectProcessStatus : public CommandObjectParsed {
1208 public:
1209   CommandObjectProcessStatus(CommandInterpreter &interpreter)
1210       : CommandObjectParsed(
1211             interpreter, "process status",
1212             "Show status and stop location for the current target process.",
1213             "process status",
1214             eCommandRequiresProcess | eCommandTryTargetAPILock),
1215         m_options() {}
1216 
1217   ~CommandObjectProcessStatus() override = default;
1218 
1219   Options *GetOptions() override { return &m_options; }
1220 
1221   class CommandOptions : public Options {
1222   public:
1223     CommandOptions() : Options() {}
1224 
1225     ~CommandOptions() override = default;
1226 
1227     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1228                           ExecutionContext *execution_context) override {
1229       const int short_option = m_getopt_table[option_idx].val;
1230 
1231       switch (short_option) {
1232       case 'v':
1233         m_verbose = true;
1234         break;
1235       default:
1236         llvm_unreachable("Unimplemented option");
1237       }
1238 
1239       return {};
1240     }
1241 
1242     void OptionParsingStarting(ExecutionContext *execution_context) override {
1243       m_verbose = false;
1244     }
1245 
1246     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1247       return llvm::makeArrayRef(g_process_status_options);
1248     }
1249 
1250     // Instance variables to hold the values for command options.
1251     bool m_verbose = false;
1252   };
1253 
1254 protected:
1255   bool DoExecute(Args &command, CommandReturnObject &result) override {
1256     Stream &strm = result.GetOutputStream();
1257     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1258 
1259     if (command.GetArgumentCount()) {
1260       result.AppendError("'process status' takes no arguments");
1261       return result.Succeeded();
1262     }
1263 
1264     // No need to check "process" for validity as eCommandRequiresProcess
1265     // ensures it is valid
1266     Process *process = m_exe_ctx.GetProcessPtr();
1267     const bool only_threads_with_stop_reason = true;
1268     const uint32_t start_frame = 0;
1269     const uint32_t num_frames = 1;
1270     const uint32_t num_frames_with_source = 1;
1271     const bool stop_format = true;
1272     process->GetStatus(strm);
1273     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1274                              num_frames, num_frames_with_source, stop_format);
1275 
1276     if (m_options.m_verbose) {
1277       PlatformSP platform_sp = process->GetTarget().GetPlatform();
1278       if (!platform_sp) {
1279         result.AppendError("Couldn'retrieve the target's platform");
1280         return result.Succeeded();
1281       }
1282 
1283       auto expected_crash_info =
1284           platform_sp->FetchExtendedCrashInformation(*process);
1285 
1286       if (!expected_crash_info) {
1287         result.AppendError(llvm::toString(expected_crash_info.takeError()));
1288         return result.Succeeded();
1289       }
1290 
1291       StructuredData::DictionarySP crash_info_sp = *expected_crash_info;
1292 
1293       if (crash_info_sp) {
1294         strm.PutCString("Extended Crash Information:\n");
1295         crash_info_sp->Dump(strm);
1296       }
1297     }
1298 
1299     return result.Succeeded();
1300   }
1301 
1302 private:
1303   CommandOptions m_options;
1304 };
1305 
1306 // CommandObjectProcessHandle
1307 #define LLDB_OPTIONS_process_handle
1308 #include "CommandOptions.inc"
1309 
1310 #pragma mark CommandObjectProcessHandle
1311 
1312 class CommandObjectProcessHandle : public CommandObjectParsed {
1313 public:
1314   class CommandOptions : public Options {
1315   public:
1316     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
1317 
1318     ~CommandOptions() override = default;
1319 
1320     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1321                           ExecutionContext *execution_context) override {
1322       Status error;
1323       const int short_option = m_getopt_table[option_idx].val;
1324 
1325       switch (short_option) {
1326       case 's':
1327         stop = std::string(option_arg);
1328         break;
1329       case 'n':
1330         notify = std::string(option_arg);
1331         break;
1332       case 'p':
1333         pass = std::string(option_arg);
1334         break;
1335       default:
1336         llvm_unreachable("Unimplemented option");
1337       }
1338       return error;
1339     }
1340 
1341     void OptionParsingStarting(ExecutionContext *execution_context) override {
1342       stop.clear();
1343       notify.clear();
1344       pass.clear();
1345     }
1346 
1347     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1348       return llvm::makeArrayRef(g_process_handle_options);
1349     }
1350 
1351     // Instance variables to hold the values for command options.
1352 
1353     std::string stop;
1354     std::string notify;
1355     std::string pass;
1356   };
1357 
1358   CommandObjectProcessHandle(CommandInterpreter &interpreter)
1359       : CommandObjectParsed(interpreter, "process handle",
1360                             "Manage LLDB handling of OS signals for the "
1361                             "current target process.  Defaults to showing "
1362                             "current policy.",
1363                             nullptr, eCommandRequiresTarget),
1364         m_options() {
1365     SetHelpLong("\nIf no signals are specified, update them all.  If no update "
1366                 "option is specified, list the current values.");
1367     CommandArgumentEntry arg;
1368     CommandArgumentData signal_arg;
1369 
1370     signal_arg.arg_type = eArgTypeUnixSignal;
1371     signal_arg.arg_repetition = eArgRepeatStar;
1372 
1373     arg.push_back(signal_arg);
1374 
1375     m_arguments.push_back(arg);
1376   }
1377 
1378   ~CommandObjectProcessHandle() override = default;
1379 
1380   Options *GetOptions() override { return &m_options; }
1381 
1382   bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
1383     bool okay = true;
1384     bool success = false;
1385     bool tmp_value = OptionArgParser::ToBoolean(option, false, &success);
1386 
1387     if (success && tmp_value)
1388       real_value = 1;
1389     else if (success && !tmp_value)
1390       real_value = 0;
1391     else {
1392       // If the value isn't 'true' or 'false', it had better be 0 or 1.
1393       if (!llvm::to_integer(option, real_value))
1394         real_value = 3;
1395       if (real_value != 0 && real_value != 1)
1396         okay = false;
1397     }
1398 
1399     return okay;
1400   }
1401 
1402   void PrintSignalHeader(Stream &str) {
1403     str.Printf("NAME         PASS   STOP   NOTIFY\n");
1404     str.Printf("===========  =====  =====  ======\n");
1405   }
1406 
1407   void PrintSignal(Stream &str, int32_t signo, const char *sig_name,
1408                    const UnixSignalsSP &signals_sp) {
1409     bool stop;
1410     bool suppress;
1411     bool notify;
1412 
1413     str.Printf("%-11s  ", sig_name);
1414     if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
1415       bool pass = !suppress;
1416       str.Printf("%s  %s  %s", (pass ? "true " : "false"),
1417                  (stop ? "true " : "false"), (notify ? "true " : "false"));
1418     }
1419     str.Printf("\n");
1420   }
1421 
1422   void PrintSignalInformation(Stream &str, Args &signal_args,
1423                               int num_valid_signals,
1424                               const UnixSignalsSP &signals_sp) {
1425     PrintSignalHeader(str);
1426 
1427     if (num_valid_signals > 0) {
1428       size_t num_args = signal_args.GetArgumentCount();
1429       for (size_t i = 0; i < num_args; ++i) {
1430         int32_t signo = signals_sp->GetSignalNumberFromName(
1431             signal_args.GetArgumentAtIndex(i));
1432         if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1433           PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1434                       signals_sp);
1435       }
1436     } else // Print info for ALL signals
1437     {
1438       int32_t signo = signals_sp->GetFirstSignalNumber();
1439       while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1440         PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo),
1441                     signals_sp);
1442         signo = signals_sp->GetNextSignalNumber(signo);
1443       }
1444     }
1445   }
1446 
1447 protected:
1448   bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
1449     Target *target_sp = &GetSelectedTarget();
1450 
1451     ProcessSP process_sp = target_sp->GetProcessSP();
1452 
1453     if (!process_sp) {
1454       result.AppendError("No current process; cannot handle signals until you "
1455                          "have a valid process.\n");
1456       return false;
1457     }
1458 
1459     int stop_action = -1;   // -1 means leave the current setting alone
1460     int pass_action = -1;   // -1 means leave the current setting alone
1461     int notify_action = -1; // -1 means leave the current setting alone
1462 
1463     if (!m_options.stop.empty() &&
1464         !VerifyCommandOptionValue(m_options.stop, stop_action)) {
1465       result.AppendError("Invalid argument for command option --stop; must be "
1466                          "true or false.\n");
1467       return false;
1468     }
1469 
1470     if (!m_options.notify.empty() &&
1471         !VerifyCommandOptionValue(m_options.notify, notify_action)) {
1472       result.AppendError("Invalid argument for command option --notify; must "
1473                          "be true or false.\n");
1474       return false;
1475     }
1476 
1477     if (!m_options.pass.empty() &&
1478         !VerifyCommandOptionValue(m_options.pass, pass_action)) {
1479       result.AppendError("Invalid argument for command option --pass; must be "
1480                          "true or false.\n");
1481       return false;
1482     }
1483 
1484     size_t num_args = signal_args.GetArgumentCount();
1485     UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
1486     int num_signals_set = 0;
1487 
1488     if (num_args > 0) {
1489       for (const auto &arg : signal_args) {
1490         int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1491         if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1492           // Casting the actions as bools here should be okay, because
1493           // VerifyCommandOptionValue guarantees the value is either 0 or 1.
1494           if (stop_action != -1)
1495             signals_sp->SetShouldStop(signo, stop_action);
1496           if (pass_action != -1) {
1497             bool suppress = !pass_action;
1498             signals_sp->SetShouldSuppress(signo, suppress);
1499           }
1500           if (notify_action != -1)
1501             signals_sp->SetShouldNotify(signo, notify_action);
1502           ++num_signals_set;
1503         } else {
1504           result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1505                                        arg.c_str());
1506         }
1507       }
1508     } else {
1509       // No signal specified, if any command options were specified, update ALL
1510       // signals.
1511       if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) {
1512         if (m_interpreter.Confirm(
1513                 "Do you really want to update all the signals?", false)) {
1514           int32_t signo = signals_sp->GetFirstSignalNumber();
1515           while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1516             if (notify_action != -1)
1517               signals_sp->SetShouldNotify(signo, notify_action);
1518             if (stop_action != -1)
1519               signals_sp->SetShouldStop(signo, stop_action);
1520             if (pass_action != -1) {
1521               bool suppress = !pass_action;
1522               signals_sp->SetShouldSuppress(signo, suppress);
1523             }
1524             signo = signals_sp->GetNextSignalNumber(signo);
1525           }
1526         }
1527       }
1528     }
1529 
1530     PrintSignalInformation(result.GetOutputStream(), signal_args,
1531                            num_signals_set, signals_sp);
1532 
1533     if (num_signals_set > 0)
1534       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1535     else
1536       result.SetStatus(eReturnStatusFailed);
1537 
1538     return result.Succeeded();
1539   }
1540 
1541   CommandOptions m_options;
1542 };
1543 
1544 // Next are the subcommands of CommandObjectMultiwordProcessTrace
1545 
1546 // CommandObjectProcessTraceStart
1547 class CommandObjectProcessTraceStart : public CommandObjectTraceProxy {
1548 public:
1549   CommandObjectProcessTraceStart(CommandInterpreter &interpreter)
1550       : CommandObjectTraceProxy(
1551             /*live_debug_session_only*/ true, interpreter,
1552             "process trace start",
1553             "Start tracing this process with the corresponding trace "
1554             "plug-in.",
1555             "process trace start [<trace-options>]") {}
1556 
1557 protected:
1558   lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
1559     return trace.GetProcessTraceStartCommand(m_interpreter);
1560   }
1561 };
1562 
1563 // CommandObjectProcessTraceStop
1564 class CommandObjectProcessTraceStop : public CommandObjectParsed {
1565 public:
1566   CommandObjectProcessTraceStop(CommandInterpreter &interpreter)
1567       : CommandObjectParsed(interpreter, "process trace stop",
1568                             "Stop tracing this process. This does not affect "
1569                             "traces started with the "
1570                             "\"thread trace start\" command.",
1571                             "process trace stop",
1572                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1573                                 eCommandProcessMustBeLaunched |
1574                                 eCommandProcessMustBePaused |
1575                                 eCommandProcessMustBeTraced) {}
1576 
1577   ~CommandObjectProcessTraceStop() override = default;
1578 
1579   bool DoExecute(Args &command, CommandReturnObject &result) override {
1580     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1581 
1582     TraceSP trace_sp = process_sp->GetTarget().GetTrace();
1583 
1584     if (llvm::Error err = trace_sp->Stop())
1585       result.SetError(toString(std::move(err)));
1586     else
1587       result.SetStatus(eReturnStatusSuccessFinishResult);
1588 
1589     return result.Succeeded();
1590   }
1591 };
1592 
1593 // CommandObjectMultiwordProcessTrace
1594 class CommandObjectMultiwordProcessTrace : public CommandObjectMultiword {
1595 public:
1596   CommandObjectMultiwordProcessTrace(CommandInterpreter &interpreter)
1597       : CommandObjectMultiword(
1598             interpreter, "trace", "Commands for tracing the current process.",
1599             "process trace <subcommand> [<subcommand objects>]") {
1600     LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart(
1601                                 interpreter)));
1602     LoadSubCommand("stop", CommandObjectSP(
1603                                new CommandObjectProcessTraceStop(interpreter)));
1604   }
1605 
1606   ~CommandObjectMultiwordProcessTrace() override = default;
1607 };
1608 
1609 // CommandObjectMultiwordProcess
1610 
1611 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1612     CommandInterpreter &interpreter)
1613     : CommandObjectMultiword(
1614           interpreter, "process",
1615           "Commands for interacting with processes on the current platform.",
1616           "process <subcommand> [<subcommand-options>]") {
1617   LoadSubCommand("attach",
1618                  CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1619   LoadSubCommand("launch",
1620                  CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1621   LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1622                                  interpreter)));
1623   LoadSubCommand("connect",
1624                  CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1625   LoadSubCommand("detach",
1626                  CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1627   LoadSubCommand("load",
1628                  CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1629   LoadSubCommand("unload",
1630                  CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1631   LoadSubCommand("signal",
1632                  CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1633   LoadSubCommand("handle",
1634                  CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1635   LoadSubCommand("status",
1636                  CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1637   LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1638                                   interpreter)));
1639   LoadSubCommand("kill",
1640                  CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1641   LoadSubCommand("plugin",
1642                  CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1643   LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1644                                   interpreter)));
1645   LoadSubCommand(
1646       "trace",
1647       CommandObjectSP(new CommandObjectMultiwordProcessTrace(interpreter)));
1648 }
1649 
1650 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1651