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