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