xref: /freebsd/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 "CommandObjectBreakpoint.h"
11 #include "CommandObjectTrace.h"
12 #include "CommandOptionsProcessAttach.h"
13 #include "CommandOptionsProcessLaunch.h"
14 #include "lldb/Breakpoint/Breakpoint.h"
15 #include "lldb/Breakpoint/BreakpointIDList.h"
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Breakpoint/BreakpointName.h"
18 #include "lldb/Breakpoint/BreakpointSite.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Host/OptionParser.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
24 #include "lldb/Interpreter/CommandReturnObject.h"
25 #include "lldb/Interpreter/OptionArgParser.h"
26 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
27 #include "lldb/Interpreter/Options.h"
28 #include "lldb/Symbol/SaveCoreOptions.h"
29 #include "lldb/Target/Platform.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/StopInfo.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Target/UnixSignals.h"
35 #include "lldb/Utility/Args.h"
36 #include "lldb/Utility/ScriptedMetadata.h"
37 #include "lldb/Utility/State.h"
38 #include "llvm/Support/FormatAdapters.h"
39 
40 #include "llvm/ADT/ScopeExit.h"
41 
42 #include <bitset>
43 #include <optional>
44 
45 using namespace lldb;
46 using namespace lldb_private;
47 
48 class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
49 public:
CommandObjectProcessLaunchOrAttach(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags,const char * new_process_action)50   CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
51                                      const char *name, const char *help,
52                                      const char *syntax, uint32_t flags,
53                                      const char *new_process_action)
54       : CommandObjectParsed(interpreter, name, help, syntax, flags),
55         m_new_process_action(new_process_action) {}
56 
57   ~CommandObjectProcessLaunchOrAttach() override = default;
58 
59 protected:
StopProcessIfNecessary(Process * process,StateType & state,CommandReturnObject & result)60   bool StopProcessIfNecessary(Process *process, StateType &state,
61                               CommandReturnObject &result) {
62     state = eStateInvalid;
63     if (process) {
64       state = process->GetState();
65 
66       if (process->IsAlive() && state != eStateConnected) {
67         std::string message;
68         if (process->GetState() == eStateAttaching)
69           message =
70               llvm::formatv("There is a pending attach, abort it and {0}?",
71                             m_new_process_action);
72         else if (process->GetShouldDetach())
73           message = llvm::formatv(
74               "There is a running process, detach from it and {0}?",
75               m_new_process_action);
76         else
77           message =
78               llvm::formatv("There is a running process, kill it and {0}?",
79                             m_new_process_action);
80 
81         if (!m_interpreter.Confirm(message, true)) {
82           result.SetStatus(eReturnStatusFailed);
83           return false;
84         } else {
85           if (process->GetShouldDetach()) {
86             bool keep_stopped = false;
87             Status detach_error(process->Detach(keep_stopped));
88             if (detach_error.Success()) {
89               result.SetStatus(eReturnStatusSuccessFinishResult);
90               process = nullptr;
91             } else {
92               result.AppendErrorWithFormat(
93                   "Failed to detach from process: %s\n",
94                   detach_error.AsCString());
95             }
96           } else {
97             Status destroy_error(process->Destroy(false));
98             if (destroy_error.Success()) {
99               result.SetStatus(eReturnStatusSuccessFinishResult);
100               process = nullptr;
101             } else {
102               result.AppendErrorWithFormat("Failed to kill process: %s\n",
103                                            destroy_error.AsCString());
104             }
105           }
106         }
107       }
108     }
109     return result.Succeeded();
110   }
111 
112   std::string m_new_process_action;
113 };
114 
115 // CommandObjectProcessLaunch
116 #pragma mark CommandObjectProcessLaunch
117 class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
118 public:
CommandObjectProcessLaunch(CommandInterpreter & interpreter)119   CommandObjectProcessLaunch(CommandInterpreter &interpreter)
120       : CommandObjectProcessLaunchOrAttach(
121             interpreter, "process launch",
122             "Launch the executable in the debugger. If no run-args are "
123             "specified, the arguments from target.run-args are used.",
124             nullptr, eCommandRequiresTarget, "restart"),
125 
126         m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
127     m_all_options.Append(&m_options);
128     m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
129                          LLDB_OPT_SET_ALL);
130     m_all_options.Finalize();
131 
132     AddSimpleArgumentList(eArgTypeRunArgs, eArgRepeatOptional);
133   }
134 
135   ~CommandObjectProcessLaunch() override = default;
136 
GetOptions()137   Options *GetOptions() override { return &m_all_options; }
138 
GetRepeatCommand(Args & current_command_args,uint32_t index)139   std::optional<std::string> GetRepeatCommand(Args &current_command_args,
140                                               uint32_t index) override {
141     // No repeat for "process launch"...
142     return std::string("");
143   }
144 
145 protected:
DoExecute(Args & launch_args,CommandReturnObject & result)146   void DoExecute(Args &launch_args, CommandReturnObject &result) override {
147     Debugger &debugger = GetDebugger();
148     Target *target = debugger.GetSelectedTarget().get();
149     // If our listener is nullptr, users aren't allows to launch
150     ModuleSP exe_module_sp = target->GetExecutableModule();
151 
152     // If the target already has an executable module, then use that.  If it
153     // doesn't then someone must be trying to launch using a path that will
154     // make sense to the remote stub, but doesn't exist on the local host.
155     // In that case use the ExecutableFile that was set in the target's
156     // ProcessLaunchInfo.
157     if (exe_module_sp == nullptr && !target->GetProcessLaunchInfo().GetExecutableFile()) {
158       result.AppendError("no file in target, create a debug target using the "
159                          "'target create' command");
160       return;
161     }
162 
163     StateType state = eStateInvalid;
164 
165     if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
166       return;
167 
168     // Determine whether we will disable ASLR or leave it in the default state
169     // (i.e. enabled if the platform supports it). First check if the process
170     // launch options explicitly turn on/off
171     // disabling ASLR.  If so, use that setting;
172     // otherwise, use the 'settings target.disable-aslr' setting.
173     bool disable_aslr = false;
174     if (m_options.disable_aslr != eLazyBoolCalculate) {
175       // The user specified an explicit setting on the process launch line.
176       // Use it.
177       disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
178     } else {
179       // The user did not explicitly specify whether to disable ASLR.  Fall
180       // back to the target.disable-aslr setting.
181       disable_aslr = target->GetDisableASLR();
182     }
183 
184     if (!m_class_options.GetName().empty()) {
185       m_options.launch_info.SetProcessPluginName("ScriptedProcess");
186       ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
187           m_class_options.GetName(), m_class_options.GetStructuredData());
188       m_options.launch_info.SetScriptedMetadata(metadata_sp);
189       target->SetProcessLaunchInfo(m_options.launch_info);
190     }
191 
192     if (disable_aslr)
193       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
194     else
195       m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
196 
197     if (target->GetInheritTCC())
198       m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
199 
200     if (target->GetDetachOnError())
201       m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
202 
203     if (target->GetDisableSTDIO())
204       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
205 
206     if (!m_options.launch_info.GetWorkingDirectory()) {
207       if (llvm::StringRef wd = target->GetLaunchWorkingDirectory();
208           !wd.empty()) {
209         m_options.launch_info.SetWorkingDirectory(FileSpec(wd));
210       }
211     }
212 
213     // Merge the launch info environment with the target environment.
214     Environment target_env = target->GetEnvironment();
215     m_options.launch_info.GetEnvironment().insert(target_env.begin(),
216                                                   target_env.end());
217 
218     llvm::StringRef target_settings_argv0 = target->GetArg0();
219 
220     if (!target_settings_argv0.empty()) {
221       m_options.launch_info.GetArguments().AppendArgument(
222           target_settings_argv0);
223       if (exe_module_sp)
224         m_options.launch_info.SetExecutableFile(
225             exe_module_sp->GetPlatformFileSpec(), false);
226       else
227         m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), false);
228     } else {
229       if (exe_module_sp)
230         m_options.launch_info.SetExecutableFile(
231             exe_module_sp->GetPlatformFileSpec(), true);
232       else
233         m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), true);
234     }
235 
236     if (launch_args.GetArgumentCount() == 0) {
237       m_options.launch_info.GetArguments().AppendArguments(
238           target->GetProcessLaunchInfo().GetArguments());
239     } else {
240       m_options.launch_info.GetArguments().AppendArguments(launch_args);
241       // Save the arguments for subsequent runs in the current target.
242       target->SetRunArguments(launch_args);
243     }
244 
245     StreamString stream;
246     Status error = target->Launch(m_options.launch_info, &stream);
247 
248     if (error.Success()) {
249       ProcessSP process_sp(target->GetProcessSP());
250       if (process_sp) {
251         // There is a race condition where this thread will return up the call
252         // stack to the main command handler and show an (lldb) prompt before
253         // HandlePrivateEvent (from PrivateStateThread) has a chance to call
254         // PushProcessIOHandler().
255         process_sp->SyncIOHandler(0, std::chrono::seconds(2));
256 
257         // If we didn't have a local executable, then we wouldn't have had an
258         // executable module before launch.
259         if (!exe_module_sp)
260           exe_module_sp = target->GetExecutableModule();
261         if (!exe_module_sp) {
262           result.AppendWarning("Could not get executable module after launch.");
263         } else {
264 
265           const char *archname =
266               exe_module_sp->GetArchitecture().GetArchitectureName();
267           result.AppendMessageWithFormat(
268               "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
269               exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
270         }
271         result.SetStatus(eReturnStatusSuccessFinishResult);
272         // This message will refer to an event that happened after the process
273         // launched.
274         llvm::StringRef data = stream.GetString();
275         if (!data.empty())
276           result.AppendMessage(data);
277         result.SetDidChangeProcessState(true);
278       } else {
279         result.AppendError(
280             "no error returned from Target::Launch, and target has no process");
281       }
282     } else {
283       result.AppendError(error.AsCString());
284     }
285   }
286 
287   CommandOptionsProcessLaunch m_options;
288   OptionGroupPythonClassWithDict m_class_options;
289   OptionGroupOptions m_all_options;
290 };
291 
292 #define LLDB_OPTIONS_process_attach
293 #include "CommandOptions.inc"
294 
295 #pragma mark CommandObjectProcessAttach
296 class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
297 public:
CommandObjectProcessAttach(CommandInterpreter & interpreter)298   CommandObjectProcessAttach(CommandInterpreter &interpreter)
299       : CommandObjectProcessLaunchOrAttach(
300             interpreter, "process attach", "Attach to a process.",
301             "process attach <cmd-options>", 0, "attach"),
302         m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
303     m_all_options.Append(&m_options);
304     m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
305                          LLDB_OPT_SET_ALL);
306     m_all_options.Finalize();
307   }
308 
309   ~CommandObjectProcessAttach() override = default;
310 
GetOptions()311   Options *GetOptions() override { return &m_all_options; }
312 
313 protected:
DoExecute(Args & command,CommandReturnObject & result)314   void DoExecute(Args &command, CommandReturnObject &result) override {
315     PlatformSP platform_sp(
316         GetDebugger().GetPlatformList().GetSelectedPlatform());
317 
318     Target *target = GetDebugger().GetSelectedTarget().get();
319     // N.B. The attach should be synchronous.  It doesn't help much to get the
320     // prompt back between initiating the attach and the target actually
321     // stopping.  So even if the interpreter is set to be asynchronous, we wait
322     // for the stop ourselves here.
323 
324     StateType state = eStateInvalid;
325     Process *process = m_exe_ctx.GetProcessPtr();
326 
327     if (!StopProcessIfNecessary(process, state, result))
328       return;
329 
330     if (target == nullptr) {
331       // If there isn't a current target create one.
332       TargetSP new_target_sp;
333       Status error;
334 
335       error = GetDebugger().GetTargetList().CreateTarget(
336           GetDebugger(), "", "", eLoadDependentsNo,
337           nullptr, // No platform options
338           new_target_sp);
339       target = new_target_sp.get();
340       if (target == nullptr || error.Fail()) {
341         result.AppendError(error.AsCString("Error creating target"));
342         return;
343       }
344     }
345 
346     if (!m_class_options.GetName().empty()) {
347       m_options.attach_info.SetProcessPluginName("ScriptedProcess");
348       ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
349           m_class_options.GetName(), m_class_options.GetStructuredData());
350       m_options.attach_info.SetScriptedMetadata(metadata_sp);
351     }
352 
353     // Record the old executable module, we want to issue a warning if the
354     // process of attaching changed the current executable (like somebody said
355     // "file foo" then attached to a PID whose executable was bar.)
356 
357     ModuleSP old_exec_module_sp = target->GetExecutableModule();
358     ArchSpec old_arch_spec = target->GetArchitecture();
359 
360     StreamString stream;
361     ProcessSP process_sp;
362     const auto error = target->Attach(m_options.attach_info, &stream);
363     if (error.Success()) {
364       process_sp = target->GetProcessSP();
365       if (process_sp) {
366         result.AppendMessage(stream.GetString());
367         result.SetStatus(eReturnStatusSuccessFinishNoResult);
368         result.SetDidChangeProcessState(true);
369       } else {
370         result.AppendError(
371             "no error returned from Target::Attach, and target has no process");
372       }
373     } else {
374       result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
375     }
376 
377     if (!result.Succeeded())
378       return;
379 
380     // Okay, we're done.  Last step is to warn if the executable module has
381     // changed:
382     ModuleSP new_exec_module_sp(target->GetExecutableModule());
383     if (!old_exec_module_sp) {
384       // We might not have a module if we attached to a raw pid...
385       if (new_exec_module_sp) {
386         result.AppendMessageWithFormat(
387             "Executable binary set to \"%s\".\n",
388             new_exec_module_sp->GetFileSpec().GetPath().c_str());
389       }
390     } else if (!new_exec_module_sp) {
391       result.AppendWarningWithFormat("No executable binary.");
392     } else if (old_exec_module_sp->GetFileSpec() !=
393                new_exec_module_sp->GetFileSpec()) {
394 
395       result.AppendWarningWithFormat(
396           "Executable binary changed from \"%s\" to \"%s\".\n",
397           old_exec_module_sp->GetFileSpec().GetPath().c_str(),
398           new_exec_module_sp->GetFileSpec().GetPath().c_str());
399     }
400 
401     if (!old_arch_spec.IsValid()) {
402       result.AppendMessageWithFormat(
403           "Architecture set to: %s.\n",
404           target->GetArchitecture().GetTriple().getTriple().c_str());
405     } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
406       result.AppendWarningWithFormat(
407           "Architecture changed from %s to %s.\n",
408           old_arch_spec.GetTriple().getTriple().c_str(),
409           target->GetArchitecture().GetTriple().getTriple().c_str());
410     }
411 
412     // This supports the use-case scenario of immediately continuing the
413     // process once attached.
414     if (m_options.attach_info.GetContinueOnceAttached()) {
415       // We have made a process but haven't told the interpreter about it yet,
416       // so CheckRequirements will fail for "process continue".  Set the override
417       // here:
418       ExecutionContext exe_ctx(process_sp);
419       m_interpreter.HandleCommand("process continue", eLazyBoolNo, exe_ctx, result);
420     }
421   }
422 
423   CommandOptionsProcessAttach m_options;
424   OptionGroupPythonClassWithDict m_class_options;
425   OptionGroupOptions m_all_options;
426 };
427 
428 // CommandObjectProcessContinue
429 
430 #define LLDB_OPTIONS_process_continue
431 #include "CommandOptions.inc"
432 
433 #pragma mark CommandObjectProcessContinue
434 
435 class CommandObjectProcessContinue : public CommandObjectParsed {
436 public:
CommandObjectProcessContinue(CommandInterpreter & interpreter)437   CommandObjectProcessContinue(CommandInterpreter &interpreter)
438       : CommandObjectParsed(
439             interpreter, "process continue",
440             "Continue execution of all threads in the current process.",
441             "process continue",
442             eCommandRequiresProcess | eCommandTryTargetAPILock |
443                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
444 
445   ~CommandObjectProcessContinue() override = default;
446 
447 protected:
448   class CommandOptions : public Options {
449   public:
CommandOptions()450     CommandOptions() {
451       // Keep default values of all options in one place: OptionParsingStarting
452       // ()
453       OptionParsingStarting(nullptr);
454     }
455 
456     ~CommandOptions() override = default;
457 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * exe_ctx)458     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
459                           ExecutionContext *exe_ctx) override {
460       Status error;
461       const int short_option = m_getopt_table[option_idx].val;
462       switch (short_option) {
463       case 'i':
464         if (option_arg.getAsInteger(0, m_ignore))
465           error = Status::FromErrorStringWithFormat(
466               "invalid value for ignore option: \"%s\", should be a number.",
467               option_arg.str().c_str());
468         break;
469       case 'b':
470         m_run_to_bkpt_args.AppendArgument(option_arg);
471         m_any_bkpts_specified = true;
472         break;
473       case 'F':
474         m_base_direction = lldb::RunDirection::eRunForward;
475         break;
476       case 'R':
477         m_base_direction = lldb::RunDirection::eRunReverse;
478         break;
479       default:
480         llvm_unreachable("Unimplemented option");
481       }
482       return error;
483     }
484 
OptionParsingStarting(ExecutionContext * execution_context)485     void OptionParsingStarting(ExecutionContext *execution_context) override {
486       m_ignore = 0;
487       m_run_to_bkpt_args.Clear();
488       m_any_bkpts_specified = false;
489       m_base_direction = std::nullopt;
490     }
491 
GetDefinitions()492     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
493       return llvm::ArrayRef(g_process_continue_options);
494     }
495 
496     uint32_t m_ignore = 0;
497     Args m_run_to_bkpt_args;
498     bool m_any_bkpts_specified = false;
499     std::optional<lldb::RunDirection> m_base_direction;
500   };
501 
DoExecute(Args & command,CommandReturnObject & result)502   void DoExecute(Args &command, CommandReturnObject &result) override {
503     Process *process = m_exe_ctx.GetProcessPtr();
504     bool synchronous_execution = m_interpreter.GetSynchronous();
505     StateType state = process->GetState();
506     if (state == eStateStopped) {
507       if (m_options.m_ignore > 0) {
508         ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
509         if (sel_thread_sp) {
510           StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
511           if (stop_info_sp &&
512               stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
513             lldb::break_id_t bp_site_id =
514                 (lldb::break_id_t)stop_info_sp->GetValue();
515             BreakpointSiteSP bp_site_sp(
516                 process->GetBreakpointSiteList().FindByID(bp_site_id));
517             if (bp_site_sp) {
518               const size_t num_owners = bp_site_sp->GetNumberOfConstituents();
519               for (size_t i = 0; i < num_owners; i++) {
520                 Breakpoint &bp_ref =
521                     bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint();
522                 if (!bp_ref.IsInternal()) {
523                   bp_ref.SetIgnoreCount(m_options.m_ignore);
524                 }
525               }
526             }
527           }
528         }
529       }
530 
531       Target &target = GetTarget();
532       BreakpointIDList run_to_bkpt_ids;
533       // Don't pass an empty run_to_breakpoint list, as Verify will look for the
534       // default breakpoint.
535       if (m_options.m_run_to_bkpt_args.GetArgumentCount() > 0)
536         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
537             m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids,
538             BreakpointName::Permissions::disablePerm);
539       if (!result.Succeeded()) {
540         return;
541       }
542       result.Clear();
543       if (m_options.m_any_bkpts_specified && run_to_bkpt_ids.GetSize() == 0) {
544         result.AppendError("continue-to breakpoints did not specify any actual "
545                            "breakpoints or locations");
546         return;
547       }
548 
549       // First figure out which breakpoints & locations were specified by the
550       // user:
551       size_t num_run_to_bkpt_ids = run_to_bkpt_ids.GetSize();
552       std::vector<break_id_t> bkpts_disabled;
553       std::vector<BreakpointID> locs_disabled;
554       if (num_run_to_bkpt_ids != 0) {
555         // Go through the ID's specified, and separate the breakpoints from are
556         // the breakpoint.location specifications since the latter require
557         // special handling.  We also figure out whether there's at least one
558         // specifier in the set that is enabled.
559         BreakpointList &bkpt_list = target.GetBreakpointList();
560         std::unordered_set<break_id_t> bkpts_seen;
561         std::unordered_set<break_id_t> bkpts_with_locs_seen;
562         BreakpointIDList with_locs;
563         bool any_enabled = false;
564 
565         for (size_t idx = 0; idx < num_run_to_bkpt_ids; idx++) {
566           BreakpointID bkpt_id = run_to_bkpt_ids.GetBreakpointIDAtIndex(idx);
567           break_id_t bp_id = bkpt_id.GetBreakpointID();
568           break_id_t loc_id = bkpt_id.GetLocationID();
569           BreakpointSP bp_sp
570               = bkpt_list.FindBreakpointByID(bp_id);
571           // Note, VerifyBreakpointOrLocationIDs checks for existence, so we
572           // don't need to do it again here.
573           if (bp_sp->IsEnabled()) {
574             if (loc_id == LLDB_INVALID_BREAK_ID) {
575               // A breakpoint (without location) was specified.  Make sure that
576               // at least one of the locations is enabled.
577               size_t num_locations = bp_sp->GetNumLocations();
578               for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) {
579                 BreakpointLocationSP loc_sp
580                     = bp_sp->GetLocationAtIndex(loc_idx);
581                 if (loc_sp->IsEnabled()) {
582                   any_enabled = true;
583                   break;
584                 }
585               }
586             } else {
587               // A location was specified, check if it was enabled:
588               BreakpointLocationSP loc_sp = bp_sp->FindLocationByID(loc_id);
589               if (loc_sp->IsEnabled())
590                 any_enabled = true;
591             }
592 
593             // Then sort the bp & bp.loc entries for later use:
594             if (bkpt_id.GetLocationID() == LLDB_INVALID_BREAK_ID)
595               bkpts_seen.insert(bkpt_id.GetBreakpointID());
596             else {
597               bkpts_with_locs_seen.insert(bkpt_id.GetBreakpointID());
598               with_locs.AddBreakpointID(bkpt_id);
599             }
600           }
601         }
602         // Do all the error checking here so once we start disabling we don't
603         // have to back out half-way through.
604 
605         // Make sure at least one of the specified breakpoints is enabled.
606         if (!any_enabled) {
607           result.AppendError("at least one of the continue-to breakpoints must "
608                              "be enabled.");
609           return;
610         }
611 
612         // Also, if you specify BOTH a breakpoint and one of it's locations,
613         // we flag that as an error, since it won't do what you expect, the
614         // breakpoint directive will mean "run to all locations", which is not
615         // what the location directive means...
616         for (break_id_t bp_id : bkpts_with_locs_seen) {
617           if (bkpts_seen.count(bp_id)) {
618             result.AppendErrorWithFormatv("can't specify both a breakpoint and "
619                                "one of its locations: {0}", bp_id);
620           }
621         }
622 
623         // Now go through the breakpoints in the target, disabling all the ones
624         // that the user didn't mention:
625         for (BreakpointSP bp_sp : bkpt_list.Breakpoints()) {
626           break_id_t bp_id = bp_sp->GetID();
627           // Handle the case where no locations were specified.  Note we don't
628           // have to worry about the case where a breakpoint and one of its
629           // locations are both in the lists, we've already disallowed that.
630           if (!bkpts_with_locs_seen.count(bp_id)) {
631             if (!bkpts_seen.count(bp_id) && bp_sp->IsEnabled()) {
632               bkpts_disabled.push_back(bp_id);
633               bp_sp->SetEnabled(false);
634             }
635             continue;
636           }
637           // Next, handle the case where a location was specified:
638           // Run through all the locations of this breakpoint and disable
639           // the ones that aren't on our "with locations" BreakpointID list:
640           size_t num_locations = bp_sp->GetNumLocations();
641           BreakpointID tmp_id(bp_id, LLDB_INVALID_BREAK_ID);
642           for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) {
643             BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx);
644             tmp_id.SetBreakpointLocationID(loc_idx);
645             if (!with_locs.Contains(tmp_id) && loc_sp->IsEnabled()) {
646               if (llvm::Error error = loc_sp->SetEnabled(false))
647                 result.AppendErrorWithFormatv(
648                     "failed to disable breakpoint location: {0}",
649                     llvm::fmt_consume(std::move(error)));
650               else
651                 locs_disabled.push_back(tmp_id);
652             }
653           }
654         }
655       }
656 
657       { // Scope for thread list mutex:
658         std::lock_guard<std::recursive_mutex> guard(
659             process->GetThreadList().GetMutex());
660         const uint32_t num_threads = process->GetThreadList().GetSize();
661 
662         // Set the actions that the threads should each take when resuming
663         for (uint32_t idx = 0; idx < num_threads; ++idx) {
664           const bool override_suspend = false;
665           process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
666               eStateRunning, override_suspend);
667         }
668       }
669 
670       if (m_options.m_base_direction.has_value())
671         process->SetBaseDirection(*m_options.m_base_direction);
672 
673       const uint32_t iohandler_id = process->GetIOHandlerID();
674 
675       StreamString stream;
676       Status error;
677       // For now we can only do -b with synchronous:
678       bool old_sync = GetDebugger().GetAsyncExecution();
679 
680       if (run_to_bkpt_ids.GetSize() != 0) {
681         GetDebugger().SetAsyncExecution(false);
682         synchronous_execution = true;
683       }
684       if (synchronous_execution)
685         error = process->ResumeSynchronous(&stream);
686       else
687         error = process->Resume();
688 
689       if (run_to_bkpt_ids.GetSize() != 0) {
690         GetDebugger().SetAsyncExecution(old_sync);
691       }
692 
693       // Now re-enable the breakpoints we disabled:
694       BreakpointList &bkpt_list = target.GetBreakpointList();
695       for (break_id_t bp_id : bkpts_disabled) {
696         BreakpointSP bp_sp = bkpt_list.FindBreakpointByID(bp_id);
697         if (bp_sp)
698           bp_sp->SetEnabled(true);
699       }
700       for (const BreakpointID &bkpt_id : locs_disabled) {
701         BreakpointSP bp_sp
702             = bkpt_list.FindBreakpointByID(bkpt_id.GetBreakpointID());
703         if (bp_sp) {
704           BreakpointLocationSP loc_sp
705               = bp_sp->FindLocationByID(bkpt_id.GetLocationID());
706           if (loc_sp) {
707             if (llvm::Error error = loc_sp->SetEnabled(true))
708               result.AppendErrorWithFormatv(
709                   "failed to enable breakpoint location: {0}",
710                   llvm::fmt_consume(std::move(error)));
711           }
712         }
713       }
714 
715       if (error.Success()) {
716         // There is a race condition where this thread will return up the call
717         // stack to the main command handler and show an (lldb) prompt before
718         // HandlePrivateEvent (from PrivateStateThread) has a chance to call
719         // PushProcessIOHandler().
720         process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
721 
722         result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
723                                        process->GetID());
724         if (synchronous_execution) {
725           // If any state changed events had anything to say, add that to the
726           // result
727           result.AppendMessage(stream.GetString());
728 
729           result.SetDidChangeProcessState(true);
730           result.SetStatus(eReturnStatusSuccessFinishNoResult);
731         } else {
732           result.SetStatus(eReturnStatusSuccessContinuingNoResult);
733         }
734       } else {
735         result.AppendErrorWithFormat("Failed to resume process: %s.\n",
736                                      error.AsCString());
737       }
738     } else {
739       result.AppendErrorWithFormat(
740           "Process cannot be continued from its current state (%s).\n",
741           StateAsCString(state));
742     }
743   }
744 
GetOptions()745   Options *GetOptions() override { return &m_options; }
746 
747   CommandOptions m_options;
748 };
749 
750 // CommandObjectProcessDetach
751 #define LLDB_OPTIONS_process_detach
752 #include "CommandOptions.inc"
753 
754 #pragma mark CommandObjectProcessDetach
755 
756 class CommandObjectProcessDetach : public CommandObjectParsed {
757 public:
758   class CommandOptions : public Options {
759   public:
CommandOptions()760     CommandOptions() { OptionParsingStarting(nullptr); }
761 
762     ~CommandOptions() override = default;
763 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)764     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
765                           ExecutionContext *execution_context) override {
766       Status error;
767       const int short_option = m_getopt_table[option_idx].val;
768 
769       switch (short_option) {
770       case 's':
771         bool tmp_result;
772         bool success;
773         tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success);
774         if (!success)
775           error = Status::FromErrorStringWithFormat(
776               "invalid boolean option: \"%s\"", option_arg.str().c_str());
777         else {
778           if (tmp_result)
779             m_keep_stopped = eLazyBoolYes;
780           else
781             m_keep_stopped = eLazyBoolNo;
782         }
783         break;
784       default:
785         llvm_unreachable("Unimplemented option");
786       }
787       return error;
788     }
789 
OptionParsingStarting(ExecutionContext * execution_context)790     void OptionParsingStarting(ExecutionContext *execution_context) override {
791       m_keep_stopped = eLazyBoolCalculate;
792     }
793 
GetDefinitions()794     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
795       return llvm::ArrayRef(g_process_detach_options);
796     }
797 
798     // Instance variables to hold the values for command options.
799     LazyBool m_keep_stopped;
800   };
801 
CommandObjectProcessDetach(CommandInterpreter & interpreter)802   CommandObjectProcessDetach(CommandInterpreter &interpreter)
803       : CommandObjectParsed(interpreter, "process detach",
804                             "Detach from the current target process.",
805                             "process detach",
806                             eCommandRequiresProcess | eCommandTryTargetAPILock |
807                                 eCommandProcessMustBeLaunched) {}
808 
809   ~CommandObjectProcessDetach() override = default;
810 
GetOptions()811   Options *GetOptions() override { return &m_options; }
812 
813 protected:
DoExecute(Args & command,CommandReturnObject & result)814   void DoExecute(Args &command, CommandReturnObject &result) override {
815     Process *process = m_exe_ctx.GetProcessPtr();
816     // FIXME: This will be a Command Option:
817     bool keep_stopped;
818     if (m_options.m_keep_stopped == eLazyBoolCalculate) {
819       // Check the process default:
820       keep_stopped = process->GetDetachKeepsStopped();
821     } else if (m_options.m_keep_stopped == eLazyBoolYes)
822       keep_stopped = true;
823     else
824       keep_stopped = false;
825 
826     Status error(process->Detach(keep_stopped));
827     if (error.Success()) {
828       result.SetStatus(eReturnStatusSuccessFinishResult);
829     } else {
830       result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
831     }
832   }
833 
834   CommandOptions m_options;
835 };
836 
837 // CommandObjectProcessConnect
838 #define LLDB_OPTIONS_process_connect
839 #include "CommandOptions.inc"
840 
841 #pragma mark CommandObjectProcessConnect
842 
843 class CommandObjectProcessConnect : public CommandObjectParsed {
844 public:
845   class CommandOptions : public Options {
846   public:
CommandOptions()847     CommandOptions() {
848       // Keep default values of all options in one place: OptionParsingStarting
849       // ()
850       OptionParsingStarting(nullptr);
851     }
852 
853     ~CommandOptions() override = default;
854 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)855     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
856                           ExecutionContext *execution_context) override {
857       Status error;
858       const int short_option = m_getopt_table[option_idx].val;
859 
860       switch (short_option) {
861       case 'p':
862         plugin_name.assign(std::string(option_arg));
863         break;
864 
865       default:
866         llvm_unreachable("Unimplemented option");
867       }
868       return error;
869     }
870 
OptionParsingStarting(ExecutionContext * execution_context)871     void OptionParsingStarting(ExecutionContext *execution_context) override {
872       plugin_name.clear();
873     }
874 
GetDefinitions()875     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
876       return llvm::ArrayRef(g_process_connect_options);
877     }
878 
879     // Instance variables to hold the values for command options.
880 
881     std::string plugin_name;
882   };
883 
CommandObjectProcessConnect(CommandInterpreter & interpreter)884   CommandObjectProcessConnect(CommandInterpreter &interpreter)
885       : CommandObjectParsed(interpreter, "process connect",
886                             "Connect to a remote debug service.",
887                             "process connect <remote-url>", 0) {
888     AddSimpleArgumentList(eArgTypeConnectURL);
889   }
890 
891   ~CommandObjectProcessConnect() override = default;
892 
GetOptions()893   Options *GetOptions() override { return &m_options; }
894 
895 protected:
DoExecute(Args & command,CommandReturnObject & result)896   void DoExecute(Args &command, CommandReturnObject &result) override {
897     if (command.GetArgumentCount() != 1) {
898       result.AppendErrorWithFormat(
899           "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
900           m_cmd_syntax.c_str());
901       return;
902     }
903 
904     Process *process = m_exe_ctx.GetProcessPtr();
905     if (process && process->IsAlive()) {
906       result.AppendErrorWithFormat(
907           "Process %" PRIu64
908           " is currently being debugged, kill the process before connecting.\n",
909           process->GetID());
910       return;
911     }
912 
913     const char *plugin_name = nullptr;
914     if (!m_options.plugin_name.empty())
915       plugin_name = m_options.plugin_name.c_str();
916 
917     Status error;
918     Debugger &debugger = GetDebugger();
919     PlatformSP platform_sp = m_interpreter.GetPlatform(true);
920     ProcessSP process_sp =
921         debugger.GetAsyncExecution()
922             ? platform_sp->ConnectProcess(
923                   command.GetArgumentAtIndex(0), plugin_name, debugger,
924                   debugger.GetSelectedTarget().get(), error)
925             : platform_sp->ConnectProcessSynchronous(
926                   command.GetArgumentAtIndex(0), plugin_name, debugger,
927                   result.GetOutputStream(), debugger.GetSelectedTarget().get(),
928                   error);
929     if (error.Fail() || process_sp == nullptr) {
930       result.AppendError(error.AsCString("Error connecting to the process"));
931     }
932   }
933 
934   CommandOptions m_options;
935 };
936 
937 // CommandObjectProcessPlugin
938 #pragma mark CommandObjectProcessPlugin
939 
940 class CommandObjectProcessPlugin : public CommandObjectProxy {
941 public:
CommandObjectProcessPlugin(CommandInterpreter & interpreter)942   CommandObjectProcessPlugin(CommandInterpreter &interpreter)
943       : CommandObjectProxy(
944             interpreter, "process plugin",
945             "Send a custom command to the current target process plug-in.",
946             "process plugin <args>", 0) {}
947 
948   ~CommandObjectProcessPlugin() override = default;
949 
GetProxyCommandObject()950   CommandObject *GetProxyCommandObject() override {
951     Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
952     if (process)
953       return process->GetPluginCommandObject();
954     return nullptr;
955   }
956 };
957 
958 // CommandObjectProcessLoad
959 #define LLDB_OPTIONS_process_load
960 #include "CommandOptions.inc"
961 
962 #pragma mark CommandObjectProcessLoad
963 
964 class CommandObjectProcessLoad : public CommandObjectParsed {
965 public:
966   class CommandOptions : public Options {
967   public:
CommandOptions()968     CommandOptions() {
969       // Keep default values of all options in one place: OptionParsingStarting
970       // ()
971       OptionParsingStarting(nullptr);
972     }
973 
974     ~CommandOptions() override = default;
975 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)976     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
977                           ExecutionContext *execution_context) override {
978       Status error;
979       const int short_option = m_getopt_table[option_idx].val;
980       ArchSpec arch =
981           execution_context->GetProcessPtr()->GetSystemArchitecture();
982       switch (short_option) {
983       case 'i':
984         do_install = true;
985         if (!option_arg.empty())
986           install_path.SetFile(option_arg, arch.GetTriple());
987         break;
988       default:
989         llvm_unreachable("Unimplemented option");
990       }
991       return error;
992     }
993 
OptionParsingStarting(ExecutionContext * execution_context)994     void OptionParsingStarting(ExecutionContext *execution_context) override {
995       do_install = false;
996       install_path.Clear();
997     }
998 
GetDefinitions()999     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1000       return llvm::ArrayRef(g_process_load_options);
1001     }
1002 
1003     // Instance variables to hold the values for command options.
1004     bool do_install;
1005     FileSpec install_path;
1006   };
1007 
CommandObjectProcessLoad(CommandInterpreter & interpreter)1008   CommandObjectProcessLoad(CommandInterpreter &interpreter)
1009       : CommandObjectParsed(interpreter, "process load",
1010                             "Load a shared library into the current process.",
1011                             "process load <filename> [<filename> ...]",
1012                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1013                                 eCommandProcessMustBeLaunched |
1014                                 eCommandProcessMustBePaused) {
1015     AddSimpleArgumentList(eArgTypePath, eArgRepeatPlus);
1016   }
1017 
1018   ~CommandObjectProcessLoad() override = default;
1019 
1020   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1021   HandleArgumentCompletion(CompletionRequest &request,
1022                            OptionElementVector &opt_element_vector) override {
1023     if (!m_exe_ctx.HasProcessScope())
1024       return;
1025     CommandObject::HandleArgumentCompletion(request, opt_element_vector);
1026   }
1027 
GetOptions()1028   Options *GetOptions() override { return &m_options; }
1029 
1030 protected:
DoExecute(Args & command,CommandReturnObject & result)1031   void DoExecute(Args &command, CommandReturnObject &result) override {
1032     Process *process = m_exe_ctx.GetProcessPtr();
1033 
1034     for (auto &entry : command.entries()) {
1035       Status error;
1036       PlatformSP platform = process->GetTarget().GetPlatform();
1037       llvm::StringRef image_path = entry.ref();
1038       uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
1039 
1040       if (!m_options.do_install) {
1041         FileSpec image_spec(image_path);
1042         platform->ResolveRemotePath(image_spec, image_spec);
1043         image_token =
1044             platform->LoadImage(process, FileSpec(), image_spec, error);
1045       } else if (m_options.install_path) {
1046         FileSpec image_spec(image_path);
1047         FileSystem::Instance().Resolve(image_spec);
1048         platform->ResolveRemotePath(m_options.install_path,
1049                                     m_options.install_path);
1050         image_token = platform->LoadImage(process, image_spec,
1051                                           m_options.install_path, error);
1052       } else {
1053         FileSpec image_spec(image_path);
1054         FileSystem::Instance().Resolve(image_spec);
1055         image_token =
1056             platform->LoadImage(process, image_spec, FileSpec(), error);
1057       }
1058 
1059       if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
1060         result.AppendMessageWithFormat(
1061             "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
1062             image_token);
1063         result.SetStatus(eReturnStatusSuccessFinishResult);
1064       } else {
1065         result.AppendErrorWithFormat("failed to load '%s': %s",
1066                                      image_path.str().c_str(),
1067                                      error.AsCString());
1068       }
1069     }
1070   }
1071 
1072   CommandOptions m_options;
1073 };
1074 
1075 // CommandObjectProcessUnload
1076 #pragma mark CommandObjectProcessUnload
1077 
1078 class CommandObjectProcessUnload : public CommandObjectParsed {
1079 public:
CommandObjectProcessUnload(CommandInterpreter & interpreter)1080   CommandObjectProcessUnload(CommandInterpreter &interpreter)
1081       : CommandObjectParsed(
1082             interpreter, "process unload",
1083             "Unload a shared library from the current process using the index "
1084             "returned by a previous call to \"process load\".",
1085             "process unload <index>",
1086             eCommandRequiresProcess | eCommandTryTargetAPILock |
1087                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
1088     AddSimpleArgumentList(eArgTypeUnsignedInteger);
1089   }
1090 
1091   ~CommandObjectProcessUnload() override = default;
1092 
1093   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1094   HandleArgumentCompletion(CompletionRequest &request,
1095                            OptionElementVector &opt_element_vector) override {
1096 
1097     if (request.GetCursorIndex() || !m_exe_ctx.HasProcessScope())
1098       return;
1099 
1100     Process *process = m_exe_ctx.GetProcessPtr();
1101 
1102     const std::vector<lldb::addr_t> &tokens = process->GetImageTokens();
1103     const size_t token_num = tokens.size();
1104     for (size_t i = 0; i < token_num; ++i) {
1105       if (tokens[i] == LLDB_INVALID_IMAGE_TOKEN)
1106         continue;
1107       request.TryCompleteCurrentArg(std::to_string(i));
1108     }
1109   }
1110 
1111 protected:
DoExecute(Args & command,CommandReturnObject & result)1112   void DoExecute(Args &command, CommandReturnObject &result) override {
1113     Process *process = m_exe_ctx.GetProcessPtr();
1114 
1115     for (auto &entry : command.entries()) {
1116       uint32_t image_token;
1117       if (entry.ref().getAsInteger(0, image_token)) {
1118         result.AppendErrorWithFormat("invalid image index argument '%s'",
1119                                      entry.ref().str().c_str());
1120         break;
1121       } else {
1122         Status error(process->GetTarget().GetPlatform()->UnloadImage(
1123             process, image_token));
1124         if (error.Success()) {
1125           result.AppendMessageWithFormat(
1126               "Unloading shared library with index %u...ok\n", image_token);
1127           result.SetStatus(eReturnStatusSuccessFinishResult);
1128         } else {
1129           result.AppendErrorWithFormat("failed to unload image: %s",
1130                                        error.AsCString());
1131           break;
1132         }
1133       }
1134     }
1135   }
1136 };
1137 
1138 // CommandObjectProcessSignal
1139 #pragma mark CommandObjectProcessSignal
1140 
1141 class CommandObjectProcessSignal : public CommandObjectParsed {
1142 public:
CommandObjectProcessSignal(CommandInterpreter & interpreter)1143   CommandObjectProcessSignal(CommandInterpreter &interpreter)
1144       : CommandObjectParsed(
1145             interpreter, "process signal",
1146             "Send a UNIX signal to the current target process.", nullptr,
1147             eCommandRequiresProcess | eCommandTryTargetAPILock) {
1148     AddSimpleArgumentList(eArgTypeUnixSignal);
1149   }
1150 
1151   ~CommandObjectProcessSignal() override = default;
1152 
1153   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1154   HandleArgumentCompletion(CompletionRequest &request,
1155                            OptionElementVector &opt_element_vector) override {
1156     if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
1157       return;
1158 
1159     UnixSignalsSP signals = m_exe_ctx.GetProcessPtr()->GetUnixSignals();
1160     int signo = signals->GetFirstSignalNumber();
1161     while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1162       request.TryCompleteCurrentArg(signals->GetSignalAsStringRef(signo));
1163       signo = signals->GetNextSignalNumber(signo);
1164     }
1165   }
1166 
1167 protected:
DoExecute(Args & command,CommandReturnObject & result)1168   void DoExecute(Args &command, CommandReturnObject &result) override {
1169     Process *process = m_exe_ctx.GetProcessPtr();
1170 
1171     if (command.GetArgumentCount() == 1) {
1172       int signo = LLDB_INVALID_SIGNAL_NUMBER;
1173 
1174       const char *signal_name = command.GetArgumentAtIndex(0);
1175       if (::isxdigit(signal_name[0])) {
1176         if (!llvm::to_integer(signal_name, signo))
1177           signo = LLDB_INVALID_SIGNAL_NUMBER;
1178       } else
1179         signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
1180 
1181       if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
1182         result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
1183                                      command.GetArgumentAtIndex(0));
1184       } else {
1185         Status error(process->Signal(signo));
1186         if (error.Success()) {
1187           result.SetStatus(eReturnStatusSuccessFinishResult);
1188         } else {
1189           result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
1190                                        error.AsCString());
1191         }
1192       }
1193     } else {
1194       result.AppendErrorWithFormat(
1195           "'%s' takes exactly one signal number argument:\nUsage: %s\n",
1196           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1197     }
1198   }
1199 };
1200 
1201 // CommandObjectProcessInterrupt
1202 #pragma mark CommandObjectProcessInterrupt
1203 
1204 class CommandObjectProcessInterrupt : public CommandObjectParsed {
1205 public:
CommandObjectProcessInterrupt(CommandInterpreter & interpreter)1206   CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
1207       : CommandObjectParsed(interpreter, "process interrupt",
1208                             "Interrupt the current target process.",
1209                             "process interrupt",
1210                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1211                                 eCommandProcessMustBeLaunched) {}
1212 
1213   ~CommandObjectProcessInterrupt() override = default;
1214 
1215 protected:
DoExecute(Args & command,CommandReturnObject & result)1216   void DoExecute(Args &command, CommandReturnObject &result) override {
1217     Process *process = m_exe_ctx.GetProcessPtr();
1218     if (process == nullptr) {
1219       result.AppendError("no process to halt");
1220       return;
1221     }
1222 
1223     bool clear_thread_plans = true;
1224     Status error(process->Halt(clear_thread_plans));
1225     if (error.Success()) {
1226       result.SetStatus(eReturnStatusSuccessFinishResult);
1227     } else {
1228       result.AppendErrorWithFormat("Failed to halt process: %s\n",
1229                                    error.AsCString());
1230     }
1231   }
1232 };
1233 
1234 // CommandObjectProcessKill
1235 #pragma mark CommandObjectProcessKill
1236 
1237 class CommandObjectProcessKill : public CommandObjectParsed {
1238 public:
CommandObjectProcessKill(CommandInterpreter & interpreter)1239   CommandObjectProcessKill(CommandInterpreter &interpreter)
1240       : CommandObjectParsed(interpreter, "process kill",
1241                             "Terminate the current target process.",
1242                             "process kill",
1243                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1244                                 eCommandProcessMustBeLaunched) {}
1245 
1246   ~CommandObjectProcessKill() override = default;
1247 
1248 protected:
DoExecute(Args & command,CommandReturnObject & result)1249   void DoExecute(Args &command, CommandReturnObject &result) override {
1250     Process *process = m_exe_ctx.GetProcessPtr();
1251     if (process == nullptr) {
1252       result.AppendError("no process to kill");
1253       return;
1254     }
1255 
1256     Status error(process->Destroy(true));
1257     if (error.Success()) {
1258       result.SetStatus(eReturnStatusSuccessFinishResult);
1259     } else {
1260       result.AppendErrorWithFormat("Failed to kill process: %s\n",
1261                                    error.AsCString());
1262     }
1263   }
1264 };
1265 
1266 #define LLDB_OPTIONS_process_save_core
1267 #include "CommandOptions.inc"
1268 
1269 class CommandObjectProcessSaveCore : public CommandObjectParsed {
1270 public:
CommandObjectProcessSaveCore(CommandInterpreter & interpreter)1271   CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
1272       : CommandObjectParsed(
1273             interpreter, "process save-core",
1274             "Save the current process as a core file using an "
1275             "appropriate file type.",
1276             "process save-core [-s corefile-style -p plugin-name] FILE",
1277             eCommandRequiresProcess | eCommandTryTargetAPILock |
1278                 eCommandProcessMustBeLaunched) {
1279     AddSimpleArgumentList(eArgTypePath);
1280   }
1281 
1282   ~CommandObjectProcessSaveCore() override = default;
1283 
GetOptions()1284   Options *GetOptions() override { return &m_options; }
1285 
1286   class CommandOptions : public Options {
1287   public:
1288     CommandOptions() = default;
1289 
1290     ~CommandOptions() override = default;
1291 
GetDefinitions()1292     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1293       if (!m_opt_def.empty())
1294         return llvm::ArrayRef(m_opt_def);
1295 
1296       auto orig = llvm::ArrayRef(g_process_save_core_options);
1297       m_opt_def.resize(orig.size());
1298       llvm::copy(g_process_save_core_options, m_opt_def.data());
1299       for (OptionDefinition &value : m_opt_def) {
1300         llvm::StringRef opt_name = value.long_option;
1301         if (opt_name != "plugin-name")
1302           continue;
1303 
1304         std::vector<llvm::StringRef> plugin_names =
1305             PluginManager::GetSaveCorePluginNames();
1306         m_plugin_enums.resize(plugin_names.size());
1307         for (auto [num, val] : llvm::zip(plugin_names, m_plugin_enums)) {
1308           val.string_value = num.data();
1309         }
1310         value.enum_values = llvm::ArrayRef(m_plugin_enums);
1311         break;
1312       }
1313       return llvm::ArrayRef(m_opt_def);
1314     }
1315 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1316     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1317                           ExecutionContext *execution_context) override {
1318       const int short_option = m_getopt_table[option_idx].val;
1319       Status error;
1320 
1321       switch (short_option) {
1322       case 'p':
1323         error = m_core_dump_options.SetPluginName(option_arg.data());
1324         break;
1325       case 's':
1326         m_core_dump_options.SetStyle(
1327             (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum(
1328                 option_arg, GetDefinitions()[option_idx].enum_values,
1329                 eSaveCoreUnspecified, error));
1330         break;
1331       default:
1332         llvm_unreachable("Unimplemented option");
1333       }
1334 
1335       return error;
1336     }
1337 
OptionParsingStarting(ExecutionContext * execution_context)1338     void OptionParsingStarting(ExecutionContext *execution_context) override {
1339       m_core_dump_options.Clear();
1340     }
1341 
1342     // Instance variables to hold the values for command options.
1343     SaveCoreOptions m_core_dump_options;
1344     llvm::SmallVector<OptionEnumValueElement> m_plugin_enums;
1345     std::vector<OptionDefinition> m_opt_def;
1346   };
1347 
1348 protected:
DoExecute(Args & command,CommandReturnObject & result)1349   void DoExecute(Args &command, CommandReturnObject &result) override {
1350     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1351     if (process_sp) {
1352       if (command.GetArgumentCount() == 1) {
1353         FileSpec output_file(command.GetArgumentAtIndex(0));
1354         FileSystem::Instance().Resolve(output_file);
1355         auto &core_dump_options = m_options.m_core_dump_options;
1356         core_dump_options.SetOutputFile(output_file);
1357         Status error = PluginManager::SaveCore(process_sp, core_dump_options);
1358         if (error.Success()) {
1359           if (core_dump_options.GetStyle() ==
1360                   SaveCoreStyle::eSaveCoreDirtyOnly ||
1361               core_dump_options.GetStyle() ==
1362                   SaveCoreStyle::eSaveCoreStackOnly) {
1363             result.AppendMessageWithFormat(
1364                 "\nModified-memory or stack-memory only corefile "
1365                 "created.  This corefile may \n"
1366                 "not show library/framework/app binaries "
1367                 "on a different system, or when \n"
1368                 "those binaries have "
1369                 "been updated/modified. Copies are not included\n"
1370                 "in this corefile.  Use --style full to include all "
1371                 "process memory.\n");
1372           }
1373           result.SetStatus(eReturnStatusSuccessFinishResult);
1374         } else {
1375           result.AppendErrorWithFormat(
1376               "Failed to save core file for process: %s\n", error.AsCString());
1377         }
1378       } else {
1379         result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
1380                                      m_cmd_name.c_str(), m_cmd_syntax.c_str());
1381       }
1382     } else {
1383       result.AppendError("invalid process");
1384     }
1385   }
1386 
1387   CommandOptions m_options;
1388 };
1389 
1390 // CommandObjectProcessStatus
1391 #pragma mark CommandObjectProcessStatus
1392 #define LLDB_OPTIONS_process_status
1393 #include "CommandOptions.inc"
1394 
1395 class CommandObjectProcessStatus : public CommandObjectParsed {
1396 public:
CommandObjectProcessStatus(CommandInterpreter & interpreter)1397   CommandObjectProcessStatus(CommandInterpreter &interpreter)
1398       : CommandObjectParsed(
1399             interpreter, "process status",
1400             "Show status and stop location for the current target process.",
1401             "process status",
1402             eCommandRequiresProcess | eCommandTryTargetAPILock) {}
1403 
1404   ~CommandObjectProcessStatus() override = default;
1405 
GetOptions()1406   Options *GetOptions() override { return &m_options; }
1407 
1408   class CommandOptions : public Options {
1409   public:
1410     CommandOptions() = default;
1411 
1412     ~CommandOptions() override = default;
1413 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1414     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1415                           ExecutionContext *execution_context) override {
1416       const int short_option = m_getopt_table[option_idx].val;
1417 
1418       switch (short_option) {
1419       case 'v':
1420         m_verbose = true;
1421         break;
1422       case 'd':
1423         m_dump = true;
1424         break;
1425       default:
1426         llvm_unreachable("Unimplemented option");
1427       }
1428 
1429       return {};
1430     }
1431 
OptionParsingStarting(ExecutionContext * execution_context)1432     void OptionParsingStarting(ExecutionContext *execution_context) override {
1433       m_verbose = false;
1434       m_dump = false;
1435     }
1436 
GetDefinitions()1437     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1438       return llvm::ArrayRef(g_process_status_options);
1439     }
1440 
1441     // Instance variables to hold the values for command options.
1442     bool m_verbose = false;
1443     bool m_dump = false;
1444   };
1445 
1446 protected:
DoExecute(Args & command,CommandReturnObject & result)1447   void DoExecute(Args &command, CommandReturnObject &result) override {
1448     Stream &strm = result.GetOutputStream();
1449     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1450 
1451     // No need to check "process" for validity as eCommandRequiresProcess
1452     // ensures it is valid
1453     Process *process = m_exe_ctx.GetProcessPtr();
1454     const bool only_threads_with_stop_reason = true;
1455     const uint32_t start_frame = 0;
1456     const uint32_t num_frames = 1;
1457     const uint32_t num_frames_with_source = 1;
1458     const bool stop_format = true;
1459     process->GetStatus(strm);
1460     process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
1461                              num_frames, num_frames_with_source, stop_format);
1462 
1463     if (m_options.m_verbose) {
1464       addr_t code_mask = process->GetCodeAddressMask();
1465       addr_t data_mask = process->GetDataAddressMask();
1466       if (code_mask != LLDB_INVALID_ADDRESS_MASK) {
1467         int bits = std::bitset<64>(~code_mask).count();
1468         result.AppendMessageWithFormat(
1469             "Addressable code address mask: 0x%" PRIx64 "\n", code_mask);
1470         result.AppendMessageWithFormat(
1471             "Addressable data address mask: 0x%" PRIx64 "\n", data_mask);
1472         result.AppendMessageWithFormat(
1473             "Number of bits used in addressing (code): %d\n", bits);
1474       }
1475 
1476       PlatformSP platform_sp = process->GetTarget().GetPlatform();
1477       if (!platform_sp) {
1478         result.AppendError("Couldn't retrieve the target's platform");
1479         return;
1480       }
1481 
1482       auto expected_crash_info =
1483           platform_sp->FetchExtendedCrashInformation(*process);
1484 
1485       if (!expected_crash_info) {
1486         result.AppendError(llvm::toString(expected_crash_info.takeError()));
1487         return;
1488       }
1489 
1490       StructuredData::DictionarySP crash_info_sp = *expected_crash_info;
1491 
1492       if (crash_info_sp) {
1493         strm.EOL();
1494         strm.PutCString("Extended Crash Information:\n");
1495         crash_info_sp->GetDescription(strm);
1496       }
1497     }
1498 
1499     if (m_options.m_dump) {
1500       StateType state = process->GetState();
1501       if (state == eStateStopped) {
1502         ProcessModID process_mod_id = process->GetModID();
1503         process_mod_id.Dump(result.GetOutputStream());
1504       }
1505     }
1506   }
1507 
1508 private:
1509   CommandOptions m_options;
1510 };
1511 
1512 // CommandObjectProcessHandle
1513 #define LLDB_OPTIONS_process_handle
1514 #include "CommandOptions.inc"
1515 
1516 #pragma mark CommandObjectProcessHandle
1517 
1518 class CommandObjectProcessHandle : public CommandObjectParsed {
1519 public:
1520   class CommandOptions : public Options {
1521   public:
CommandOptions()1522     CommandOptions() { OptionParsingStarting(nullptr); }
1523 
1524     ~CommandOptions() override = default;
1525 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1526     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1527                           ExecutionContext *execution_context) override {
1528       Status error;
1529       const int short_option = m_getopt_table[option_idx].val;
1530 
1531       switch (short_option) {
1532       case 'c':
1533         do_clear = true;
1534         break;
1535       case 'd':
1536         dummy = true;
1537         break;
1538       case 's':
1539         stop = std::string(option_arg);
1540         break;
1541       case 'n':
1542         notify = std::string(option_arg);
1543         break;
1544       case 'p':
1545         pass = std::string(option_arg);
1546         break;
1547       case 't':
1548         only_target_values = true;
1549         break;
1550       default:
1551         llvm_unreachable("Unimplemented option");
1552       }
1553       return error;
1554     }
1555 
OptionParsingStarting(ExecutionContext * execution_context)1556     void OptionParsingStarting(ExecutionContext *execution_context) override {
1557       stop.clear();
1558       notify.clear();
1559       pass.clear();
1560       only_target_values = false;
1561       do_clear = false;
1562       dummy = false;
1563     }
1564 
GetDefinitions()1565     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1566       return llvm::ArrayRef(g_process_handle_options);
1567     }
1568 
1569     // Instance variables to hold the values for command options.
1570 
1571     std::string stop;
1572     std::string notify;
1573     std::string pass;
1574     bool only_target_values = false;
1575     bool do_clear = false;
1576     bool dummy = false;
1577   };
1578 
CommandObjectProcessHandle(CommandInterpreter & interpreter)1579   CommandObjectProcessHandle(CommandInterpreter &interpreter)
1580       : CommandObjectParsed(interpreter, "process handle",
1581                             "Manage LLDB handling of OS signals for the "
1582                             "current target process.  Defaults to showing "
1583                             "current policy.",
1584                             nullptr) {
1585     SetHelpLong("\nIf no signals are specified but one or more actions are, "
1586                 "and there is a live process, update them all.  If no action "
1587                 "is specified, list the current values.\n"
1588                 "If you specify actions with no target (e.g. in an init file) "
1589                 "or in a target with no process "
1590                 "the values will get copied into subsequent targets, but "
1591                 "lldb won't be able to spell-check the options since it can't "
1592                 "know which signal set will later be in force."
1593                 "\nYou can see the signal modifications held by the target"
1594                 "by passing the -t option."
1595                 "\nYou can also clear the target modification for a signal"
1596                 "by passing the -c option");
1597     AddSimpleArgumentList(eArgTypeUnixSignal, eArgRepeatStar);
1598   }
1599 
1600   ~CommandObjectProcessHandle() override = default;
1601 
GetOptions()1602   Options *GetOptions() override { return &m_options; }
1603 
PrintSignalHeader(Stream & str)1604   void PrintSignalHeader(Stream &str) {
1605     str.Printf("NAME         PASS   STOP   NOTIFY\n");
1606     str.Printf("===========  =====  =====  ======\n");
1607   }
1608 
PrintSignal(Stream & str,int32_t signo,llvm::StringRef sig_name,const UnixSignalsSP & signals_sp)1609   void PrintSignal(Stream &str, int32_t signo, llvm::StringRef sig_name,
1610                    const UnixSignalsSP &signals_sp) {
1611     bool stop;
1612     bool suppress;
1613     bool notify;
1614 
1615     str.Format("{0, -11}  ", sig_name);
1616     if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
1617       bool pass = !suppress;
1618       str.Printf("%s  %s  %s", (pass ? "true " : "false"),
1619                  (stop ? "true " : "false"), (notify ? "true " : "false"));
1620     }
1621     str.Printf("\n");
1622   }
1623 
PrintSignalInformation(Stream & str,Args & signal_args,int num_valid_signals,const UnixSignalsSP & signals_sp)1624   void PrintSignalInformation(Stream &str, Args &signal_args,
1625                               int num_valid_signals,
1626                               const UnixSignalsSP &signals_sp) {
1627     PrintSignalHeader(str);
1628 
1629     if (num_valid_signals > 0) {
1630       size_t num_args = signal_args.GetArgumentCount();
1631       for (size_t i = 0; i < num_args; ++i) {
1632         int32_t signo = signals_sp->GetSignalNumberFromName(
1633             signal_args.GetArgumentAtIndex(i));
1634         if (signo != LLDB_INVALID_SIGNAL_NUMBER)
1635           PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
1636                       signals_sp);
1637       }
1638     } else // Print info for ALL signals
1639     {
1640       int32_t signo = signals_sp->GetFirstSignalNumber();
1641       while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1642         PrintSignal(str, signo, signals_sp->GetSignalAsStringRef(signo),
1643                     signals_sp);
1644         signo = signals_sp->GetNextSignalNumber(signo);
1645       }
1646     }
1647   }
1648 
1649 protected:
DoExecute(Args & signal_args,CommandReturnObject & result)1650   void DoExecute(Args &signal_args, CommandReturnObject &result) override {
1651     Target &target = GetTarget();
1652 
1653     // Any signals that are being set should be added to the Target's
1654     // DummySignals so they will get applied on rerun, etc.
1655     // If we have a process, however, we can do a more accurate job of vetting
1656     // the user's options.
1657     ProcessSP process_sp = target.GetProcessSP();
1658 
1659     std::optional<bool> stop_action = {};
1660     std::optional<bool> pass_action = {};
1661     std::optional<bool> notify_action = {};
1662 
1663     if (!m_options.stop.empty()) {
1664       bool success = false;
1665       bool value = OptionArgParser::ToBoolean(m_options.stop, false, &success);
1666       if (!success) {
1667         result.AppendError(
1668             "Invalid argument for command option --stop; must be "
1669             "true or false.\n");
1670         return;
1671       }
1672 
1673       stop_action = value;
1674     }
1675 
1676     if (!m_options.pass.empty()) {
1677       bool success = false;
1678       bool value = OptionArgParser::ToBoolean(m_options.pass, false, &success);
1679       if (!success) {
1680         result.AppendError(
1681             "Invalid argument for command option --pass; must be "
1682             "true or false.\n");
1683         return;
1684       }
1685       pass_action = value;
1686     }
1687 
1688     if (!m_options.notify.empty()) {
1689       bool success = false;
1690       bool value =
1691           OptionArgParser::ToBoolean(m_options.notify, false, &success);
1692       if (!success) {
1693         result.AppendError("Invalid argument for command option --notify; must "
1694                            "be true or false.\n");
1695         return;
1696       }
1697       notify_action = value;
1698     }
1699 
1700     if (!m_options.notify.empty() && !notify_action.has_value()) {
1701     }
1702 
1703     bool no_actions = (!stop_action.has_value() && !pass_action.has_value() &&
1704                        !notify_action.has_value());
1705     if (m_options.only_target_values && !no_actions) {
1706       result.AppendError("-t is for reporting, not setting, target values.");
1707       return;
1708     }
1709 
1710     size_t num_args = signal_args.GetArgumentCount();
1711     UnixSignalsSP signals_sp;
1712     if (process_sp)
1713       signals_sp = process_sp->GetUnixSignals();
1714 
1715     int num_signals_set = 0;
1716 
1717     // If we were just asked to print the target values, do that here and
1718     // return:
1719     if (m_options.only_target_values) {
1720       target.PrintDummySignals(result.GetOutputStream(), signal_args);
1721       result.SetStatus(eReturnStatusSuccessFinishResult);
1722       return;
1723     }
1724 
1725     // This handles clearing values:
1726     if (m_options.do_clear) {
1727       target.ClearDummySignals(signal_args);
1728       if (m_options.dummy)
1729         GetDummyTarget().ClearDummySignals(signal_args);
1730       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1731       return;
1732     }
1733 
1734     // This rest handles setting values:
1735     if (num_args > 0) {
1736       for (const auto &arg : signal_args) {
1737         // Do the process first.  If we have a process we can catch
1738         // invalid signal names, which we do here.
1739         if (signals_sp) {
1740           int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
1741           if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1742             if (stop_action.has_value())
1743               signals_sp->SetShouldStop(signo, *stop_action);
1744             if (pass_action.has_value()) {
1745               bool suppress = !*pass_action;
1746               signals_sp->SetShouldSuppress(signo, suppress);
1747             }
1748             if (notify_action.has_value())
1749               signals_sp->SetShouldNotify(signo, *notify_action);
1750             ++num_signals_set;
1751           } else {
1752             result.AppendErrorWithFormat("Invalid signal name '%s'\n",
1753                                           arg.c_str());
1754             continue;
1755           }
1756         } else {
1757           // If there's no process we can't check, so we just set them all.
1758           // But since the map signal name -> signal number across all platforms
1759           // is not 1-1, we can't sensibly set signal actions by number before
1760           // we have a process.  Check that here:
1761           int32_t signo;
1762           if (llvm::to_integer(arg.c_str(), signo)) {
1763             result.AppendErrorWithFormat("Can't set signal handling by signal "
1764                                          "number with no process");
1765             return;
1766           }
1767          num_signals_set = num_args;
1768         }
1769         auto set_lazy_bool = [](std::optional<bool> action) -> LazyBool {
1770           if (!action.has_value())
1771             return eLazyBoolCalculate;
1772           return (*action) ? eLazyBoolYes : eLazyBoolNo;
1773         };
1774 
1775         // If there were no actions, we're just listing, don't add the dummy:
1776         if (!no_actions)
1777           target.AddDummySignal(arg.ref(), set_lazy_bool(pass_action),
1778                                 set_lazy_bool(notify_action),
1779                                 set_lazy_bool(stop_action));
1780       }
1781     } else {
1782       // No signal specified, if any command options were specified, update ALL
1783       // signals.  But we can't do this without a process since we don't know
1784       // all the possible signals that might be valid for this target.
1785       if ((notify_action.has_value() || stop_action.has_value() ||
1786            pass_action.has_value()) &&
1787           process_sp) {
1788         if (m_interpreter.Confirm(
1789                 "Do you really want to update all the signals?", false)) {
1790           int32_t signo = signals_sp->GetFirstSignalNumber();
1791           while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
1792             if (notify_action.has_value())
1793               signals_sp->SetShouldNotify(signo, *notify_action);
1794             if (stop_action.has_value())
1795               signals_sp->SetShouldStop(signo, *stop_action);
1796             if (pass_action.has_value()) {
1797               bool suppress = !*pass_action;
1798               signals_sp->SetShouldSuppress(signo, suppress);
1799             }
1800             signo = signals_sp->GetNextSignalNumber(signo);
1801           }
1802         }
1803       }
1804     }
1805 
1806     if (signals_sp)
1807       PrintSignalInformation(result.GetOutputStream(), signal_args,
1808                              num_signals_set, signals_sp);
1809     else
1810       target.PrintDummySignals(result.GetOutputStream(),
1811           signal_args);
1812 
1813     if (num_signals_set > 0)
1814       result.SetStatus(eReturnStatusSuccessFinishResult);
1815     else
1816       result.SetStatus(eReturnStatusFailed);
1817   }
1818 
1819   CommandOptions m_options;
1820 };
1821 
1822 // Next are the subcommands of CommandObjectMultiwordProcessTrace
1823 
1824 // CommandObjectProcessTraceStart
1825 class CommandObjectProcessTraceStart : public CommandObjectTraceProxy {
1826 public:
CommandObjectProcessTraceStart(CommandInterpreter & interpreter)1827   CommandObjectProcessTraceStart(CommandInterpreter &interpreter)
1828       : CommandObjectTraceProxy(
1829             /*live_debug_session_only*/ true, interpreter,
1830             "process trace start",
1831             "Start tracing this process with the corresponding trace "
1832             "plug-in.",
1833             "process trace start [<trace-options>]") {}
1834 
1835 protected:
GetDelegateCommand(Trace & trace)1836   lldb::CommandObjectSP GetDelegateCommand(Trace &trace) override {
1837     return trace.GetProcessTraceStartCommand(m_interpreter);
1838   }
1839 };
1840 
1841 // CommandObjectProcessTraceStop
1842 class CommandObjectProcessTraceStop : public CommandObjectParsed {
1843 public:
CommandObjectProcessTraceStop(CommandInterpreter & interpreter)1844   CommandObjectProcessTraceStop(CommandInterpreter &interpreter)
1845       : CommandObjectParsed(interpreter, "process trace stop",
1846                             "Stop tracing this process. This does not affect "
1847                             "traces started with the "
1848                             "\"thread trace start\" command.",
1849                             "process trace stop",
1850                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1851                                 eCommandProcessMustBeLaunched |
1852                                 eCommandProcessMustBePaused |
1853                                 eCommandProcessMustBeTraced) {}
1854 
1855   ~CommandObjectProcessTraceStop() override = default;
1856 
DoExecute(Args & command,CommandReturnObject & result)1857   void DoExecute(Args &command, CommandReturnObject &result) override {
1858     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1859 
1860     TraceSP trace_sp = process_sp->GetTarget().GetTrace();
1861 
1862     if (llvm::Error err = trace_sp->Stop())
1863       result.AppendError(toString(std::move(err)));
1864     else
1865       result.SetStatus(eReturnStatusSuccessFinishResult);
1866   }
1867 };
1868 
1869 // CommandObjectMultiwordProcessTrace
1870 class CommandObjectMultiwordProcessTrace : public CommandObjectMultiword {
1871 public:
CommandObjectMultiwordProcessTrace(CommandInterpreter & interpreter)1872   CommandObjectMultiwordProcessTrace(CommandInterpreter &interpreter)
1873       : CommandObjectMultiword(
1874             interpreter, "trace", "Commands for tracing the current process.",
1875             "process trace <subcommand> [<subcommand objects>]") {
1876     LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart(
1877                                 interpreter)));
1878     LoadSubCommand("stop", CommandObjectSP(
1879                                new CommandObjectProcessTraceStop(interpreter)));
1880   }
1881 
1882   ~CommandObjectMultiwordProcessTrace() override = default;
1883 };
1884 
1885 // CommandObjectMultiwordProcess
1886 
CommandObjectMultiwordProcess(CommandInterpreter & interpreter)1887 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
1888     CommandInterpreter &interpreter)
1889     : CommandObjectMultiword(
1890           interpreter, "process",
1891           "Commands for interacting with processes on the current platform.",
1892           "process <subcommand> [<subcommand-options>]") {
1893   LoadSubCommand("attach",
1894                  CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
1895   LoadSubCommand("launch",
1896                  CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
1897   LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
1898                                  interpreter)));
1899   LoadSubCommand("connect",
1900                  CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
1901   LoadSubCommand("detach",
1902                  CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
1903   LoadSubCommand("load",
1904                  CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
1905   LoadSubCommand("unload",
1906                  CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
1907   LoadSubCommand("signal",
1908                  CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
1909   LoadSubCommand("handle",
1910                  CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
1911   LoadSubCommand("status",
1912                  CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
1913   LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
1914                                   interpreter)));
1915   LoadSubCommand("kill",
1916                  CommandObjectSP(new CommandObjectProcessKill(interpreter)));
1917   LoadSubCommand("plugin",
1918                  CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
1919   LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
1920                                   interpreter)));
1921   LoadSubCommand(
1922       "trace",
1923       CommandObjectSP(new CommandObjectMultiwordProcessTrace(interpreter)));
1924 }
1925 
1926 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
1927