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