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