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