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