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