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