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