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