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