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