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