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