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