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