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