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