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