CommandObjectProcess.cpp revision 309124
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 34using namespace lldb; 35using namespace lldb_private; 36 37class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed 38{ 39public: 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 51protected: 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 119class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach 120{ 121public: 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 184protected: 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 294protected: 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 325class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach 326{ 327public: 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 482protected: 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 606OptionDefinition 607CommandObjectProcessAttach::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 623class CommandObjectProcessContinue : public CommandObjectParsed 624{ 625public: 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 641protected: 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(GetDefaultThread()->shared_from_this()); 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 std::lock_guard<std::recursive_mutex> guard(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 802OptionDefinition 803CommandObjectProcessContinue::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 815class CommandObjectProcessDetach : public CommandObjectParsed 816{ 817public: 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, "process detach", "Detach from the current target process.", 880 "process detach", 881 eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched), 882 m_options(interpreter) 883 { 884 } 885 886 ~CommandObjectProcessDetach() override = default; 887 888 Options * 889 GetOptions () override 890 { 891 return &m_options; 892 } 893 894protected: 895 bool 896 DoExecute (Args& command, CommandReturnObject &result) override 897 { 898 Process *process = m_exe_ctx.GetProcessPtr(); 899 // FIXME: This will be a Command Option: 900 bool keep_stopped; 901 if (m_options.m_keep_stopped == eLazyBoolCalculate) 902 { 903 // Check the process default: 904 keep_stopped = process->GetDetachKeepsStopped(); 905 } 906 else if (m_options.m_keep_stopped == eLazyBoolYes) 907 keep_stopped = true; 908 else 909 keep_stopped = false; 910 911 Error error (process->Detach(keep_stopped)); 912 if (error.Success()) 913 { 914 result.SetStatus (eReturnStatusSuccessFinishResult); 915 } 916 else 917 { 918 result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 919 result.SetStatus (eReturnStatusFailed); 920 return false; 921 } 922 return result.Succeeded(); 923 } 924 925 CommandOptions m_options; 926}; 927 928OptionDefinition 929CommandObjectProcessDetach::CommandOptions::g_option_table[] = 930{ 931{ 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)." }, 932{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 933}; 934 935//------------------------------------------------------------------------- 936// CommandObjectProcessConnect 937//------------------------------------------------------------------------- 938#pragma mark CommandObjectProcessConnect 939 940class CommandObjectProcessConnect : public CommandObjectParsed 941{ 942public: 943 class CommandOptions : public Options 944 { 945 public: 946 CommandOptions (CommandInterpreter &interpreter) : 947 Options(interpreter) 948 { 949 // Keep default values of all options in one place: OptionParsingStarting () 950 OptionParsingStarting (); 951 } 952 953 ~CommandOptions() override = default; 954 955 Error 956 SetOptionValue (uint32_t option_idx, const char *option_arg) override 957 { 958 Error error; 959 const int short_option = m_getopt_table[option_idx].val; 960 961 switch (short_option) 962 { 963 case 'p': 964 plugin_name.assign (option_arg); 965 break; 966 967 default: 968 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 969 break; 970 } 971 return error; 972 } 973 974 void 975 OptionParsingStarting () override 976 { 977 plugin_name.clear(); 978 } 979 980 const OptionDefinition* 981 GetDefinitions () override 982 { 983 return g_option_table; 984 } 985 986 // Options table: Required for subclasses of Options. 987 988 static OptionDefinition g_option_table[]; 989 990 // Instance variables to hold the values for command options. 991 992 std::string plugin_name; 993 }; 994 995 CommandObjectProcessConnect (CommandInterpreter &interpreter) : 996 CommandObjectParsed (interpreter, 997 "process connect", 998 "Connect to a remote debug service.", 999 "process connect <remote-url>", 1000 0), 1001 m_options (interpreter) 1002 { 1003 } 1004 1005 ~CommandObjectProcessConnect() override = default; 1006 1007 Options * 1008 GetOptions () override 1009 { 1010 return &m_options; 1011 } 1012 1013protected: 1014 bool 1015 DoExecute (Args& command, CommandReturnObject &result) override 1016 { 1017 if (command.GetArgumentCount() != 1) 1018 { 1019 result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n", 1020 m_cmd_name.c_str(), 1021 m_cmd_syntax.c_str()); 1022 result.SetStatus (eReturnStatusFailed); 1023 return false; 1024 } 1025 1026 Process *process = m_exe_ctx.GetProcessPtr(); 1027 if (process && process->IsAlive()) 1028 { 1029 result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n", 1030 process->GetID()); 1031 result.SetStatus (eReturnStatusFailed); 1032 return false; 1033 } 1034 1035 const char *plugin_name = nullptr; 1036 if (!m_options.plugin_name.empty()) 1037 plugin_name = m_options.plugin_name.c_str(); 1038 1039 Error error; 1040 Debugger& debugger = m_interpreter.GetDebugger(); 1041 PlatformSP platform_sp = m_interpreter.GetPlatform(true); 1042 ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0), 1043 plugin_name, 1044 debugger, 1045 debugger.GetSelectedTarget().get(), 1046 error); 1047 if (error.Fail() || process_sp == nullptr) 1048 { 1049 result.AppendError(error.AsCString("Error connecting to the process")); 1050 result.SetStatus (eReturnStatusFailed); 1051 return false; 1052 } 1053 return true; 1054 } 1055 1056 CommandOptions m_options; 1057}; 1058 1059OptionDefinition 1060CommandObjectProcessConnect::CommandOptions::g_option_table[] = 1061{ 1062 { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 1063 { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1064}; 1065 1066//------------------------------------------------------------------------- 1067// CommandObjectProcessPlugin 1068//------------------------------------------------------------------------- 1069#pragma mark CommandObjectProcessPlugin 1070 1071class CommandObjectProcessPlugin : public CommandObjectProxy 1072{ 1073public: 1074 CommandObjectProcessPlugin(CommandInterpreter &interpreter) 1075 : CommandObjectProxy(interpreter, "process plugin", 1076 "Send a custom command to the current target process plug-in.", "process plugin <args>", 0) 1077 { 1078 } 1079 1080 ~CommandObjectProcessPlugin() override = default; 1081 1082 CommandObject * 1083 GetProxyCommandObject() override 1084 { 1085 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 1086 if (process) 1087 return process->GetPluginCommandObject(); 1088 return nullptr; 1089 } 1090}; 1091 1092//------------------------------------------------------------------------- 1093// CommandObjectProcessLoad 1094//------------------------------------------------------------------------- 1095#pragma mark CommandObjectProcessLoad 1096 1097class CommandObjectProcessLoad : public CommandObjectParsed 1098{ 1099public: 1100 class CommandOptions : public Options 1101 { 1102 public: 1103 CommandOptions (CommandInterpreter &interpreter) : 1104 Options(interpreter) 1105 { 1106 // Keep default values of all options in one place: OptionParsingStarting () 1107 OptionParsingStarting (); 1108 } 1109 1110 ~CommandOptions() override = default; 1111 1112 Error 1113 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1114 { 1115 Error error; 1116 const int short_option = m_getopt_table[option_idx].val; 1117 switch (short_option) 1118 { 1119 case 'i': 1120 do_install = true; 1121 if (option_arg && option_arg[0]) 1122 install_path.SetFile(option_arg, false); 1123 break; 1124 default: 1125 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1126 break; 1127 } 1128 return error; 1129 } 1130 1131 void 1132 OptionParsingStarting () override 1133 { 1134 do_install = false; 1135 install_path.Clear(); 1136 } 1137 1138 const OptionDefinition* 1139 GetDefinitions () override 1140 { 1141 return g_option_table; 1142 } 1143 1144 // Options table: Required for subclasses of Options. 1145 static OptionDefinition g_option_table[]; 1146 1147 // Instance variables to hold the values for command options. 1148 bool do_install; 1149 FileSpec install_path; 1150 }; 1151 1152 CommandObjectProcessLoad (CommandInterpreter &interpreter) : 1153 CommandObjectParsed (interpreter, 1154 "process load", 1155 "Load a shared library into the current process.", 1156 "process load <filename> [<filename> ...]", 1157 eCommandRequiresProcess | 1158 eCommandTryTargetAPILock | 1159 eCommandProcessMustBeLaunched | 1160 eCommandProcessMustBePaused ), 1161 m_options (interpreter) 1162 { 1163 } 1164 1165 ~CommandObjectProcessLoad() override = default; 1166 1167 Options * 1168 GetOptions () override 1169 { 1170 return &m_options; 1171 } 1172 1173protected: 1174 bool 1175 DoExecute (Args& command, CommandReturnObject &result) override 1176 { 1177 Process *process = m_exe_ctx.GetProcessPtr(); 1178 1179 const size_t argc = command.GetArgumentCount(); 1180 for (uint32_t i = 0; i < argc; ++i) 1181 { 1182 Error error; 1183 PlatformSP platform = process->GetTarget().GetPlatform(); 1184 const char *image_path = command.GetArgumentAtIndex(i); 1185 uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN; 1186 1187 if (!m_options.do_install) 1188 { 1189 FileSpec image_spec (image_path, false); 1190 platform->ResolveRemotePath(image_spec, image_spec); 1191 image_token = platform->LoadImage(process, FileSpec(), image_spec, error); 1192 } 1193 else if (m_options.install_path) 1194 { 1195 FileSpec image_spec (image_path, true); 1196 platform->ResolveRemotePath(m_options.install_path, m_options.install_path); 1197 image_token = platform->LoadImage(process, image_spec, m_options.install_path, error); 1198 } 1199 else 1200 { 1201 FileSpec image_spec (image_path, true); 1202 image_token = platform->LoadImage(process, image_spec, FileSpec(), error); 1203 } 1204 1205 if (image_token != LLDB_INVALID_IMAGE_TOKEN) 1206 { 1207 result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); 1208 result.SetStatus (eReturnStatusSuccessFinishResult); 1209 } 1210 else 1211 { 1212 result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString()); 1213 result.SetStatus (eReturnStatusFailed); 1214 } 1215 } 1216 return result.Succeeded(); 1217 } 1218 1219 CommandOptions m_options; 1220}; 1221 1222OptionDefinition 1223CommandObjectProcessLoad::CommandOptions::g_option_table[] = 1224{ 1225 { 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."}, 1226 { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1227}; 1228 1229//------------------------------------------------------------------------- 1230// CommandObjectProcessUnload 1231//------------------------------------------------------------------------- 1232#pragma mark CommandObjectProcessUnload 1233 1234class CommandObjectProcessUnload : public CommandObjectParsed 1235{ 1236public: 1237 1238 CommandObjectProcessUnload (CommandInterpreter &interpreter) : 1239 CommandObjectParsed (interpreter, 1240 "process unload", 1241 "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", 1242 "process unload <index>", 1243 eCommandRequiresProcess | 1244 eCommandTryTargetAPILock | 1245 eCommandProcessMustBeLaunched | 1246 eCommandProcessMustBePaused ) 1247 { 1248 } 1249 1250 ~CommandObjectProcessUnload() override = default; 1251 1252protected: 1253 bool 1254 DoExecute (Args& command, CommandReturnObject &result) override 1255 { 1256 Process *process = m_exe_ctx.GetProcessPtr(); 1257 1258 const size_t argc = command.GetArgumentCount(); 1259 1260 for (uint32_t i = 0; i < argc; ++i) 1261 { 1262 const char *image_token_cstr = command.GetArgumentAtIndex(i); 1263 uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); 1264 if (image_token == LLDB_INVALID_IMAGE_TOKEN) 1265 { 1266 result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); 1267 result.SetStatus (eReturnStatusFailed); 1268 break; 1269 } 1270 else 1271 { 1272 Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token)); 1273 if (error.Success()) 1274 { 1275 result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); 1276 result.SetStatus (eReturnStatusSuccessFinishResult); 1277 } 1278 else 1279 { 1280 result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString()); 1281 result.SetStatus (eReturnStatusFailed); 1282 break; 1283 } 1284 } 1285 } 1286 return result.Succeeded(); 1287 } 1288}; 1289 1290//------------------------------------------------------------------------- 1291// CommandObjectProcessSignal 1292//------------------------------------------------------------------------- 1293#pragma mark CommandObjectProcessSignal 1294 1295class CommandObjectProcessSignal : public CommandObjectParsed 1296{ 1297public: 1298 CommandObjectProcessSignal(CommandInterpreter &interpreter) 1299 : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.", 1300 nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock) 1301 { 1302 CommandArgumentEntry arg; 1303 CommandArgumentData signal_arg; 1304 1305 // Define the first (and only) variant of this arg. 1306 signal_arg.arg_type = eArgTypeUnixSignal; 1307 signal_arg.arg_repetition = eArgRepeatPlain; 1308 1309 // There is only one variant this argument could be; put it into the argument entry. 1310 arg.push_back (signal_arg); 1311 1312 // Push the data for the first argument into the m_arguments vector. 1313 m_arguments.push_back (arg); 1314 } 1315 1316 ~CommandObjectProcessSignal() override = default; 1317 1318protected: 1319 bool 1320 DoExecute (Args& command, CommandReturnObject &result) override 1321 { 1322 Process *process = m_exe_ctx.GetProcessPtr(); 1323 1324 if (command.GetArgumentCount() == 1) 1325 { 1326 int signo = LLDB_INVALID_SIGNAL_NUMBER; 1327 1328 const char *signal_name = command.GetArgumentAtIndex(0); 1329 if (::isxdigit (signal_name[0])) 1330 signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 1331 else 1332 signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); 1333 1334 if (signo == LLDB_INVALID_SIGNAL_NUMBER) 1335 { 1336 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 1337 result.SetStatus (eReturnStatusFailed); 1338 } 1339 else 1340 { 1341 Error error (process->Signal (signo)); 1342 if (error.Success()) 1343 { 1344 result.SetStatus (eReturnStatusSuccessFinishResult); 1345 } 1346 else 1347 { 1348 result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 1349 result.SetStatus (eReturnStatusFailed); 1350 } 1351 } 1352 } 1353 else 1354 { 1355 result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(), 1356 m_cmd_syntax.c_str()); 1357 result.SetStatus (eReturnStatusFailed); 1358 } 1359 return result.Succeeded(); 1360 } 1361}; 1362 1363//------------------------------------------------------------------------- 1364// CommandObjectProcessInterrupt 1365//------------------------------------------------------------------------- 1366#pragma mark CommandObjectProcessInterrupt 1367 1368class CommandObjectProcessInterrupt : public CommandObjectParsed 1369{ 1370public: 1371 CommandObjectProcessInterrupt(CommandInterpreter &interpreter) 1372 : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.", 1373 "process interrupt", 1374 eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched) 1375 { 1376 } 1377 1378 ~CommandObjectProcessInterrupt() override = default; 1379 1380protected: 1381 bool 1382 DoExecute (Args& command, CommandReturnObject &result) override 1383 { 1384 Process *process = m_exe_ctx.GetProcessPtr(); 1385 if (process == nullptr) 1386 { 1387 result.AppendError ("no process to halt"); 1388 result.SetStatus (eReturnStatusFailed); 1389 return false; 1390 } 1391 1392 if (command.GetArgumentCount() == 0) 1393 { 1394 bool clear_thread_plans = true; 1395 Error error(process->Halt (clear_thread_plans)); 1396 if (error.Success()) 1397 { 1398 result.SetStatus (eReturnStatusSuccessFinishResult); 1399 } 1400 else 1401 { 1402 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 1403 result.SetStatus (eReturnStatusFailed); 1404 } 1405 } 1406 else 1407 { 1408 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1409 m_cmd_name.c_str(), 1410 m_cmd_syntax.c_str()); 1411 result.SetStatus (eReturnStatusFailed); 1412 } 1413 return result.Succeeded(); 1414 } 1415}; 1416 1417//------------------------------------------------------------------------- 1418// CommandObjectProcessKill 1419//------------------------------------------------------------------------- 1420#pragma mark CommandObjectProcessKill 1421 1422class CommandObjectProcessKill : public CommandObjectParsed 1423{ 1424public: 1425 CommandObjectProcessKill(CommandInterpreter &interpreter) 1426 : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill", 1427 eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched) 1428 { 1429 } 1430 1431 ~CommandObjectProcessKill() override = default; 1432 1433protected: 1434 bool 1435 DoExecute (Args& command, CommandReturnObject &result) override 1436 { 1437 Process *process = m_exe_ctx.GetProcessPtr(); 1438 if (process == nullptr) 1439 { 1440 result.AppendError ("no process to kill"); 1441 result.SetStatus (eReturnStatusFailed); 1442 return false; 1443 } 1444 1445 if (command.GetArgumentCount() == 0) 1446 { 1447 Error error (process->Destroy(true)); 1448 if (error.Success()) 1449 { 1450 result.SetStatus (eReturnStatusSuccessFinishResult); 1451 } 1452 else 1453 { 1454 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 1455 result.SetStatus (eReturnStatusFailed); 1456 } 1457 } 1458 else 1459 { 1460 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n", 1461 m_cmd_name.c_str(), 1462 m_cmd_syntax.c_str()); 1463 result.SetStatus (eReturnStatusFailed); 1464 } 1465 return result.Succeeded(); 1466 } 1467}; 1468 1469//------------------------------------------------------------------------- 1470// CommandObjectProcessSaveCore 1471//------------------------------------------------------------------------- 1472#pragma mark CommandObjectProcessSaveCore 1473 1474class CommandObjectProcessSaveCore : public CommandObjectParsed 1475{ 1476public: 1477 CommandObjectProcessSaveCore (CommandInterpreter &interpreter) : 1478 CommandObjectParsed (interpreter, 1479 "process save-core", 1480 "Save the current process as a core file using an appropriate file type.", 1481 "process save-core FILE", 1482 eCommandRequiresProcess | 1483 eCommandTryTargetAPILock | 1484 eCommandProcessMustBeLaunched) 1485 { 1486 } 1487 1488 ~CommandObjectProcessSaveCore() override = default; 1489 1490protected: 1491 bool 1492 DoExecute (Args& command, 1493 CommandReturnObject &result) override 1494 { 1495 ProcessSP process_sp = m_exe_ctx.GetProcessSP(); 1496 if (process_sp) 1497 { 1498 if (command.GetArgumentCount() == 1) 1499 { 1500 FileSpec output_file(command.GetArgumentAtIndex(0), false); 1501 Error error = PluginManager::SaveCore(process_sp, output_file); 1502 if (error.Success()) 1503 { 1504 result.SetStatus (eReturnStatusSuccessFinishResult); 1505 } 1506 else 1507 { 1508 result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString()); 1509 result.SetStatus (eReturnStatusFailed); 1510 } 1511 } 1512 else 1513 { 1514 result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n", 1515 m_cmd_name.c_str(), 1516 m_cmd_syntax.c_str()); 1517 result.SetStatus (eReturnStatusFailed); 1518 } 1519 } 1520 else 1521 { 1522 result.AppendError ("invalid process"); 1523 result.SetStatus (eReturnStatusFailed); 1524 return false; 1525 } 1526 1527 return result.Succeeded(); 1528 } 1529}; 1530 1531//------------------------------------------------------------------------- 1532// CommandObjectProcessStatus 1533//------------------------------------------------------------------------- 1534#pragma mark CommandObjectProcessStatus 1535 1536class CommandObjectProcessStatus : public CommandObjectParsed 1537{ 1538public: 1539 CommandObjectProcessStatus(CommandInterpreter &interpreter) 1540 : CommandObjectParsed(interpreter, "process status", 1541 "Show status and stop location for the current target process.", "process status", 1542 eCommandRequiresProcess | eCommandTryTargetAPILock) 1543 { 1544 } 1545 1546 ~CommandObjectProcessStatus() override = default; 1547 1548 bool 1549 DoExecute (Args& command, CommandReturnObject &result) override 1550 { 1551 Stream &strm = result.GetOutputStream(); 1552 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1553 // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid 1554 Process *process = m_exe_ctx.GetProcessPtr(); 1555 const bool only_threads_with_stop_reason = true; 1556 const uint32_t start_frame = 0; 1557 const uint32_t num_frames = 1; 1558 const uint32_t num_frames_with_source = 1; 1559 process->GetStatus(strm); 1560 process->GetThreadStatus (strm, 1561 only_threads_with_stop_reason, 1562 start_frame, 1563 num_frames, 1564 num_frames_with_source); 1565 return result.Succeeded(); 1566 } 1567}; 1568 1569//------------------------------------------------------------------------- 1570// CommandObjectProcessHandle 1571//------------------------------------------------------------------------- 1572#pragma mark CommandObjectProcessHandle 1573 1574class CommandObjectProcessHandle : public CommandObjectParsed 1575{ 1576public: 1577 class CommandOptions : public Options 1578 { 1579 public: 1580 CommandOptions (CommandInterpreter &interpreter) : 1581 Options (interpreter) 1582 { 1583 OptionParsingStarting (); 1584 } 1585 1586 ~CommandOptions() override = default; 1587 1588 Error 1589 SetOptionValue (uint32_t option_idx, const char *option_arg) override 1590 { 1591 Error error; 1592 const int short_option = m_getopt_table[option_idx].val; 1593 1594 switch (short_option) 1595 { 1596 case 's': 1597 stop = option_arg; 1598 break; 1599 case 'n': 1600 notify = option_arg; 1601 break; 1602 case 'p': 1603 pass = option_arg; 1604 break; 1605 default: 1606 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1607 break; 1608 } 1609 return error; 1610 } 1611 1612 void 1613 OptionParsingStarting () override 1614 { 1615 stop.clear(); 1616 notify.clear(); 1617 pass.clear(); 1618 } 1619 1620 const OptionDefinition* 1621 GetDefinitions () override 1622 { 1623 return g_option_table; 1624 } 1625 1626 // Options table: Required for subclasses of Options. 1627 1628 static OptionDefinition g_option_table[]; 1629 1630 // Instance variables to hold the values for command options. 1631 1632 std::string stop; 1633 std::string notify; 1634 std::string pass; 1635 }; 1636 1637 CommandObjectProcessHandle(CommandInterpreter &interpreter) 1638 : CommandObjectParsed( 1639 interpreter, "process handle", 1640 "Manage LLDB handling of OS signals for the current target process. Defaults to showing current policy.", 1641 nullptr), 1642 m_options(interpreter) 1643 { 1644 SetHelpLong ("\nIf no signals are specified, update them all. If no update " 1645 "option is specified, list the current values."); 1646 CommandArgumentEntry arg; 1647 CommandArgumentData signal_arg; 1648 1649 signal_arg.arg_type = eArgTypeUnixSignal; 1650 signal_arg.arg_repetition = eArgRepeatStar; 1651 1652 arg.push_back (signal_arg); 1653 1654 m_arguments.push_back (arg); 1655 } 1656 1657 ~CommandObjectProcessHandle() override = default; 1658 1659 Options * 1660 GetOptions () override 1661 { 1662 return &m_options; 1663 } 1664 1665 bool 1666 VerifyCommandOptionValue (const std::string &option, int &real_value) 1667 { 1668 bool okay = true; 1669 bool success = false; 1670 bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 1671 1672 if (success && tmp_value) 1673 real_value = 1; 1674 else if (success && !tmp_value) 1675 real_value = 0; 1676 else 1677 { 1678 // If the value isn't 'true' or 'false', it had better be 0 or 1. 1679 real_value = StringConvert::ToUInt32 (option.c_str(), 3); 1680 if (real_value != 0 && real_value != 1) 1681 okay = false; 1682 } 1683 1684 return okay; 1685 } 1686 1687 void 1688 PrintSignalHeader (Stream &str) 1689 { 1690 str.Printf ("NAME PASS STOP NOTIFY\n"); 1691 str.Printf ("=========== ===== ===== ======\n"); 1692 } 1693 1694 void 1695 PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp) 1696 { 1697 bool stop; 1698 bool suppress; 1699 bool notify; 1700 1701 str.Printf ("%-11s ", sig_name); 1702 if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) 1703 { 1704 bool pass = !suppress; 1705 str.Printf ("%s %s %s", 1706 (pass ? "true " : "false"), 1707 (stop ? "true " : "false"), 1708 (notify ? "true " : "false")); 1709 } 1710 str.Printf ("\n"); 1711 } 1712 1713 void 1714 PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp) 1715 { 1716 PrintSignalHeader (str); 1717 1718 if (num_valid_signals > 0) 1719 { 1720 size_t num_args = signal_args.GetArgumentCount(); 1721 for (size_t i = 0; i < num_args; ++i) 1722 { 1723 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); 1724 if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1725 PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp); 1726 } 1727 } 1728 else // Print info for ALL signals 1729 { 1730 int32_t signo = signals_sp->GetFirstSignalNumber(); 1731 while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1732 { 1733 PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp); 1734 signo = signals_sp->GetNextSignalNumber(signo); 1735 } 1736 } 1737 } 1738 1739protected: 1740 bool 1741 DoExecute (Args &signal_args, CommandReturnObject &result) override 1742 { 1743 TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 1744 1745 if (!target_sp) 1746 { 1747 result.AppendError ("No current target;" 1748 " cannot handle signals until you have a valid target and process.\n"); 1749 result.SetStatus (eReturnStatusFailed); 1750 return false; 1751 } 1752 1753 ProcessSP process_sp = target_sp->GetProcessSP(); 1754 1755 if (!process_sp) 1756 { 1757 result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 1758 result.SetStatus (eReturnStatusFailed); 1759 return false; 1760 } 1761 1762 int stop_action = -1; // -1 means leave the current setting alone 1763 int pass_action = -1; // -1 means leave the current setting alone 1764 int notify_action = -1; // -1 means leave the current setting alone 1765 1766 if (! m_options.stop.empty() 1767 && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 1768 { 1769 result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 1770 result.SetStatus (eReturnStatusFailed); 1771 return false; 1772 } 1773 1774 if (! m_options.notify.empty() 1775 && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 1776 { 1777 result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 1778 result.SetStatus (eReturnStatusFailed); 1779 return false; 1780 } 1781 1782 if (! m_options.pass.empty() 1783 && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 1784 { 1785 result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 1786 result.SetStatus (eReturnStatusFailed); 1787 return false; 1788 } 1789 1790 size_t num_args = signal_args.GetArgumentCount(); 1791 UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); 1792 int num_signals_set = 0; 1793 1794 if (num_args > 0) 1795 { 1796 for (size_t i = 0; i < num_args; ++i) 1797 { 1798 int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); 1799 if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1800 { 1801 // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 1802 // the value is either 0 or 1. 1803 if (stop_action != -1) 1804 signals_sp->SetShouldStop(signo, stop_action); 1805 if (pass_action != -1) 1806 { 1807 bool suppress = !pass_action; 1808 signals_sp->SetShouldSuppress(signo, suppress); 1809 } 1810 if (notify_action != -1) 1811 signals_sp->SetShouldNotify(signo, notify_action); 1812 ++num_signals_set; 1813 } 1814 else 1815 { 1816 result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 1817 } 1818 } 1819 } 1820 else 1821 { 1822 // No signal specified, if any command options were specified, update ALL signals. 1823 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 1824 { 1825 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 1826 { 1827 int32_t signo = signals_sp->GetFirstSignalNumber(); 1828 while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1829 { 1830 if (notify_action != -1) 1831 signals_sp->SetShouldNotify(signo, notify_action); 1832 if (stop_action != -1) 1833 signals_sp->SetShouldStop(signo, stop_action); 1834 if (pass_action != -1) 1835 { 1836 bool suppress = !pass_action; 1837 signals_sp->SetShouldSuppress(signo, suppress); 1838 } 1839 signo = signals_sp->GetNextSignalNumber(signo); 1840 } 1841 } 1842 } 1843 } 1844 1845 PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp); 1846 1847 if (num_signals_set > 0) 1848 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1849 else 1850 result.SetStatus (eReturnStatusFailed); 1851 1852 return result.Succeeded(); 1853 } 1854 1855 CommandOptions m_options; 1856}; 1857 1858OptionDefinition 1859CommandObjectProcessHandle::CommandOptions::g_option_table[] = 1860{ 1861{ 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." }, 1862{ 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." }, 1863{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 1864{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 1865}; 1866 1867//------------------------------------------------------------------------- 1868// CommandObjectMultiwordProcess 1869//------------------------------------------------------------------------- 1870 1871CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter) 1872 : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.", 1873 "process <subcommand> [<subcommand-options>]") 1874{ 1875 LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1876 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1877 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1878 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); 1879 LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1880 LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); 1881 LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); 1882 LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 1883 LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1884 LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1885 LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1886 LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 1887 LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter))); 1888 LoadSubCommand ("save-core", CommandObjectSP (new CommandObjectProcessSaveCore (interpreter))); 1889} 1890 1891CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default; 1892