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