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