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