1//===-- Driver.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 "Driver.h" 11 12#include <getopt.h> 13#include <libgen.h> 14#include <sys/ioctl.h> 15#include <termios.h> 16#include <unistd.h> 17#include <string.h> 18#include <stdlib.h> 19#include <limits.h> 20#include <fcntl.h> 21#include <inttypes.h> 22 23#include <string> 24 25#include "IOChannel.h" 26#include "lldb/API/SBBreakpoint.h" 27#include "lldb/API/SBCommandInterpreter.h" 28#include "lldb/API/SBCommandReturnObject.h" 29#include "lldb/API/SBCommunication.h" 30#include "lldb/API/SBDebugger.h" 31#include "lldb/API/SBEvent.h" 32#include "lldb/API/SBHostOS.h" 33#include "lldb/API/SBListener.h" 34#include "lldb/API/SBStream.h" 35#include "lldb/API/SBTarget.h" 36#include "lldb/API/SBThread.h" 37#include "lldb/API/SBProcess.h" 38 39using namespace lldb; 40 41static void reset_stdin_termios (); 42static bool g_old_stdin_termios_is_valid = false; 43static struct termios g_old_stdin_termios; 44 45static char *g_debugger_name = (char *) ""; 46static Driver *g_driver = NULL; 47 48// In the Driver::MainLoop, we change the terminal settings. This function is 49// added as an atexit handler to make sure we clean them up. 50static void 51reset_stdin_termios () 52{ 53 if (g_old_stdin_termios_is_valid) 54 { 55 g_old_stdin_termios_is_valid = false; 56 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios); 57 } 58} 59 60typedef struct 61{ 62 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0 63 // then this option belongs to option set n. 64 bool required; // This option is required (in the current usage level) 65 const char * long_option; // Full name for this option. 66 int short_option; // Single character for this option. 67 int option_has_arg; // no_argument, required_argument or optional_argument 68 uint32_t completion_type; // Cookie the option class can use to do define the argument completion. 69 lldb::CommandArgumentType argument_type; // Type of argument this option takes 70 const char * usage_text; // Full text explaining what this options does and what (if any) argument to 71 // pass it. 72} OptionDefinition; 73 74#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5 75#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5 76 77static OptionDefinition g_options[] = 78{ 79 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone, 80 "Prints out the usage information for the LLDB debugger." }, 81 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone, 82 "Prints out the current version number of the LLDB debugger." }, 83 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture, 84 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must " 85 "be one of the architectures for which the program was compiled." }, 86 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename, 87 "Tells the debugger to use the file <filename> as the program to be debugged." }, 88 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename, 89 "Tells the debugger to use the fullpath to <path> as the core file." }, 90 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName, 91 "Tells the debugger to attach to a process with the given name." }, 92 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone, 93 "Tells the debugger to wait for a process with the given pid or name to launch before attaching." }, 94 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid, 95 "Tells the debugger to attach to a process with the given pid." }, 96 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang, 97 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. " 98 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python " 99 "extensions have been implemented." }, 100 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone, 101 "Tells the debugger to print out extra information for debugging itself." }, 102 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename, 103 "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." }, 104 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone, 105 "Tells the debugger to open source files using the host's \"external editor\" mechanism." }, 106 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone, 107 "Do not automatically parse any '.lldbinit' files." }, 108 { LLDB_3_TO_5, false, "no-use-colors" , 'o', no_argument , 0, eArgTypeNone, 109 "Do not use colors." }, 110 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone, 111 "Prints out the path to the lldb.py file for this version of lldb." }, 112 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL } 113}; 114 115static const uint32_t last_option_set_with_args = 2; 116 117Driver::Driver () : 118 SBBroadcaster ("Driver"), 119 m_debugger (SBDebugger::Create(false)), 120 m_editline_pty (), 121 m_editline_slave_fh (NULL), 122 m_editline_reader (), 123 m_io_channel_ap (), 124 m_option_data (), 125 m_executing_user_command (false), 126 m_waiting_for_command (false), 127 m_done(false) 128{ 129 // We want to be able to handle CTRL+D in the terminal to have it terminate 130 // certain input 131 m_debugger.SetCloseInputOnEOF (false); 132 g_debugger_name = (char *) m_debugger.GetInstanceName(); 133 if (g_debugger_name == NULL) 134 g_debugger_name = (char *) ""; 135 g_driver = this; 136} 137 138Driver::~Driver () 139{ 140 g_driver = NULL; 141 g_debugger_name = NULL; 142} 143 144void 145Driver::CloseIOChannelFile () 146{ 147 // Write an End of File sequence to the file descriptor to ensure any 148 // read functions can exit. 149 char eof_str[] = "\x04"; 150 ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str)); 151 152 m_editline_pty.CloseMasterFileDescriptor(); 153 154 if (m_editline_slave_fh) 155 { 156 ::fclose (m_editline_slave_fh); 157 m_editline_slave_fh = NULL; 158 } 159} 160 161// This function takes INDENT, which tells how many spaces to output at the front 162// of each line; TEXT, which is the text that is to be output. It outputs the 163// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the 164// front of each line. It breaks lines on spaces, tabs or newlines, shortening 165// the line if necessary to not break in the middle of a word. It assumes that 166// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters. 167 168void 169OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns) 170{ 171 int len = strlen (text); 172 std::string text_string (text); 173 174 // Force indentation to be reasonable. 175 if (indent >= output_max_columns) 176 indent = 0; 177 178 // Will it all fit on one line? 179 180 if (len + indent < output_max_columns) 181 // Output as a single line 182 fprintf (out, "%*s%s\n", indent, "", text); 183 else 184 { 185 // We need to break it up into multiple lines. 186 int text_width = output_max_columns - indent - 1; 187 int start = 0; 188 int end = start; 189 int final_end = len; 190 int sub_len; 191 192 while (end < final_end) 193 { 194 // Dont start the 'text' on a space, since we're already outputting the indentation. 195 while ((start < final_end) && (text[start] == ' ')) 196 start++; 197 198 end = start + text_width; 199 if (end > final_end) 200 end = final_end; 201 else 202 { 203 // If we're not at the end of the text, make sure we break the line on white space. 204 while (end > start 205 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 206 end--; 207 } 208 sub_len = end - start; 209 std::string substring = text_string.substr (start, sub_len); 210 fprintf (out, "%*s%s\n", indent, "", substring.c_str()); 211 start = end + 1; 212 } 213 } 214} 215 216void 217ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data) 218{ 219 uint32_t screen_width = 80; 220 uint32_t indent_level = 0; 221 const char *name = "lldb"; 222 223 fprintf (out, "\nUsage:\n\n"); 224 225 indent_level += 2; 226 227 228 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0] 229 // <cmd> [options-for-level-1] 230 // etc. 231 232 uint32_t num_options; 233 uint32_t num_option_sets = 0; 234 235 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options) 236 { 237 uint32_t this_usage_mask = option_table[num_options].usage_mask; 238 if (this_usage_mask == LLDB_OPT_SET_ALL) 239 { 240 if (num_option_sets == 0) 241 num_option_sets = 1; 242 } 243 else 244 { 245 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) 246 { 247 if (this_usage_mask & 1 << j) 248 { 249 if (num_option_sets <= j) 250 num_option_sets = j + 1; 251 } 252 } 253 } 254 } 255 256 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++) 257 { 258 uint32_t opt_set_mask; 259 260 opt_set_mask = 1 << opt_set; 261 262 if (opt_set > 0) 263 fprintf (out, "\n"); 264 fprintf (out, "%*s%s", indent_level, "", name); 265 bool is_help_line = false; 266 267 for (uint32_t i = 0; i < num_options; ++i) 268 { 269 if (option_table[i].usage_mask & opt_set_mask) 270 { 271 CommandArgumentType arg_type = option_table[i].argument_type; 272 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type); 273 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet... 274 // so we do it by hand here. 275 if (option_table[i].short_option == 'h') 276 is_help_line = true; 277 278 if (option_table[i].required) 279 { 280 if (option_table[i].option_has_arg == required_argument) 281 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name); 282 else if (option_table[i].option_has_arg == optional_argument) 283 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name); 284 else 285 fprintf (out, " -%c", option_table[i].short_option); 286 } 287 else 288 { 289 if (option_table[i].option_has_arg == required_argument) 290 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name); 291 else if (option_table[i].option_has_arg == optional_argument) 292 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name); 293 else 294 fprintf (out, " [-%c]", option_table[i].short_option); 295 } 296 } 297 } 298 if (!is_help_line && (opt_set <= last_option_set_with_args)) 299 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]"); 300 } 301 302 fprintf (out, "\n\n"); 303 304 // Now print out all the detailed information about the various options: long form, short form and help text: 305 // -- long_name <argument> 306 // - short <argument> 307 // help text 308 309 // This variable is used to keep track of which options' info we've printed out, because some options can be in 310 // more than one usage level, but we only want to print the long form of its information once. 311 312 Driver::OptionData::OptionSet options_seen; 313 Driver::OptionData::OptionSet::iterator pos; 314 315 indent_level += 5; 316 317 for (uint32_t i = 0; i < num_options; ++i) 318 { 319 // Only print this option if we haven't already seen it. 320 pos = options_seen.find (option_table[i].short_option); 321 if (pos == options_seen.end()) 322 { 323 CommandArgumentType arg_type = option_table[i].argument_type; 324 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type); 325 326 options_seen.insert (option_table[i].short_option); 327 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option); 328 if (arg_type != eArgTypeNone) 329 fprintf (out, "<%s>", arg_name); 330 fprintf (out, "\n"); 331 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option); 332 if (arg_type != eArgTypeNone) 333 fprintf (out, "<%s>", arg_name); 334 fprintf (out, "\n"); 335 indent_level += 5; 336 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width); 337 indent_level -= 5; 338 fprintf (out, "\n"); 339 } 340 } 341 342 indent_level -= 5; 343 344 fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged" 345 "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works." 346 "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n", 347 indent_level, "", 348 indent_level, "", 349 name, 350 indent_level, ""); 351} 352 353void 354BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table, 355 uint32_t num_options) 356{ 357 if (num_options == 0) 358 return; 359 360 uint32_t i; 361 uint32_t j; 362 std::bitset<256> option_seen; 363 364 getopt_table.resize (num_options + 1); 365 366 for (i = 0, j = 0; i < num_options; ++i) 367 { 368 char short_opt = expanded_option_table[i].short_option; 369 370 if (option_seen.test(short_opt) == false) 371 { 372 getopt_table[j].name = expanded_option_table[i].long_option; 373 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg; 374 getopt_table[j].flag = NULL; 375 getopt_table[j].val = expanded_option_table[i].short_option; 376 option_seen.set(short_opt); 377 ++j; 378 } 379 } 380 381 getopt_table[j].name = NULL; 382 getopt_table[j].has_arg = 0; 383 getopt_table[j].flag = NULL; 384 getopt_table[j].val = 0; 385 386} 387 388Driver::OptionData::OptionData () : 389 m_args(), 390 m_script_lang (lldb::eScriptLanguageDefault), 391 m_core_file (), 392 m_crash_log (), 393 m_source_command_files (), 394 m_debug_mode (false), 395 m_print_version (false), 396 m_print_python_path (false), 397 m_print_help (false), 398 m_wait_for(false), 399 m_process_name(), 400 m_process_pid(LLDB_INVALID_PROCESS_ID), 401 m_use_external_editor(false), 402 m_seen_options() 403{ 404} 405 406Driver::OptionData::~OptionData () 407{ 408} 409 410void 411Driver::OptionData::Clear () 412{ 413 m_args.clear (); 414 m_script_lang = lldb::eScriptLanguageDefault; 415 m_source_command_files.clear (); 416 m_debug_mode = false; 417 m_print_help = false; 418 m_print_version = false; 419 m_print_python_path = false; 420 m_use_external_editor = false; 421 m_wait_for = false; 422 m_process_name.erase(); 423 m_process_pid = LLDB_INVALID_PROCESS_ID; 424} 425 426void 427Driver::ResetOptionValues () 428{ 429 m_option_data.Clear (); 430} 431 432const char * 433Driver::GetFilename() const 434{ 435 if (m_option_data.m_args.empty()) 436 return NULL; 437 return m_option_data.m_args.front().c_str(); 438} 439 440const char * 441Driver::GetCrashLogFilename() const 442{ 443 if (m_option_data.m_crash_log.empty()) 444 return NULL; 445 return m_option_data.m_crash_log.c_str(); 446} 447 448lldb::ScriptLanguage 449Driver::GetScriptLanguage() const 450{ 451 return m_option_data.m_script_lang; 452} 453 454size_t 455Driver::GetNumSourceCommandFiles () const 456{ 457 return m_option_data.m_source_command_files.size(); 458} 459 460const char * 461Driver::GetSourceCommandFileAtIndex (uint32_t idx) const 462{ 463 if (idx < m_option_data.m_source_command_files.size()) 464 return m_option_data.m_source_command_files[idx].c_str(); 465 return NULL; 466} 467 468bool 469Driver::GetDebugMode() const 470{ 471 return m_option_data.m_debug_mode; 472} 473 474 475// Check the arguments that were passed to this program to make sure they are valid and to get their 476// argument values (if any). Return a boolean value indicating whether or not to start up the full 477// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR 478// if the user only wanted help or version information. 479 480SBError 481Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit) 482{ 483 ResetOptionValues (); 484 485 SBCommandReturnObject result; 486 487 SBError error; 488 std::string option_string; 489 struct option *long_options = NULL; 490 std::vector<struct option> long_options_vector; 491 uint32_t num_options; 492 493 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options) 494 /* Do Nothing. */; 495 496 if (num_options == 0) 497 { 498 if (argc > 1) 499 error.SetErrorStringWithFormat ("invalid number of options"); 500 return error; 501 } 502 503 BuildGetOptTable (g_options, long_options_vector, num_options); 504 505 if (long_options_vector.empty()) 506 long_options = NULL; 507 else 508 long_options = &long_options_vector.front(); 509 510 if (long_options == NULL) 511 { 512 error.SetErrorStringWithFormat ("invalid long options"); 513 return error; 514 } 515 516 // Build the option_string argument for call to getopt_long_only. 517 518 for (int i = 0; long_options[i].name != NULL; ++i) 519 { 520 if (long_options[i].flag == NULL) 521 { 522 option_string.push_back ((char) long_options[i].val); 523 switch (long_options[i].has_arg) 524 { 525 default: 526 case no_argument: 527 break; 528 case required_argument: 529 option_string.push_back (':'); 530 break; 531 case optional_argument: 532 option_string.append ("::"); 533 break; 534 } 535 } 536 } 537 538 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't 539 // know at that point whether we should read in init files yet. So we don't read them in in the 540 // Driver constructor, then set the flags back to "read them in" here, and then if we see the 541 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the 542 // main loop. 543 544 m_debugger.SkipLLDBInitFiles (false); 545 m_debugger.SkipAppInitFiles (false); 546 547 // Prepare for & make calls to getopt_long_only. 548#if __GLIBC__ 549 optind = 0; 550#else 551 optreset = 1; 552 optind = 1; 553#endif 554 int val; 555 while (1) 556 { 557 int long_options_index = -1; 558 val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index); 559 560 if (val == -1) 561 break; 562 else if (val == '?') 563 { 564 m_option_data.m_print_help = true; 565 error.SetErrorStringWithFormat ("unknown or ambiguous option"); 566 break; 567 } 568 else if (val == 0) 569 continue; 570 else 571 { 572 m_option_data.m_seen_options.insert ((char) val); 573 if (long_options_index == -1) 574 { 575 for (int i = 0; 576 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val; 577 ++i) 578 { 579 if (long_options[i].val == val) 580 { 581 long_options_index = i; 582 break; 583 } 584 } 585 } 586 587 if (long_options_index >= 0) 588 { 589 const int short_option = g_options[long_options_index].short_option; 590 591 switch (short_option) 592 { 593 case 'h': 594 m_option_data.m_print_help = true; 595 break; 596 597 case 'v': 598 m_option_data.m_print_version = true; 599 break; 600 601 case 'P': 602 m_option_data.m_print_python_path = true; 603 break; 604 605 case 'c': 606 { 607 SBFileSpec file(optarg); 608 if (file.Exists()) 609 { 610 m_option_data.m_core_file = optarg; 611 } 612 else 613 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg); 614 } 615 break; 616 617 case 'e': 618 m_option_data.m_use_external_editor = true; 619 break; 620 621 case 'x': 622 m_debugger.SkipLLDBInitFiles (true); 623 m_debugger.SkipAppInitFiles (true); 624 break; 625 626 case 'o': 627 m_debugger.SetUseColor (false); 628 break; 629 630 case 'f': 631 { 632 SBFileSpec file(optarg); 633 if (file.Exists()) 634 { 635 m_option_data.m_args.push_back (optarg); 636 } 637 else if (file.ResolveExecutableLocation()) 638 { 639 char path[PATH_MAX]; 640 file.GetPath (path, sizeof(path)); 641 m_option_data.m_args.push_back (path); 642 } 643 else 644 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg); 645 } 646 break; 647 648 case 'a': 649 if (!m_debugger.SetDefaultArchitecture (optarg)) 650 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg); 651 break; 652 653 case 'l': 654 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg); 655 break; 656 657 case 'd': 658 m_option_data.m_debug_mode = true; 659 break; 660 661 case 'n': 662 m_option_data.m_process_name = optarg; 663 break; 664 665 case 'w': 666 m_option_data.m_wait_for = true; 667 break; 668 669 case 'p': 670 { 671 char *remainder; 672 m_option_data.m_process_pid = strtol (optarg, &remainder, 0); 673 if (remainder == optarg || *remainder != '\0') 674 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.", 675 optarg); 676 } 677 break; 678 case 's': 679 { 680 SBFileSpec file(optarg); 681 if (file.Exists()) 682 m_option_data.m_source_command_files.push_back (optarg); 683 else if (file.ResolveExecutableLocation()) 684 { 685 char final_path[PATH_MAX]; 686 file.GetPath (final_path, sizeof(final_path)); 687 std::string path_str (final_path); 688 m_option_data.m_source_command_files.push_back (path_str); 689 } 690 else 691 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); 692 } 693 break; 694 695 default: 696 m_option_data.m_print_help = true; 697 error.SetErrorStringWithFormat ("unrecognized option %c", short_option); 698 break; 699 } 700 } 701 else 702 { 703 error.SetErrorStringWithFormat ("invalid option with value %i", val); 704 } 705 if (error.Fail()) 706 { 707 return error; 708 } 709 } 710 } 711 712 if (error.Fail() || m_option_data.m_print_help) 713 { 714 ShowUsage (out_fh, g_options, m_option_data); 715 exit = true; 716 } 717 else if (m_option_data.m_print_version) 718 { 719 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString()); 720 exit = true; 721 } 722 else if (m_option_data.m_print_python_path) 723 { 724 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath(); 725 if (python_file_spec.IsValid()) 726 { 727 char python_path[PATH_MAX]; 728 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX); 729 if (num_chars < PATH_MAX) 730 { 731 ::fprintf (out_fh, "%s\n", python_path); 732 } 733 else 734 ::fprintf (out_fh, "<PATH TOO LONG>\n"); 735 } 736 else 737 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n"); 738 exit = true; 739 } 740 else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) 741 { 742 // Any arguments that are left over after option parsing are for 743 // the program. If a file was specified with -f then the filename 744 // is already in the m_option_data.m_args array, and any remaining args 745 // are arguments for the inferior program. If no file was specified with 746 // -f, then what is left is the program name followed by any arguments. 747 748 // Skip any options we consumed with getopt_long_only 749 argc -= optind; 750 argv += optind; 751 752 if (argc > 0) 753 { 754 for (int arg_idx=0; arg_idx<argc; ++arg_idx) 755 { 756 const char *arg = argv[arg_idx]; 757 if (arg) 758 m_option_data.m_args.push_back (arg); 759 } 760 } 761 762 } 763 else 764 { 765 // Skip any options we consumed with getopt_long_only 766 argc -= optind; 767 //argv += optind; // Commented out to keep static analyzer happy 768 769 if (argc > 0) 770 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n"); 771 } 772 773 return error; 774} 775 776size_t 777Driver::GetProcessSTDOUT () 778{ 779 // The process has stuff waiting for stdout; get it and write it out to the appropriate place. 780 char stdio_buffer[1024]; 781 size_t len; 782 size_t total_bytes = 0; 783 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) 784 { 785 m_io_channel_ap->OutWrite (stdio_buffer, len, NO_ASYNC); 786 total_bytes += len; 787 } 788 return total_bytes; 789} 790 791size_t 792Driver::GetProcessSTDERR () 793{ 794 // The process has stuff waiting for stderr; get it and write it out to the appropriate place. 795 char stdio_buffer[1024]; 796 size_t len; 797 size_t total_bytes = 0; 798 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) 799 { 800 m_io_channel_ap->ErrWrite (stdio_buffer, len, NO_ASYNC); 801 total_bytes += len; 802 } 803 return total_bytes; 804} 805 806void 807Driver::UpdateSelectedThread () 808{ 809 using namespace lldb; 810 SBProcess process(m_debugger.GetSelectedTarget().GetProcess()); 811 if (process.IsValid()) 812 { 813 SBThread curr_thread (process.GetSelectedThread()); 814 SBThread thread; 815 StopReason curr_thread_stop_reason = eStopReasonInvalid; 816 curr_thread_stop_reason = curr_thread.GetStopReason(); 817 818 if (!curr_thread.IsValid() || 819 curr_thread_stop_reason == eStopReasonInvalid || 820 curr_thread_stop_reason == eStopReasonNone) 821 { 822 // Prefer a thread that has just completed its plan over another thread as current thread. 823 SBThread plan_thread; 824 SBThread other_thread; 825 const size_t num_threads = process.GetNumThreads(); 826 size_t i; 827 for (i = 0; i < num_threads; ++i) 828 { 829 thread = process.GetThreadAtIndex(i); 830 StopReason thread_stop_reason = thread.GetStopReason(); 831 switch (thread_stop_reason) 832 { 833 case eStopReasonInvalid: 834 case eStopReasonNone: 835 break; 836 837 case eStopReasonTrace: 838 case eStopReasonBreakpoint: 839 case eStopReasonWatchpoint: 840 case eStopReasonSignal: 841 case eStopReasonException: 842 case eStopReasonExec: 843 case eStopReasonThreadExiting: 844 if (!other_thread.IsValid()) 845 other_thread = thread; 846 break; 847 case eStopReasonPlanComplete: 848 if (!plan_thread.IsValid()) 849 plan_thread = thread; 850 break; 851 } 852 } 853 if (plan_thread.IsValid()) 854 process.SetSelectedThread (plan_thread); 855 else if (other_thread.IsValid()) 856 process.SetSelectedThread (other_thread); 857 else 858 { 859 if (curr_thread.IsValid()) 860 thread = curr_thread; 861 else 862 thread = process.GetThreadAtIndex(0); 863 864 if (thread.IsValid()) 865 process.SetSelectedThread (thread); 866 } 867 } 868 } 869} 870 871// This function handles events that were broadcast by the process. 872void 873Driver::HandleBreakpointEvent (const SBEvent &event) 874{ 875 using namespace lldb; 876 const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event); 877 878 if (event_type & eBreakpointEventTypeAdded 879 || event_type & eBreakpointEventTypeRemoved 880 || event_type & eBreakpointEventTypeEnabled 881 || event_type & eBreakpointEventTypeDisabled 882 || event_type & eBreakpointEventTypeCommandChanged 883 || event_type & eBreakpointEventTypeConditionChanged 884 || event_type & eBreakpointEventTypeIgnoreChanged 885 || event_type & eBreakpointEventTypeLocationsResolved) 886 { 887 // Don't do anything about these events, since the breakpoint commands already echo these actions. 888 } 889 else if (event_type & eBreakpointEventTypeLocationsAdded) 890 { 891 char message[256]; 892 uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event); 893 if (num_new_locations > 0) 894 { 895 SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event); 896 int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n", 897 num_new_locations, 898 num_new_locations == 1 ? "" : "s", 899 breakpoint.GetID()); 900 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 901 } 902 } 903 else if (event_type & eBreakpointEventTypeLocationsRemoved) 904 { 905 // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 906 } 907 else if (event_type & eBreakpointEventTypeLocationsResolved) 908 { 909 // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 910 } 911} 912 913// This function handles events that were broadcast by the process. 914void 915Driver::HandleProcessEvent (const SBEvent &event) 916{ 917 using namespace lldb; 918 const uint32_t event_type = event.GetType(); 919 920 if (event_type & SBProcess::eBroadcastBitSTDOUT) 921 { 922 // The process has stdout available, get it and write it out to the 923 // appropriate place. 924 GetProcessSTDOUT (); 925 } 926 else if (event_type & SBProcess::eBroadcastBitSTDERR) 927 { 928 // The process has stderr available, get it and write it out to the 929 // appropriate place. 930 GetProcessSTDERR (); 931 } 932 else if (event_type & SBProcess::eBroadcastBitStateChanged) 933 { 934 // Drain all stout and stderr so we don't see any output come after 935 // we print our prompts 936 GetProcessSTDOUT (); 937 GetProcessSTDERR (); 938 // Something changed in the process; get the event and report the process's current status and location to 939 // the user. 940 StateType event_state = SBProcess::GetStateFromEvent (event); 941 if (event_state == eStateInvalid) 942 return; 943 944 SBProcess process (SBProcess::GetProcessFromEvent (event)); 945 assert (process.IsValid()); 946 947 switch (event_state) 948 { 949 case eStateInvalid: 950 case eStateUnloaded: 951 case eStateConnected: 952 case eStateAttaching: 953 case eStateLaunching: 954 case eStateStepping: 955 case eStateDetached: 956 { 957 char message[1024]; 958 int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(), 959 m_debugger.StateAsCString (event_state)); 960 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 961 } 962 break; 963 964 case eStateRunning: 965 // Don't be chatty when we run... 966 break; 967 968 case eStateExited: 969 { 970 SBCommandReturnObject result; 971 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 972 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 973 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 974 } 975 break; 976 977 case eStateStopped: 978 case eStateCrashed: 979 case eStateSuspended: 980 // Make sure the program hasn't been auto-restarted: 981 if (SBProcess::GetRestartedFromEvent (event)) 982 { 983 size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event); 984 if (num_reasons > 0) 985 { 986 // FIXME: Do we want to report this, or would that just be annoyingly chatty? 987 if (num_reasons == 1) 988 { 989 char message[1024]; 990 const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0); 991 int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n", 992 process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>"); 993 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 994 } 995 else 996 { 997 char message[1024]; 998 int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n", 999 process.GetProcessID()); 1000 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 1001 for (size_t i = 0; i < num_reasons; i++) 1002 { 1003 const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i); 1004 int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>"); 1005 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 1006 } 1007 } 1008 } 1009 } 1010 else 1011 { 1012 if (GetDebugger().GetSelectedTarget() == process.GetTarget()) 1013 { 1014 SBCommandReturnObject result; 1015 UpdateSelectedThread (); 1016 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 1017 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 1018 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 1019 } 1020 else 1021 { 1022 SBStream out_stream; 1023 uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget()); 1024 if (target_idx != UINT32_MAX) 1025 out_stream.Printf ("Target %d: (", target_idx); 1026 else 1027 out_stream.Printf ("Target <unknown index>: ("); 1028 process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief); 1029 out_stream.Printf (") stopped.\n"); 1030 m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC); 1031 } 1032 } 1033 break; 1034 } 1035 } 1036} 1037 1038void 1039Driver::HandleThreadEvent (const SBEvent &event) 1040{ 1041 // At present the only thread event we handle is the Frame Changed event, and all we do for that is just 1042 // reprint the thread status for that thread. 1043 using namespace lldb; 1044 const uint32_t event_type = event.GetType(); 1045 if (event_type == SBThread::eBroadcastBitStackChanged 1046 || event_type == SBThread::eBroadcastBitThreadSelected) 1047 { 1048 SBThread thread = SBThread::GetThreadFromEvent (event); 1049 if (thread.IsValid()) 1050 { 1051 SBStream out_stream; 1052 thread.GetStatus(out_stream); 1053 m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC); 1054 } 1055 } 1056} 1057 1058// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit). 1059 1060bool 1061Driver::HandleIOEvent (const SBEvent &event) 1062{ 1063 bool quit = false; 1064 1065 const uint32_t event_type = event.GetType(); 1066 1067 if (event_type & IOChannel::eBroadcastBitHasUserInput) 1068 { 1069 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for 1070 // handling. 1071 1072 const char *command_string = SBEvent::GetCStringFromEvent(event); 1073 if (command_string == NULL) 1074 command_string = ""; 1075 SBCommandReturnObject result; 1076 1077 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd 1078 // output orderings and problems with the prompt. 1079 1080 // Note that we are in the process of executing a command 1081 m_executing_user_command = true; 1082 1083 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true); 1084 1085 // Note that we are back from executing a user command 1086 m_executing_user_command = false; 1087 1088 // Display any STDOUT/STDERR _prior_ to emitting the command result text 1089 GetProcessSTDOUT (); 1090 GetProcessSTDERR (); 1091 1092 const bool only_if_no_immediate = true; 1093 1094 // Now emit the command output text from the command we just executed 1095 const size_t output_size = result.GetOutputSize(); 1096 if (output_size > 0) 1097 m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC); 1098 1099 // Now emit the command error text from the command we just executed 1100 const size_t error_size = result.GetErrorSize(); 1101 if (error_size > 0) 1102 m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC); 1103 1104 // We are done getting and running our command, we can now clear the 1105 // m_waiting_for_command so we can get another one. 1106 m_waiting_for_command = false; 1107 1108 // If our editline input reader is active, it means another input reader 1109 // got pushed onto the input reader and caused us to become deactivated. 1110 // When the input reader above us gets popped, we will get re-activated 1111 // and our prompt will refresh in our callback 1112 if (m_editline_reader.IsActive()) 1113 { 1114 ReadyForCommand (); 1115 } 1116 } 1117 else if (event_type & IOChannel::eBroadcastBitUserInterrupt) 1118 { 1119 // This is here to handle control-c interrupts from the user. It has not yet really been implemented. 1120 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER 1121 //m_io_channel_ap->CancelInput(); 1122 // Anything else? Send Interrupt to process? 1123 } 1124 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 1125 (event_type & IOChannel::eBroadcastBitThreadDidExit)) 1126 { 1127 // If the IOChannel thread is trying to go away, then it is definitely 1128 // time to end the debugging session. 1129 quit = true; 1130 } 1131 1132 return quit; 1133} 1134 1135void 1136Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len) 1137{ 1138 Driver *driver = (Driver*)baton; 1139 driver->GetFromMaster ((const char *)src, src_len); 1140} 1141 1142void 1143Driver::GetFromMaster (const char *src, size_t src_len) 1144{ 1145 // Echo the characters back to the Debugger's stdout, that way if you 1146 // type characters while a command is running, you'll see what you've typed. 1147 FILE *out_fh = m_debugger.GetOutputFileHandle(); 1148 if (out_fh) 1149 ::fwrite (src, 1, src_len, out_fh); 1150} 1151 1152size_t 1153Driver::EditLineInputReaderCallback 1154( 1155 void *baton, 1156 SBInputReader *reader, 1157 InputReaderAction notification, 1158 const char *bytes, 1159 size_t bytes_len 1160) 1161{ 1162 Driver *driver = (Driver *)baton; 1163 1164 switch (notification) 1165 { 1166 case eInputReaderActivate: 1167 break; 1168 1169 case eInputReaderReactivate: 1170 if (driver->m_executing_user_command == false) 1171 driver->ReadyForCommand(); 1172 break; 1173 1174 case eInputReaderDeactivate: 1175 break; 1176 1177 case eInputReaderAsynchronousOutputWritten: 1178 if (driver->m_io_channel_ap.get() != NULL) 1179 driver->m_io_channel_ap->RefreshPrompt(); 1180 break; 1181 1182 case eInputReaderInterrupt: 1183 if (driver->m_io_channel_ap.get() != NULL) 1184 { 1185 SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess()); 1186 if (!driver->m_io_channel_ap->EditLineHasCharacters() 1187 && process.IsValid() 1188 && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching)) 1189 { 1190 process.SendAsyncInterrupt (); 1191 } 1192 else 1193 { 1194 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC); 1195 // I wish I could erase the entire input line, but there's no public API for that. 1196 driver->m_io_channel_ap->EraseCharsBeforeCursor(); 1197 driver->m_io_channel_ap->RefreshPrompt(); 1198 } 1199 } 1200 break; 1201 1202 case eInputReaderEndOfFile: 1203 if (driver->m_io_channel_ap.get() != NULL) 1204 { 1205 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC); 1206 driver->m_io_channel_ap->RefreshPrompt (); 1207 } 1208 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5); 1209 break; 1210 1211 case eInputReaderGotToken: 1212 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len); 1213 break; 1214 1215 case eInputReaderDone: 1216 break; 1217 } 1218 return bytes_len; 1219} 1220 1221void 1222Driver::MainLoop () 1223{ 1224 char error_str[1024]; 1225 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false) 1226 { 1227 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str); 1228 exit(1); 1229 } 1230 else 1231 { 1232 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str)); 1233 if (driver_slave_name == NULL) 1234 { 1235 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str); 1236 exit(2); 1237 } 1238 else 1239 { 1240 m_editline_slave_fh = ::fopen (driver_slave_name, "r+"); 1241 if (m_editline_slave_fh == NULL) 1242 { 1243 SBError error; 1244 error.SetErrorToErrno(); 1245 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s", 1246 error.GetCString()); 1247 exit(3); 1248 } 1249 1250 ::setbuf (m_editline_slave_fh, NULL); 1251 } 1252 } 1253 1254 lldb_utility::PseudoTerminal editline_output_pty; 1255 FILE *editline_output_slave_fh = NULL; 1256 1257 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false) 1258 { 1259 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str); 1260 exit(1); 1261 } 1262 else 1263 { 1264 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str)); 1265 if (output_slave_name == NULL) 1266 { 1267 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str); 1268 exit(2); 1269 } 1270 else 1271 { 1272 editline_output_slave_fh = ::fopen (output_slave_name, "r+"); 1273 if (editline_output_slave_fh == NULL) 1274 { 1275 SBError error; 1276 error.SetErrorToErrno(); 1277 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s", 1278 error.GetCString()); 1279 exit(3); 1280 } 1281 ::setbuf (editline_output_slave_fh, NULL); 1282 } 1283 } 1284 1285 // struct termios stdin_termios; 1286 1287 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) 1288 { 1289 g_old_stdin_termios_is_valid = true; 1290 atexit (reset_stdin_termios); 1291 } 1292 1293 ::setbuf (stdin, NULL); 1294 ::setbuf (stdout, NULL); 1295 1296 m_debugger.SetErrorFileHandle (stderr, false); 1297 m_debugger.SetOutputFileHandle (stdout, false); 1298 m_debugger.SetInputFileHandle (stdin, true); 1299 1300 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); 1301 1302 // You have to drain anything that comes to the master side of the PTY. master_out_comm is 1303 // for that purpose. The reason you need to do this is a curious reason... editline will echo 1304 // characters to the PTY when it gets characters while el_gets is not running, and then when 1305 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks 1306 // if there are unconsumed characters in the out buffer. 1307 // However, you don't need to do anything with the characters, since editline will dump these 1308 // unconsumed characters after printing the prompt again in el_gets. 1309 1310 SBCommunication master_out_comm("driver.editline"); 1311 master_out_comm.SetCloseOnEOF (false); 1312 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false); 1313 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this); 1314 1315 if (master_out_comm.ReadThreadStart () == false) 1316 { 1317 ::fprintf (stderr, "error: failed to start master out read thread"); 1318 exit(5); 1319 } 1320 1321 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); 1322 1323 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this)); 1324 1325 SBCommunication out_comm_2("driver.editline_output"); 1326 out_comm_2.SetCloseOnEOF (false); 1327 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false); 1328 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get()); 1329 1330 if (out_comm_2.ReadThreadStart () == false) 1331 { 1332 ::fprintf (stderr, "error: failed to start libedit output read thread"); 1333 exit (5); 1334 } 1335 1336 1337 struct winsize window_size; 1338 if (isatty (STDIN_FILENO) 1339 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1340 { 1341 if (window_size.ws_col > 0) 1342 m_debugger.SetTerminalWidth (window_size.ws_col); 1343 } 1344 1345 // Since input can be redirected by the debugger, we must insert our editline 1346 // input reader in the queue so we know when our reader should be active 1347 // and so we can receive bytes only when we are supposed to. 1348 SBError err (m_editline_reader.Initialize (m_debugger, 1349 Driver::EditLineInputReaderCallback, // callback 1350 this, // baton 1351 eInputReaderGranularityByte, // token_size 1352 NULL, // end token - NULL means never done 1353 NULL, // prompt - taken care of elsewhere 1354 false)); // echo input - don't need Debugger 1355 // to do this, we handle it elsewhere 1356 1357 if (err.Fail()) 1358 { 1359 ::fprintf (stderr, "error: %s", err.GetCString()); 1360 exit (6); 1361 } 1362 1363 m_debugger.PushInputReader (m_editline_reader); 1364 1365 SBListener listener(m_debugger.GetListener()); 1366 if (listener.IsValid()) 1367 { 1368 1369 listener.StartListeningForEventClass(m_debugger, 1370 SBTarget::GetBroadcasterClassName(), 1371 SBTarget::eBroadcastBitBreakpointChanged); 1372 listener.StartListeningForEventClass(m_debugger, 1373 SBThread::GetBroadcasterClassName(), 1374 SBThread::eBroadcastBitStackChanged | 1375 SBThread::eBroadcastBitThreadSelected); 1376 listener.StartListeningForEvents (*m_io_channel_ap, 1377 IOChannel::eBroadcastBitHasUserInput | 1378 IOChannel::eBroadcastBitUserInterrupt | 1379 IOChannel::eBroadcastBitThreadShouldExit | 1380 IOChannel::eBroadcastBitThreadDidStart | 1381 IOChannel::eBroadcastBitThreadDidExit); 1382 1383 if (m_io_channel_ap->Start ()) 1384 { 1385 bool iochannel_thread_exited = false; 1386 1387 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(), 1388 SBCommandInterpreter::eBroadcastBitQuitCommandReceived | 1389 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | 1390 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); 1391 1392 // Before we handle any options from the command line, we parse the 1393 // .lldbinit file in the user's home directory. 1394 SBCommandReturnObject result; 1395 sb_interpreter.SourceInitFileInHomeDirectory(result); 1396 if (GetDebugMode()) 1397 { 1398 result.PutError (m_debugger.GetErrorFileHandle()); 1399 result.PutOutput (m_debugger.GetOutputFileHandle()); 1400 } 1401 1402 // Now we handle options we got from the command line 1403 char command_string[PATH_MAX * 2]; 1404 const size_t num_source_command_files = GetNumSourceCommandFiles(); 1405 const bool dump_stream_only_if_no_immediate = true; 1406 if (num_source_command_files > 0) 1407 { 1408 for (size_t i=0; i < num_source_command_files; ++i) 1409 { 1410 const char *command_file = GetSourceCommandFileAtIndex(i); 1411 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file); 1412 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false); 1413 if (GetDebugMode()) 1414 { 1415 result.PutError (m_debugger.GetErrorFileHandle()); 1416 result.PutOutput (m_debugger.GetOutputFileHandle()); 1417 } 1418 1419 // if the command sourcing generated an error - dump the result object 1420 if (result.Succeeded() == false) 1421 { 1422 const size_t output_size = result.GetOutputSize(); 1423 if (output_size > 0) 1424 m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC); 1425 const size_t error_size = result.GetErrorSize(); 1426 if (error_size > 0) 1427 m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC); 1428 } 1429 1430 result.Clear(); 1431 } 1432 } 1433 1434 // Was there a core file specified? 1435 std::string core_file_spec(""); 1436 if (!m_option_data.m_core_file.empty()) 1437 core_file_spec.append("--core ").append(m_option_data.m_core_file); 1438 1439 const size_t num_args = m_option_data.m_args.size(); 1440 if (num_args > 0) 1441 { 1442 char arch_name[64]; 1443 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) 1444 ::snprintf (command_string, 1445 sizeof (command_string), 1446 "target create --arch=%s %s \"%s\"", 1447 arch_name, 1448 core_file_spec.c_str(), 1449 m_option_data.m_args[0].c_str()); 1450 else 1451 ::snprintf (command_string, 1452 sizeof(command_string), 1453 "target create %s \"%s\"", 1454 core_file_spec.c_str(), 1455 m_option_data.m_args[0].c_str()); 1456 1457 m_debugger.HandleCommand (command_string); 1458 1459 if (num_args > 1) 1460 { 1461 m_debugger.HandleCommand ("settings clear target.run-args"); 1462 char arg_cstr[1024]; 1463 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) 1464 { 1465 ::snprintf (arg_cstr, 1466 sizeof(arg_cstr), 1467 "settings append target.run-args \"%s\"", 1468 m_option_data.m_args[arg_idx].c_str()); 1469 m_debugger.HandleCommand (arg_cstr); 1470 } 1471 } 1472 } 1473 else if (!core_file_spec.empty()) 1474 { 1475 ::snprintf (command_string, 1476 sizeof(command_string), 1477 "target create %s", 1478 core_file_spec.c_str()); 1479 m_debugger.HandleCommand (command_string);; 1480 } 1481 1482 // Now that all option parsing is done, we try and parse the .lldbinit 1483 // file in the current working directory 1484 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result); 1485 if (GetDebugMode()) 1486 { 1487 result.PutError(m_debugger.GetErrorFileHandle()); 1488 result.PutOutput(m_debugger.GetOutputFileHandle()); 1489 } 1490 1491 SBEvent event; 1492 1493 // Make sure the IO channel is started up before we try to tell it we 1494 // are ready for input 1495 listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 1496 *m_io_channel_ap, 1497 IOChannel::eBroadcastBitThreadDidStart, 1498 event); 1499 // If we were asked to attach, then do that here: 1500 // I'm going to use the command string rather than directly 1501 // calling the API's because then I don't have to recode the 1502 // event handling here. 1503 if (!m_option_data.m_process_name.empty() 1504 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 1505 { 1506 std::string command_str("process attach "); 1507 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 1508 { 1509 command_str.append("-p "); 1510 char pid_buffer[32]; 1511 ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid); 1512 command_str.append(pid_buffer); 1513 } 1514 else 1515 { 1516 command_str.append("-n \""); 1517 command_str.append(m_option_data.m_process_name); 1518 command_str.push_back('\"'); 1519 if (m_option_data.m_wait_for) 1520 command_str.append(" -w"); 1521 } 1522 1523 if (m_debugger.GetOutputFileHandle()) 1524 ::fprintf (m_debugger.GetOutputFileHandle(), 1525 "Attaching to process with:\n %s\n", 1526 command_str.c_str()); 1527 1528 // Force the attach to be synchronous: 1529 bool orig_async = m_debugger.GetAsync(); 1530 m_debugger.SetAsync(true); 1531 m_debugger.HandleCommand(command_str.c_str()); 1532 m_debugger.SetAsync(orig_async); 1533 } 1534 1535 ReadyForCommand (); 1536 1537 while (!GetIsDone()) 1538 { 1539 listener.WaitForEvent (UINT32_MAX, event); 1540 if (event.IsValid()) 1541 { 1542 if (event.GetBroadcaster().IsValid()) 1543 { 1544 uint32_t event_type = event.GetType(); 1545 if (event.BroadcasterMatchesRef (*m_io_channel_ap)) 1546 { 1547 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 1548 (event_type & IOChannel::eBroadcastBitThreadDidExit)) 1549 { 1550 SetIsDone(); 1551 if (event_type & IOChannel::eBroadcastBitThreadDidExit) 1552 iochannel_thread_exited = true; 1553 } 1554 else 1555 { 1556 if (HandleIOEvent (event)) 1557 SetIsDone(); 1558 } 1559 } 1560 else if (SBProcess::EventIsProcessEvent (event)) 1561 { 1562 HandleProcessEvent (event); 1563 } 1564 else if (SBBreakpoint::EventIsBreakpointEvent (event)) 1565 { 1566 HandleBreakpointEvent (event); 1567 } 1568 else if (SBThread::EventIsThreadEvent (event)) 1569 { 1570 HandleThreadEvent (event); 1571 } 1572 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster())) 1573 { 1574 // TODO: deprecate the eBroadcastBitQuitCommandReceived event 1575 // now that we have SBCommandInterpreter::SetCommandOverrideCallback() 1576 // that can take over a command 1577 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived) 1578 { 1579 SetIsDone(); 1580 } 1581 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData) 1582 { 1583 const char *data = SBEvent::GetCStringFromEvent (event); 1584 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC); 1585 } 1586 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData) 1587 { 1588 const char *data = SBEvent::GetCStringFromEvent (event); 1589 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC); 1590 } 1591 } 1592 } 1593 } 1594 } 1595 1596 master_out_comm.SetReadThreadBytesReceivedCallback(NULL, NULL); 1597 master_out_comm.Disconnect(); 1598 master_out_comm.ReadThreadStop(); 1599 1600 out_comm_2.SetReadThreadBytesReceivedCallback(NULL, NULL); 1601 out_comm_2.Disconnect(); 1602 out_comm_2.ReadThreadStop(); 1603 1604 editline_output_pty.CloseMasterFileDescriptor(); 1605 reset_stdin_termios(); 1606 fclose (stdin); 1607 1608 CloseIOChannelFile (); 1609 1610 if (!iochannel_thread_exited) 1611 { 1612 event.Clear(); 1613 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap, 1614 IOChannel::eBroadcastBitThreadDidExit, 1615 event); 1616 if (!event.IsValid()) 1617 { 1618 // Send end EOF to the driver file descriptor 1619 m_io_channel_ap->Stop(); 1620 } 1621 } 1622 1623 SBDebugger::Destroy (m_debugger); 1624 } 1625 } 1626} 1627 1628 1629void 1630Driver::ReadyForCommand () 1631{ 1632 if (m_waiting_for_command == false) 1633 { 1634 m_waiting_for_command = true; 1635 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true); 1636 } 1637} 1638 1639void 1640Driver::ResizeWindow (unsigned short col) 1641{ 1642 GetDebugger().SetTerminalWidth (col); 1643 if (m_io_channel_ap.get() != NULL) 1644 { 1645 m_io_channel_ap->ElResize(); 1646 } 1647} 1648 1649void 1650sigwinch_handler (int signo) 1651{ 1652 struct winsize window_size; 1653 if (isatty (STDIN_FILENO) 1654 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1655 { 1656 if ((window_size.ws_col > 0) && g_driver != NULL) 1657 { 1658 g_driver->ResizeWindow (window_size.ws_col); 1659 } 1660 } 1661} 1662 1663void 1664sigint_handler (int signo) 1665{ 1666 static bool g_interrupt_sent = false; 1667 if (g_driver) 1668 { 1669 if (!g_interrupt_sent) 1670 { 1671 g_interrupt_sent = true; 1672 g_driver->GetDebugger().DispatchInputInterrupt(); 1673 g_interrupt_sent = false; 1674 return; 1675 } 1676 } 1677 1678 exit (signo); 1679} 1680 1681void 1682sigtstp_handler (int signo) 1683{ 1684 g_driver->GetDebugger().SaveInputTerminalState(); 1685 signal (signo, SIG_DFL); 1686 kill (getpid(), signo); 1687 signal (signo, sigtstp_handler); 1688} 1689 1690void 1691sigcont_handler (int signo) 1692{ 1693 g_driver->GetDebugger().RestoreInputTerminalState(); 1694 signal (signo, SIG_DFL); 1695 kill (getpid(), signo); 1696 signal (signo, sigcont_handler); 1697} 1698 1699int 1700main (int argc, char const *argv[], const char *envp[]) 1701{ 1702 SBDebugger::Initialize(); 1703 1704 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>"); 1705 1706 signal (SIGPIPE, SIG_IGN); 1707 signal (SIGWINCH, sigwinch_handler); 1708 signal (SIGINT, sigint_handler); 1709 signal (SIGTSTP, sigtstp_handler); 1710 signal (SIGCONT, sigcont_handler); 1711 1712 // Create a scope for driver so that the driver object will destroy itself 1713 // before SBDebugger::Terminate() is called. 1714 { 1715 Driver driver; 1716 1717 bool exit = false; 1718 SBError error (driver.ParseArgs (argc, argv, stdout, exit)); 1719 if (error.Fail()) 1720 { 1721 const char *error_cstr = error.GetCString (); 1722 if (error_cstr) 1723 ::fprintf (stderr, "error: %s\n", error_cstr); 1724 } 1725 else if (!exit) 1726 { 1727 driver.MainLoop (); 1728 } 1729 } 1730 1731 SBDebugger::Terminate(); 1732 return 0; 1733} 1734