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