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