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