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