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