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/Target/Process.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/Thread.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //------------------------------------------------------------------------- 30 // CommandObjectProcessLaunch 31 //------------------------------------------------------------------------- 32 33 class CommandObjectProcessLaunch : public CommandObject 34 { 35 public: 36 37 class CommandOptions : public Options 38 { 39 public: 40 41 CommandOptions () : 42 Options() 43 { 44 // Keep default values of all options in one place: ResetOptionValues () 45 ResetOptionValues (); 46 } 47 48 ~CommandOptions () 49 { 50 } 51 52 Error 53 SetOptionValue (int option_idx, const char *option_arg) 54 { 55 Error error; 56 char short_option = (char) m_getopt_table[option_idx].val; 57 58 switch (short_option) 59 { 60 case 's': stop_at_entry = true; break; 61 case 'e': stderr_path = option_arg; break; 62 case 'i': stdin_path = option_arg; break; 63 case 'o': stdout_path = option_arg; break; 64 case 'p': plugin_name = option_arg; break; 65 case 't': in_new_tty = true; break; 66 default: 67 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 68 break; 69 70 } 71 return error; 72 } 73 74 void 75 ResetOptionValues () 76 { 77 Options::ResetOptionValues(); 78 stop_at_entry = false; 79 in_new_tty = false; 80 stdin_path.clear(); 81 stdout_path.clear(); 82 stderr_path.clear(); 83 plugin_name.clear(); 84 } 85 86 const lldb::OptionDefinition* 87 GetDefinitions () 88 { 89 return g_option_table; 90 } 91 92 // Options table: Required for subclasses of Options. 93 94 static lldb::OptionDefinition g_option_table[]; 95 96 // Instance variables to hold the values for command options. 97 98 bool stop_at_entry; 99 bool in_new_tty; 100 std::string stderr_path; 101 std::string stdin_path; 102 std::string stdout_path; 103 std::string plugin_name; 104 105 }; 106 107 CommandObjectProcessLaunch (CommandInterpreter &interpreter) : 108 CommandObject (interpreter, 109 "process launch", 110 "Launch the executable in the debugger.", 111 NULL) 112 { 113 CommandArgumentEntry arg; 114 CommandArgumentData run_args_arg; 115 116 // Define the first (and only) variant of this arg. 117 run_args_arg.arg_type = eArgTypeRunArgs; 118 run_args_arg.arg_repetition = eArgRepeatOptional; 119 120 // There is only one variant this argument could be; put it into the argument entry. 121 arg.push_back (run_args_arg); 122 123 // Push the data for the first argument into the m_arguments vector. 124 m_arguments.push_back (arg); 125 } 126 127 128 ~CommandObjectProcessLaunch () 129 { 130 } 131 132 Options * 133 GetOptions () 134 { 135 return &m_options; 136 } 137 138 bool 139 Execute (Args& launch_args, CommandReturnObject &result) 140 { 141 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 142 143 if (target == NULL) 144 { 145 result.AppendError ("invalid target, set executable file using 'file' command"); 146 result.SetStatus (eReturnStatusFailed); 147 return false; 148 } 149 150 // If our listener is NULL, users aren't allows to launch 151 char filename[PATH_MAX]; 152 const Module *exe_module = target->GetExecutableModule().get(); 153 exe_module->GetFileSpec().GetPath(filename, sizeof(filename)); 154 155 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 156 if (process && process->IsAlive()) 157 { 158 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", 159 process->GetID()); 160 result.SetStatus (eReturnStatusFailed); 161 return false; 162 } 163 164 const char *plugin_name; 165 if (!m_options.plugin_name.empty()) 166 plugin_name = m_options.plugin_name.c_str(); 167 else 168 plugin_name = NULL; 169 170 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 171 172 if (process == NULL) 173 { 174 result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n"); 175 result.SetStatus (eReturnStatusFailed); 176 return false; 177 } 178 179 // If no launch args were given on the command line, then use any that 180 // might have been set using the "run-args" set variable. 181 if (launch_args.GetArgumentCount() == 0) 182 { 183 if (process->GetRunArguments().GetArgumentCount() > 0) 184 launch_args = process->GetRunArguments(); 185 } 186 187 if (m_options.in_new_tty) 188 { 189 char exec_file_path[PATH_MAX]; 190 if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path))) 191 { 192 launch_args.InsertArgumentAtIndex(0, exec_file_path); 193 } 194 else 195 { 196 result.AppendError("invalid executable"); 197 result.SetStatus (eReturnStatusFailed); 198 return false; 199 } 200 } 201 202 Args environment; 203 204 process->GetEnvironmentAsArgs (environment); 205 206 uint32_t launch_flags = eLaunchFlagNone; 207 208 if (process->GetDisableASLR()) 209 launch_flags |= eLaunchFlagDisableASLR; 210 211 const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; 212 const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; 213 214 Error error; 215 216 if (m_options.in_new_tty) 217 { 218 219 lldb::pid_t terminal_pid = Host::LaunchInNewTerminal (inferior_argv, 220 inferior_envp, 221 &exe_module->GetArchitecture(), 222 true, 223 process->GetDisableASLR()); 224 225 // Let the app get launched and stopped... 226 const char *process_name = exe_module->GetFileSpec().GetFilename().AsCString("<invalid>"); 227 228 if (terminal_pid == LLDB_INVALID_PROCESS_ID) 229 { 230 error.SetErrorStringWithFormat ("failed to launch '%s' in new terminal", process_name); 231 } 232 else 233 { 234 for (int i=0; i<20; i++) 235 { 236 usleep (250000); 237 error = process->Attach (process_name, false); 238 if (error.Success()) 239 break; 240 } 241 } 242 } 243 else 244 { 245 const char * stdin_path = NULL; 246 const char * stdout_path = NULL; 247 const char * stderr_path = NULL; 248 249 // Were any standard input/output/error paths given on the command line? 250 if (m_options.stdin_path.empty() && 251 m_options.stdout_path.empty() && 252 m_options.stderr_path.empty()) 253 { 254 // No standard file handles were given on the command line, check 255 // with the process object in case they were give using "set settings" 256 stdin_path = process->GetStandardInputPath(); 257 stdout_path = process->GetStandardOutputPath(); 258 stderr_path = process->GetStandardErrorPath(); 259 } 260 else 261 { 262 stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str(); 263 stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str(); 264 stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); 265 } 266 267 if (stdin_path == NULL) 268 stdin_path = "/dev/null"; 269 if (stdout_path == NULL) 270 stdout_path = "/dev/null"; 271 if (stderr_path == NULL) 272 stderr_path = "/dev/null"; 273 274 error = process->Launch (inferior_argv, 275 inferior_envp, 276 launch_flags, 277 stdin_path, 278 stdout_path, 279 stderr_path); 280 } 281 282 if (error.Success()) 283 { 284 const char *archname = exe_module->GetArchitecture().AsCString(); 285 286 result.AppendMessageWithFormat ("Process %i launched: '%s' (%s)\n", process->GetID(), filename, archname); 287 result.SetDidChangeProcessState (true); 288 if (m_options.stop_at_entry == false) 289 { 290 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 291 StateType state = process->WaitForProcessToStop (NULL); 292 293 if (state == eStateStopped) 294 { 295 error = process->Resume(); 296 if (error.Success()) 297 { 298 bool synchronous_execution = m_interpreter.GetSynchronous (); 299 if (synchronous_execution) 300 { 301 state = process->WaitForProcessToStop (NULL); 302 result.SetDidChangeProcessState (true); 303 result.SetStatus (eReturnStatusSuccessFinishResult); 304 } 305 else 306 { 307 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 308 } 309 } 310 } 311 } 312 } 313 314 return result.Succeeded(); 315 } 316 317 virtual const char *GetRepeatCommand (Args ¤t_command_args, uint32_t index) 318 { 319 // No repeat for "process launch"... 320 return ""; 321 } 322 323 protected: 324 325 CommandOptions m_options; 326 }; 327 328 329 #define SET1 LLDB_OPT_SET_1 330 #define SET2 LLDB_OPT_SET_2 331 332 lldb::OptionDefinition 333 CommandObjectProcessLaunch::CommandOptions::g_option_table[] = 334 { 335 { SET1 | SET2, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, 336 { SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, 337 { SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, 338 { SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, 339 { SET1 | SET2, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 340 { SET2, false, "tty", 't', no_argument, NULL, 0, eArgTypeNone, "Start the process in a new terminal (tty)."}, 341 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 342 }; 343 344 #undef SET1 345 #undef SET2 346 347 //------------------------------------------------------------------------- 348 // CommandObjectProcessAttach 349 //------------------------------------------------------------------------- 350 351 class CommandObjectProcessAttach : public CommandObject 352 { 353 public: 354 355 class CommandOptions : public Options 356 { 357 public: 358 359 CommandOptions () : 360 Options() 361 { 362 // Keep default values of all options in one place: ResetOptionValues () 363 ResetOptionValues (); 364 } 365 366 ~CommandOptions () 367 { 368 } 369 370 Error 371 SetOptionValue (int option_idx, const char *option_arg) 372 { 373 Error error; 374 char short_option = (char) m_getopt_table[option_idx].val; 375 bool success = false; 376 switch (short_option) 377 { 378 case 'p': 379 pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); 380 if (!success || pid == LLDB_INVALID_PROCESS_ID) 381 { 382 error.SetErrorStringWithFormat("Invalid process ID '%s'.\n", option_arg); 383 } 384 break; 385 386 case 'P': 387 plugin_name = option_arg; 388 break; 389 390 case 'n': 391 name.assign(option_arg); 392 break; 393 394 case 'w': 395 waitfor = true; 396 break; 397 398 default: 399 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 400 break; 401 } 402 return error; 403 } 404 405 void 406 ResetOptionValues () 407 { 408 Options::ResetOptionValues(); 409 pid = LLDB_INVALID_PROCESS_ID; 410 name.clear(); 411 waitfor = false; 412 } 413 414 const lldb::OptionDefinition* 415 GetDefinitions () 416 { 417 return g_option_table; 418 } 419 420 virtual bool 421 HandleOptionArgumentCompletion (CommandInterpreter &interpeter, 422 Args &input, 423 int cursor_index, 424 int char_pos, 425 OptionElementVector &opt_element_vector, 426 int opt_element_index, 427 int match_start_point, 428 int max_return_elements, 429 bool &word_complete, 430 StringList &matches) 431 { 432 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; 433 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; 434 435 // We are only completing the name option for now... 436 437 const lldb::OptionDefinition *opt_defs = GetDefinitions(); 438 if (opt_defs[opt_defs_index].short_option == 'n') 439 { 440 // Are we in the name? 441 442 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise 443 // use the default plugin. 444 Process *process = interpeter.GetDebugger().GetExecutionContext().process; 445 bool need_to_delete_process = false; 446 447 const char *partial_name = NULL; 448 partial_name = input.GetArgumentAtIndex(opt_arg_pos); 449 450 if (process && process->IsAlive()) 451 return true; 452 453 Target *target = interpeter.GetDebugger().GetSelectedTarget().get(); 454 if (target == NULL) 455 { 456 // No target has been set yet, for now do host completion. Otherwise I don't know how we would 457 // figure out what the right target to use is... 458 std::vector<lldb::pid_t> pids; 459 Host::ListProcessesMatchingName (partial_name, matches, pids); 460 return true; 461 } 462 if (!process) 463 { 464 process = target->CreateProcess (interpeter.GetDebugger().GetListener(), partial_name).get(); 465 need_to_delete_process = true; 466 } 467 468 if (process) 469 { 470 matches.Clear(); 471 std::vector<lldb::pid_t> pids; 472 process->ListProcessesMatchingName (NULL, matches, pids); 473 if (need_to_delete_process) 474 target->DeleteCurrentProcess(); 475 return true; 476 } 477 } 478 479 return false; 480 } 481 482 // Options table: Required for subclasses of Options. 483 484 static lldb::OptionDefinition g_option_table[]; 485 486 // Instance variables to hold the values for command options. 487 488 lldb::pid_t pid; 489 std::string plugin_name; 490 std::string name; 491 bool waitfor; 492 }; 493 494 CommandObjectProcessAttach (CommandInterpreter &interpreter) : 495 CommandObject (interpreter, 496 "process attach", 497 "Attach to a process.", 498 "process attach <cmd-options>") 499 { 500 } 501 502 ~CommandObjectProcessAttach () 503 { 504 } 505 506 bool 507 Execute (Args& command, 508 CommandReturnObject &result) 509 { 510 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 511 512 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 513 if (process) 514 { 515 if (process->IsAlive()) 516 { 517 result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 518 process->GetID()); 519 result.SetStatus (eReturnStatusFailed); 520 return false; 521 } 522 } 523 524 if (target == NULL) 525 { 526 // If there isn't a current target create one. 527 TargetSP new_target_sp; 528 FileSpec emptyFileSpec; 529 ArchSpec emptyArchSpec; 530 Error error; 531 532 error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), 533 emptyFileSpec, 534 emptyArchSpec, 535 NULL, 536 false, 537 new_target_sp); 538 target = new_target_sp.get(); 539 if (target == NULL || error.Fail()) 540 { 541 result.AppendError(error.AsCString("Error creating empty target")); 542 return false; 543 } 544 m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); 545 } 546 547 // Record the old executable module, we want to issue a warning if the process of attaching changed the 548 // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) 549 550 ModuleSP old_exec_module_sp = target->GetExecutableModule(); 551 ArchSpec old_arch_spec = target->GetArchitecture(); 552 553 if (command.GetArgumentCount()) 554 { 555 result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); 556 result.SetStatus (eReturnStatusFailed); 557 } 558 else 559 { 560 const char *plugin_name = NULL; 561 562 if (!m_options.plugin_name.empty()) 563 plugin_name = m_options.plugin_name.c_str(); 564 565 process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); 566 567 if (process) 568 { 569 Error error; 570 int attach_pid = m_options.pid; 571 572 const char *wait_name = NULL; 573 574 if (m_options.name.empty()) 575 { 576 if (old_exec_module_sp) 577 { 578 wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString(); 579 } 580 } 581 else 582 { 583 wait_name = m_options.name.c_str(); 584 } 585 586 // If we are waiting for a process with this name to show up, do that first. 587 if (m_options.waitfor) 588 { 589 590 if (wait_name == NULL) 591 { 592 result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n"); 593 result.SetStatus (eReturnStatusFailed); 594 return false; 595 } 596 597 m_interpreter.GetDebugger().GetOutputStream().Printf("Waiting to attach to a process named \"%s\".\n", wait_name); 598 error = process->Attach (wait_name, m_options.waitfor); 599 if (error.Success()) 600 { 601 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 602 } 603 else 604 { 605 result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 606 wait_name, 607 error.AsCString()); 608 result.SetStatus (eReturnStatusFailed); 609 return false; 610 } 611 } 612 else 613 { 614 // If the process was specified by name look it up, so we can warn if there are multiple 615 // processes with this pid. 616 617 if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL) 618 { 619 std::vector<lldb::pid_t> pids; 620 StringList matches; 621 622 process->ListProcessesMatchingName(wait_name, matches, pids); 623 if (matches.GetSize() > 1) 624 { 625 result.AppendErrorWithFormat("More than one process named %s\n", wait_name); 626 result.SetStatus (eReturnStatusFailed); 627 return false; 628 } 629 else if (matches.GetSize() == 0) 630 { 631 result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name); 632 result.SetStatus (eReturnStatusFailed); 633 return false; 634 } 635 else 636 { 637 attach_pid = pids[0]; 638 } 639 640 } 641 642 if (attach_pid != LLDB_INVALID_PROCESS_ID) 643 { 644 error = process->Attach (attach_pid); 645 if (error.Success()) 646 { 647 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 648 } 649 else 650 { 651 result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 652 attach_pid, 653 error.AsCString()); 654 result.SetStatus (eReturnStatusFailed); 655 } 656 } 657 else 658 { 659 result.AppendErrorWithFormat ("No PID specified for attach\n", 660 attach_pid, 661 error.AsCString()); 662 result.SetStatus (eReturnStatusFailed); 663 664 } 665 } 666 } 667 } 668 669 if (result.Succeeded()) 670 { 671 // Okay, we're done. Last step is to warn if the executable module has changed: 672 if (!old_exec_module_sp) 673 { 674 char new_path[PATH_MAX + 1]; 675 target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); 676 677 result.AppendMessageWithFormat("Executable module set to \"%s\".\n", 678 new_path); 679 } 680 else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) 681 { 682 char old_path[PATH_MAX + 1]; 683 char new_path[PATH_MAX + 1]; 684 685 old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); 686 target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); 687 688 result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", 689 old_path, new_path); 690 } 691 692 if (!old_arch_spec.IsValid()) 693 { 694 result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); 695 } 696 else if (old_arch_spec != target->GetArchitecture()) 697 { 698 result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 699 old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); 700 } 701 } 702 return result.Succeeded(); 703 } 704 705 Options * 706 GetOptions () 707 { 708 return &m_options; 709 } 710 711 protected: 712 713 CommandOptions m_options; 714 }; 715 716 717 lldb::OptionDefinition 718 CommandObjectProcessAttach::CommandOptions::g_option_table[] = 719 { 720 { LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, 721 { LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, 722 { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, 723 { LLDB_OPT_SET_2, false, "waitfor",'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."}, 724 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 725 }; 726 727 //------------------------------------------------------------------------- 728 // CommandObjectProcessContinue 729 //------------------------------------------------------------------------- 730 731 class CommandObjectProcessContinue : public CommandObject 732 { 733 public: 734 735 CommandObjectProcessContinue (CommandInterpreter &interpreter) : 736 CommandObject (interpreter, 737 "process continue", 738 "Continue execution of all threads in the current process.", 739 "process continue", 740 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 741 { 742 } 743 744 745 ~CommandObjectProcessContinue () 746 { 747 } 748 749 bool 750 Execute (Args& command, 751 CommandReturnObject &result) 752 { 753 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 754 bool synchronous_execution = m_interpreter.GetSynchronous (); 755 756 if (process == NULL) 757 { 758 result.AppendError ("no process to continue"); 759 result.SetStatus (eReturnStatusFailed); 760 return false; 761 } 762 763 StateType state = process->GetState(); 764 if (state == eStateStopped) 765 { 766 if (command.GetArgumentCount() != 0) 767 { 768 result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str()); 769 result.SetStatus (eReturnStatusFailed); 770 return false; 771 } 772 773 const uint32_t num_threads = process->GetThreadList().GetSize(); 774 775 // Set the actions that the threads should each take when resuming 776 for (uint32_t idx=0; idx<num_threads; ++idx) 777 { 778 process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); 779 } 780 781 Error error(process->Resume()); 782 if (error.Success()) 783 { 784 result.AppendMessageWithFormat ("Process %i resuming\n", process->GetID()); 785 if (synchronous_execution) 786 { 787 state = process->WaitForProcessToStop (NULL); 788 789 result.SetDidChangeProcessState (true); 790 result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); 791 result.SetStatus (eReturnStatusSuccessFinishNoResult); 792 } 793 else 794 { 795 result.SetStatus (eReturnStatusSuccessContinuingNoResult); 796 } 797 } 798 else 799 { 800 result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString()); 801 result.SetStatus (eReturnStatusFailed); 802 } 803 } 804 else 805 { 806 result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n", 807 StateAsCString(state)); 808 result.SetStatus (eReturnStatusFailed); 809 } 810 return result.Succeeded(); 811 } 812 }; 813 814 //------------------------------------------------------------------------- 815 // CommandObjectProcessDetach 816 //------------------------------------------------------------------------- 817 818 class CommandObjectProcessDetach : public CommandObject 819 { 820 public: 821 822 CommandObjectProcessDetach (CommandInterpreter &interpreter) : 823 CommandObject (interpreter, 824 "process detach", 825 "Detach from the current process being debugged.", 826 "process detach", 827 eFlagProcessMustBeLaunched) 828 { 829 } 830 831 ~CommandObjectProcessDetach () 832 { 833 } 834 835 bool 836 Execute (Args& command, 837 CommandReturnObject &result) 838 { 839 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 840 if (process == NULL) 841 { 842 result.AppendError ("must have a valid process in order to detach"); 843 result.SetStatus (eReturnStatusFailed); 844 return false; 845 } 846 847 Error error (process->Detach()); 848 if (error.Success()) 849 { 850 result.SetStatus (eReturnStatusSuccessFinishResult); 851 } 852 else 853 { 854 result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString()); 855 result.SetStatus (eReturnStatusFailed); 856 return false; 857 } 858 return result.Succeeded(); 859 } 860 }; 861 862 //------------------------------------------------------------------------- 863 // CommandObjectProcessSignal 864 //------------------------------------------------------------------------- 865 866 class CommandObjectProcessSignal : public CommandObject 867 { 868 public: 869 870 CommandObjectProcessSignal (CommandInterpreter &interpreter) : 871 CommandObject (interpreter, 872 "process signal", 873 "Send a UNIX signal to the current process being debugged.", 874 NULL) 875 { 876 CommandArgumentEntry arg; 877 CommandArgumentData signal_arg; 878 879 // Define the first (and only) variant of this arg. 880 signal_arg.arg_type = eArgTypeUnixSignalNumber; 881 signal_arg.arg_repetition = eArgRepeatPlain; 882 883 // There is only one variant this argument could be; put it into the argument entry. 884 arg.push_back (signal_arg); 885 886 // Push the data for the first argument into the m_arguments vector. 887 m_arguments.push_back (arg); 888 } 889 890 ~CommandObjectProcessSignal () 891 { 892 } 893 894 bool 895 Execute (Args& command, 896 CommandReturnObject &result) 897 { 898 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 899 if (process == NULL) 900 { 901 result.AppendError ("no process to signal"); 902 result.SetStatus (eReturnStatusFailed); 903 return false; 904 } 905 906 if (command.GetArgumentCount() == 1) 907 { 908 int signo = LLDB_INVALID_SIGNAL_NUMBER; 909 910 const char *signal_name = command.GetArgumentAtIndex(0); 911 if (::isxdigit (signal_name[0])) 912 signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); 913 else 914 signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); 915 916 if (signo == LLDB_INVALID_SIGNAL_NUMBER) 917 { 918 result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0)); 919 result.SetStatus (eReturnStatusFailed); 920 } 921 else 922 { 923 Error error (process->Signal (signo)); 924 if (error.Success()) 925 { 926 result.SetStatus (eReturnStatusSuccessFinishResult); 927 } 928 else 929 { 930 result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString()); 931 result.SetStatus (eReturnStatusFailed); 932 } 933 } 934 } 935 else 936 { 937 result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: \n", m_cmd_name.c_str(), 938 m_cmd_syntax.c_str()); 939 result.SetStatus (eReturnStatusFailed); 940 } 941 return result.Succeeded(); 942 } 943 }; 944 945 946 //------------------------------------------------------------------------- 947 // CommandObjectProcessInterrupt 948 //------------------------------------------------------------------------- 949 950 class CommandObjectProcessInterrupt : public CommandObject 951 { 952 public: 953 954 955 CommandObjectProcessInterrupt (CommandInterpreter &interpreter) : 956 CommandObject (interpreter, 957 "process interrupt", 958 "Interrupt the current process being debugged.", 959 "process interrupt", 960 eFlagProcessMustBeLaunched) 961 { 962 } 963 964 ~CommandObjectProcessInterrupt () 965 { 966 } 967 968 bool 969 Execute (Args& command, 970 CommandReturnObject &result) 971 { 972 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 973 if (process == NULL) 974 { 975 result.AppendError ("no process to halt"); 976 result.SetStatus (eReturnStatusFailed); 977 return false; 978 } 979 980 if (command.GetArgumentCount() == 0) 981 { 982 Error error(process->Halt ()); 983 if (error.Success()) 984 { 985 result.SetStatus (eReturnStatusSuccessFinishResult); 986 987 // Maybe we should add a "SuspendThreadPlans so we 988 // can halt, and keep in place all the current thread plans. 989 process->GetThreadList().DiscardThreadPlans(); 990 } 991 else 992 { 993 result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString()); 994 result.SetStatus (eReturnStatusFailed); 995 } 996 } 997 else 998 { 999 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 1000 m_cmd_name.c_str(), 1001 m_cmd_syntax.c_str()); 1002 result.SetStatus (eReturnStatusFailed); 1003 } 1004 return result.Succeeded(); 1005 } 1006 }; 1007 1008 //------------------------------------------------------------------------- 1009 // CommandObjectProcessKill 1010 //------------------------------------------------------------------------- 1011 1012 class CommandObjectProcessKill : public CommandObject 1013 { 1014 public: 1015 1016 CommandObjectProcessKill (CommandInterpreter &interpreter) : 1017 CommandObject (interpreter, 1018 "process kill", 1019 "Terminate the current process being debugged.", 1020 "process kill", 1021 eFlagProcessMustBeLaunched) 1022 { 1023 } 1024 1025 ~CommandObjectProcessKill () 1026 { 1027 } 1028 1029 bool 1030 Execute (Args& command, 1031 CommandReturnObject &result) 1032 { 1033 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; 1034 if (process == NULL) 1035 { 1036 result.AppendError ("no process to kill"); 1037 result.SetStatus (eReturnStatusFailed); 1038 return false; 1039 } 1040 1041 if (command.GetArgumentCount() == 0) 1042 { 1043 Error error (process->Destroy()); 1044 if (error.Success()) 1045 { 1046 result.SetStatus (eReturnStatusSuccessFinishResult); 1047 } 1048 else 1049 { 1050 result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); 1051 result.SetStatus (eReturnStatusFailed); 1052 } 1053 } 1054 else 1055 { 1056 result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: \n", 1057 m_cmd_name.c_str(), 1058 m_cmd_syntax.c_str()); 1059 result.SetStatus (eReturnStatusFailed); 1060 } 1061 return result.Succeeded(); 1062 } 1063 }; 1064 1065 //------------------------------------------------------------------------- 1066 // CommandObjectProcessStatus 1067 //------------------------------------------------------------------------- 1068 class CommandObjectProcessStatus : public CommandObject 1069 { 1070 public: 1071 CommandObjectProcessStatus (CommandInterpreter &interpreter) : 1072 CommandObject (interpreter, 1073 "process status", 1074 "Show the current status and location of executing process.", 1075 "process status", 1076 0) 1077 { 1078 } 1079 1080 ~CommandObjectProcessStatus() 1081 { 1082 } 1083 1084 1085 bool 1086 Execute 1087 ( 1088 Args& command, 1089 CommandReturnObject &result 1090 ) 1091 { 1092 StreamString &output_stream = result.GetOutputStream(); 1093 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1094 ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 1095 if (exe_ctx.process) 1096 { 1097 const StateType state = exe_ctx.process->GetState(); 1098 if (StateIsStoppedState(state)) 1099 { 1100 if (state == eStateExited) 1101 { 1102 int exit_status = exe_ctx.process->GetExitStatus(); 1103 const char *exit_description = exe_ctx.process->GetExitDescription(); 1104 output_stream.Printf ("Process %d exited with status = %i (0x%8.8x) %s\n", 1105 exe_ctx.process->GetID(), 1106 exit_status, 1107 exit_status, 1108 exit_description ? exit_description : ""); 1109 } 1110 else 1111 { 1112 output_stream.Printf ("Process %d %s\n", exe_ctx.process->GetID(), StateAsCString (state)); 1113 if (exe_ctx.thread == NULL) 1114 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 1115 if (exe_ctx.thread != NULL) 1116 { 1117 DisplayThreadsInfo (m_interpreter, &exe_ctx, result, true, true); 1118 } 1119 else 1120 { 1121 result.AppendError ("No valid thread found in current process."); 1122 result.SetStatus (eReturnStatusFailed); 1123 } 1124 } 1125 } 1126 else 1127 { 1128 output_stream.Printf ("Process %d is running.\n", 1129 exe_ctx.process->GetID()); 1130 } 1131 } 1132 else 1133 { 1134 result.AppendError ("No current location or status available."); 1135 result.SetStatus (eReturnStatusFailed); 1136 } 1137 return result.Succeeded(); 1138 } 1139 }; 1140 1141 //------------------------------------------------------------------------- 1142 // CommandObjectProcessHandle 1143 //------------------------------------------------------------------------- 1144 1145 class CommandObjectProcessHandle : public CommandObject 1146 { 1147 public: 1148 1149 class CommandOptions : public Options 1150 { 1151 public: 1152 1153 CommandOptions () : 1154 Options () 1155 { 1156 ResetOptionValues (); 1157 } 1158 1159 ~CommandOptions () 1160 { 1161 } 1162 1163 Error 1164 SetOptionValue (int option_idx, const char *option_arg) 1165 { 1166 Error error; 1167 char short_option = (char) m_getopt_table[option_idx].val; 1168 1169 switch (short_option) 1170 { 1171 case 's': 1172 stop = option_arg; 1173 break; 1174 case 'n': 1175 notify = option_arg; 1176 break; 1177 case 'p': 1178 pass = option_arg; 1179 break; 1180 default: 1181 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 1182 break; 1183 } 1184 return error; 1185 } 1186 1187 void 1188 ResetOptionValues () 1189 { 1190 Options::ResetOptionValues(); 1191 stop.clear(); 1192 notify.clear(); 1193 pass.clear(); 1194 } 1195 1196 const lldb::OptionDefinition* 1197 GetDefinitions () 1198 { 1199 return g_option_table; 1200 } 1201 1202 // Options table: Required for subclasses of Options. 1203 1204 static lldb::OptionDefinition g_option_table[]; 1205 1206 // Instance variables to hold the values for command options. 1207 1208 std::string stop; 1209 std::string notify; 1210 std::string pass; 1211 }; 1212 1213 1214 CommandObjectProcessHandle (CommandInterpreter &interpreter) : 1215 CommandObject (interpreter, 1216 "process handle", 1217 "Show or update what the process and debugger should do with various signals received from the OS.", 1218 NULL) 1219 { 1220 SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); 1221 CommandArgumentEntry arg; 1222 CommandArgumentData signal_name_arg; 1223 1224 signal_name_arg.arg_type = eArgTypeSignalName; 1225 signal_name_arg.arg_repetition = eArgRepeatStar; 1226 1227 arg.push_back (signal_name_arg); 1228 1229 m_arguments.push_back (arg); 1230 } 1231 1232 ~CommandObjectProcessHandle () 1233 { 1234 } 1235 1236 Options * 1237 GetOptions () 1238 { 1239 return &m_options; 1240 } 1241 1242 bool 1243 VerifyCommandOptionValue (const std::string &option, int &real_value) 1244 { 1245 bool okay = true; 1246 1247 bool success = false; 1248 bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success); 1249 1250 if (success && tmp_value) 1251 real_value = 1; 1252 else if (success && !tmp_value) 1253 real_value = 0; 1254 else 1255 { 1256 // If the value isn't 'true' or 'false', it had better be 0 or 1. 1257 real_value = Args::StringToUInt32 (option.c_str(), 3); 1258 if (real_value != 0 && real_value != 1) 1259 okay = false; 1260 } 1261 1262 return okay; 1263 } 1264 1265 void 1266 PrintSignalHeader (Stream &str) 1267 { 1268 str.Printf ("NAME PASS STOP NOTIFY\n"); 1269 str.Printf ("========== ===== ===== ======\n"); 1270 } 1271 1272 void 1273 PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) 1274 { 1275 bool stop; 1276 bool suppress; 1277 bool notify; 1278 1279 str.Printf ("%-10s ", sig_name); 1280 if (signals.GetSignalInfo (signo, suppress, stop, notify)) 1281 { 1282 bool pass = !suppress; 1283 str.Printf ("%s %s %s", 1284 (pass ? "true " : "false"), 1285 (stop ? "true " : "false"), 1286 (notify ? "true " : "false")); 1287 } 1288 str.Printf ("\n"); 1289 } 1290 1291 void 1292 PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) 1293 { 1294 PrintSignalHeader (str); 1295 1296 if (num_valid_signals > 0) 1297 { 1298 size_t num_args = signal_args.GetArgumentCount(); 1299 for (size_t i = 0; i < num_args; ++i) 1300 { 1301 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 1302 if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1303 PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); 1304 } 1305 } 1306 else // Print info for ALL signals 1307 { 1308 int32_t signo = signals.GetFirstSignalNumber(); 1309 while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1310 { 1311 PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); 1312 signo = signals.GetNextSignalNumber (signo); 1313 } 1314 } 1315 } 1316 1317 bool 1318 Execute (Args &signal_args, CommandReturnObject &result) 1319 { 1320 TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 1321 1322 if (!target_sp) 1323 { 1324 result.AppendError ("No current target;" 1325 " cannot handle signals until you have a valid target and process.\n"); 1326 result.SetStatus (eReturnStatusFailed); 1327 return false; 1328 } 1329 1330 ProcessSP process_sp = target_sp->GetProcessSP(); 1331 1332 if (!process_sp) 1333 { 1334 result.AppendError ("No current process; cannot handle signals until you have a valid process.\n"); 1335 result.SetStatus (eReturnStatusFailed); 1336 return false; 1337 } 1338 1339 int stop_action = -1; // -1 means leave the current setting alone 1340 int pass_action = -1; // -1 means leave the current setting alone 1341 int notify_action = -1; // -1 means leave the current setting alone 1342 1343 if (! m_options.stop.empty() 1344 && ! VerifyCommandOptionValue (m_options.stop, stop_action)) 1345 { 1346 result.AppendError ("Invalid argument for command option --stop; must be true or false.\n"); 1347 result.SetStatus (eReturnStatusFailed); 1348 return false; 1349 } 1350 1351 if (! m_options.notify.empty() 1352 && ! VerifyCommandOptionValue (m_options.notify, notify_action)) 1353 { 1354 result.AppendError ("Invalid argument for command option --notify; must be true or false.\n"); 1355 result.SetStatus (eReturnStatusFailed); 1356 return false; 1357 } 1358 1359 if (! m_options.pass.empty() 1360 && ! VerifyCommandOptionValue (m_options.pass, pass_action)) 1361 { 1362 result.AppendError ("Invalid argument for command option --pass; must be true or false.\n"); 1363 result.SetStatus (eReturnStatusFailed); 1364 return false; 1365 } 1366 1367 size_t num_args = signal_args.GetArgumentCount(); 1368 UnixSignals &signals = process_sp->GetUnixSignals(); 1369 int num_signals_set = 0; 1370 1371 if (num_args > 0) 1372 { 1373 for (size_t i = 0; i < num_args; ++i) 1374 { 1375 int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); 1376 if (signo != LLDB_INVALID_SIGNAL_NUMBER) 1377 { 1378 // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees 1379 // the value is either 0 or 1. 1380 if (stop_action != -1) 1381 signals.SetShouldStop (signo, (bool) stop_action); 1382 if (pass_action != -1) 1383 { 1384 bool suppress = ! ((bool) pass_action); 1385 signals.SetShouldSuppress (signo, suppress); 1386 } 1387 if (notify_action != -1) 1388 signals.SetShouldNotify (signo, (bool) notify_action); 1389 ++num_signals_set; 1390 } 1391 else 1392 { 1393 result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i)); 1394 } 1395 } 1396 } 1397 else 1398 { 1399 // No signal specified, if any command options were specified, update ALL signals. 1400 if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) 1401 { 1402 if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) 1403 { 1404 int32_t signo = signals.GetFirstSignalNumber(); 1405 while (signo != LLDB_INVALID_SIGNAL_NUMBER) 1406 { 1407 if (notify_action != -1) 1408 signals.SetShouldNotify (signo, (bool) notify_action); 1409 if (stop_action != -1) 1410 signals.SetShouldStop (signo, (bool) stop_action); 1411 if (pass_action != -1) 1412 { 1413 bool suppress = ! ((bool) pass_action); 1414 signals.SetShouldSuppress (signo, suppress); 1415 } 1416 signo = signals.GetNextSignalNumber (signo); 1417 } 1418 } 1419 } 1420 } 1421 1422 PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); 1423 1424 if (num_signals_set > 0) 1425 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1426 else 1427 result.SetStatus (eReturnStatusFailed); 1428 1429 return result.Succeeded(); 1430 } 1431 1432 protected: 1433 1434 CommandOptions m_options; 1435 }; 1436 1437 lldb::OptionDefinition 1438 CommandObjectProcessHandle::CommandOptions::g_option_table[] = 1439 { 1440 { 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." }, 1441 { 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." }, 1442 { LLDB_OPT_SET_1, false, "pass", 'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, 1443 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1444 }; 1445 1446 //------------------------------------------------------------------------- 1447 // CommandObjectMultiwordProcess 1448 //------------------------------------------------------------------------- 1449 1450 CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter &interpreter) : 1451 CommandObjectMultiword (interpreter, 1452 "process", 1453 "A set of commands for operating on a process.", 1454 "process <subcommand> [<subcommand-options>]") 1455 { 1456 LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); 1457 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); 1458 LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); 1459 LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); 1460 LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); 1461 LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); 1462 LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); 1463 LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); 1464 LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); 1465 } 1466 1467 CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () 1468 { 1469 } 1470 1471