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