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