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