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 location%s added to breakpoint %d\n", 854 num_new_locations, 855 num_new_locations == 1 ? " " : "s ", 856 breakpoint.GetID()); 857 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 858 } 859 } 860 else if (event_type & eBreakpointEventTypeLocationsRemoved) 861 { 862 // These locations just get disabled, not sure it is worth spamming folks about this on the command line. 863 } 864 else if (event_type & eBreakpointEventTypeLocationsResolved) 865 { 866 // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy. 867 } 868 } 869 870 // This function handles events that were broadcast by the process. 871 void 872 Driver::HandleProcessEvent (const SBEvent &event) 873 { 874 using namespace lldb; 875 const uint32_t event_type = event.GetType(); 876 877 if (event_type & SBProcess::eBroadcastBitSTDOUT) 878 { 879 // The process has stdout available, get it and write it out to the 880 // appropriate place. 881 GetProcessSTDOUT (); 882 } 883 else if (event_type & SBProcess::eBroadcastBitSTDERR) 884 { 885 // The process has stderr available, get it and write it out to the 886 // appropriate place. 887 GetProcessSTDERR (); 888 } 889 else if (event_type & SBProcess::eBroadcastBitStateChanged) 890 { 891 // Drain all stout and stderr so we don't see any output come after 892 // we print our prompts 893 GetProcessSTDOUT (); 894 GetProcessSTDERR (); 895 // Something changed in the process; get the event and report the process's current status and location to 896 // the user. 897 StateType event_state = SBProcess::GetStateFromEvent (event); 898 if (event_state == eStateInvalid) 899 return; 900 901 SBProcess process (SBProcess::GetProcessFromEvent (event)); 902 assert (process.IsValid()); 903 904 switch (event_state) 905 { 906 case eStateInvalid: 907 case eStateUnloaded: 908 case eStateConnected: 909 case eStateAttaching: 910 case eStateLaunching: 911 case eStateStepping: 912 case eStateDetached: 913 { 914 char message[1024]; 915 int message_len = ::snprintf (message, sizeof(message), "Process %llu %s\n", process.GetProcessID(), 916 m_debugger.StateAsCString (event_state)); 917 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 918 } 919 break; 920 921 case eStateRunning: 922 // Don't be chatty when we run... 923 break; 924 925 case eStateExited: 926 { 927 SBCommandReturnObject result; 928 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 929 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 930 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 931 } 932 break; 933 934 case eStateStopped: 935 case eStateCrashed: 936 case eStateSuspended: 937 // Make sure the program hasn't been auto-restarted: 938 if (SBProcess::GetRestartedFromEvent (event)) 939 { 940 // FIXME: Do we want to report this, or would that just be annoyingly chatty? 941 char message[1024]; 942 int message_len = ::snprintf (message, sizeof(message), "Process %llu stopped and was programmatically restarted.\n", 943 process.GetProcessID()); 944 m_io_channel_ap->OutWrite(message, message_len, ASYNC); 945 } 946 else 947 { 948 SBCommandReturnObject result; 949 UpdateSelectedThread (); 950 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 951 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 952 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 953 } 954 break; 955 } 956 } 957 } 958 959 // This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit). 960 961 bool 962 Driver::HandleIOEvent (const SBEvent &event) 963 { 964 bool quit = false; 965 966 const uint32_t event_type = event.GetType(); 967 968 if (event_type & IOChannel::eBroadcastBitHasUserInput) 969 { 970 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for 971 // handling. 972 973 const char *command_string = SBEvent::GetCStringFromEvent(event); 974 if (command_string == NULL) 975 command_string = ""; 976 SBCommandReturnObject result; 977 978 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd 979 // output orderings and problems with the prompt. 980 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true); 981 982 if (result.GetOutputSize() > 0) 983 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC); 984 985 if (result.GetErrorSize() > 0) 986 m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC); 987 988 // We are done getting and running our command, we can now clear the 989 // m_waiting_for_command so we can get another one. 990 m_waiting_for_command = false; 991 992 // If our editline input reader is active, it means another input reader 993 // got pushed onto the input reader and caused us to become deactivated. 994 // When the input reader above us gets popped, we will get re-activated 995 // and our prompt will refresh in our callback 996 if (m_editline_reader.IsActive()) 997 { 998 ReadyForCommand (); 999 } 1000 } 1001 else if (event_type & IOChannel::eBroadcastBitUserInterrupt) 1002 { 1003 // This is here to handle control-c interrupts from the user. It has not yet really been implemented. 1004 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER 1005 //m_io_channel_ap->CancelInput(); 1006 // Anything else? Send Interrupt to process? 1007 } 1008 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 1009 (event_type & IOChannel::eBroadcastBitThreadDidExit)) 1010 { 1011 // If the IOChannel thread is trying to go away, then it is definitely 1012 // time to end the debugging session. 1013 quit = true; 1014 } 1015 1016 return quit; 1017 } 1018 1019 void 1020 Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len) 1021 { 1022 Driver *driver = (Driver*)baton; 1023 driver->GetFromMaster ((const char *)src, src_len); 1024 } 1025 1026 void 1027 Driver::GetFromMaster (const char *src, size_t src_len) 1028 { 1029 // Echo the characters back to the Debugger's stdout, that way if you 1030 // type characters while a command is running, you'll see what you've typed. 1031 FILE *out_fh = m_debugger.GetOutputFileHandle(); 1032 if (out_fh) 1033 ::fwrite (src, 1, src_len, out_fh); 1034 } 1035 1036 size_t 1037 Driver::EditLineInputReaderCallback 1038 ( 1039 void *baton, 1040 SBInputReader *reader, 1041 InputReaderAction notification, 1042 const char *bytes, 1043 size_t bytes_len 1044 ) 1045 { 1046 Driver *driver = (Driver *)baton; 1047 1048 switch (notification) 1049 { 1050 case eInputReaderActivate: 1051 break; 1052 1053 case eInputReaderReactivate: 1054 driver->ReadyForCommand(); 1055 break; 1056 1057 case eInputReaderDeactivate: 1058 break; 1059 1060 case eInputReaderAsynchronousOutputWritten: 1061 if (driver->m_io_channel_ap.get() != NULL) 1062 driver->m_io_channel_ap->RefreshPrompt(); 1063 break; 1064 1065 case eInputReaderInterrupt: 1066 if (driver->m_io_channel_ap.get() != NULL) 1067 { 1068 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC); 1069 driver->m_io_channel_ap->RefreshPrompt(); 1070 } 1071 break; 1072 1073 case eInputReaderEndOfFile: 1074 if (driver->m_io_channel_ap.get() != NULL) 1075 { 1076 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC); 1077 driver->m_io_channel_ap->RefreshPrompt (); 1078 } 1079 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5); 1080 break; 1081 1082 case eInputReaderGotToken: 1083 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len); 1084 break; 1085 1086 case eInputReaderDone: 1087 break; 1088 } 1089 return bytes_len; 1090 } 1091 1092 // Intercept when the quit command is called and tell our driver that it is done 1093 static bool 1094 QuitCommandOverrideCallback (void *baton, const char **argv) 1095 { 1096 ((Driver *)baton)->SetIsDone(); 1097 return true; 1098 } 1099 1100 void 1101 Driver::MainLoop () 1102 { 1103 char error_str[1024]; 1104 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false) 1105 { 1106 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str); 1107 exit(1); 1108 } 1109 else 1110 { 1111 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str)); 1112 if (driver_slave_name == NULL) 1113 { 1114 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str); 1115 exit(2); 1116 } 1117 else 1118 { 1119 m_editline_slave_fh = ::fopen (driver_slave_name, "r+"); 1120 if (m_editline_slave_fh == NULL) 1121 { 1122 SBError error; 1123 error.SetErrorToErrno(); 1124 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s", 1125 error.GetCString()); 1126 exit(3); 1127 } 1128 1129 ::setbuf (m_editline_slave_fh, NULL); 1130 } 1131 } 1132 1133 lldb_utility::PseudoTerminal editline_output_pty; 1134 FILE *editline_output_slave_fh = NULL; 1135 1136 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false) 1137 { 1138 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str); 1139 exit(1); 1140 } 1141 else 1142 { 1143 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str)); 1144 if (output_slave_name == NULL) 1145 { 1146 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str); 1147 exit(2); 1148 } 1149 else 1150 { 1151 editline_output_slave_fh = ::fopen (output_slave_name, "r+"); 1152 if (editline_output_slave_fh == NULL) 1153 { 1154 SBError error; 1155 error.SetErrorToErrno(); 1156 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s", 1157 error.GetCString()); 1158 exit(3); 1159 } 1160 ::setbuf (editline_output_slave_fh, NULL); 1161 } 1162 } 1163 1164 // struct termios stdin_termios; 1165 1166 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) 1167 { 1168 g_old_stdin_termios_is_valid = true; 1169 atexit (reset_stdin_termios); 1170 } 1171 1172 ::setbuf (stdin, NULL); 1173 ::setbuf (stdout, NULL); 1174 1175 m_debugger.SetErrorFileHandle (stderr, false); 1176 m_debugger.SetOutputFileHandle (stdout, false); 1177 m_debugger.SetInputFileHandle (stdin, true); 1178 1179 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); 1180 1181 // You have to drain anything that comes to the master side of the PTY. master_out_comm is 1182 // for that purpose. The reason you need to do this is a curious reason... editline will echo 1183 // characters to the PTY when it gets characters while el_gets is not running, and then when 1184 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks 1185 // if there are unconsumed characters in the out buffer. 1186 // However, you don't need to do anything with the characters, since editline will dump these 1187 // unconsumed characters after printing the prompt again in el_gets. 1188 1189 SBCommunication master_out_comm("driver.editline"); 1190 master_out_comm.SetCloseOnEOF (false); 1191 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false); 1192 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this); 1193 1194 if (master_out_comm.ReadThreadStart () == false) 1195 { 1196 ::fprintf (stderr, "error: failed to start master out read thread"); 1197 exit(5); 1198 } 1199 1200 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); 1201 1202 // Intercept when the quit command is called and tell our driver that it is done 1203 bool quit_success = sb_interpreter.SetCommandOverrideCallback ("quit", QuitCommandOverrideCallback, this); 1204 assert (quit_success); 1205 1206 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this)); 1207 1208 SBCommunication out_comm_2("driver.editline_output"); 1209 out_comm_2.SetCloseOnEOF (false); 1210 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false); 1211 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get()); 1212 1213 if (out_comm_2.ReadThreadStart () == false) 1214 { 1215 ::fprintf (stderr, "error: failed to start libedit output read thread"); 1216 exit (5); 1217 } 1218 1219 1220 struct winsize window_size; 1221 if (isatty (STDIN_FILENO) 1222 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1223 { 1224 if (window_size.ws_col > 0) 1225 m_debugger.SetTerminalWidth (window_size.ws_col); 1226 } 1227 1228 // Since input can be redirected by the debugger, we must insert our editline 1229 // input reader in the queue so we know when our reader should be active 1230 // and so we can receive bytes only when we are supposed to. 1231 SBError err (m_editline_reader.Initialize (m_debugger, 1232 Driver::EditLineInputReaderCallback, // callback 1233 this, // baton 1234 eInputReaderGranularityByte, // token_size 1235 NULL, // end token - NULL means never done 1236 NULL, // prompt - taken care of elsewhere 1237 false)); // echo input - don't need Debugger 1238 // to do this, we handle it elsewhere 1239 1240 if (err.Fail()) 1241 { 1242 ::fprintf (stderr, "error: %s", err.GetCString()); 1243 exit (6); 1244 } 1245 1246 m_debugger.PushInputReader (m_editline_reader); 1247 1248 SBListener listener(m_debugger.GetListener()); 1249 listener.StartListeningForEventClass(m_debugger, 1250 SBTarget::GetBroadcasterClassName(), 1251 SBTarget::eBroadcastBitBreakpointChanged); 1252 if (listener.IsValid()) 1253 { 1254 1255 listener.StartListeningForEvents (*m_io_channel_ap, 1256 IOChannel::eBroadcastBitHasUserInput | 1257 IOChannel::eBroadcastBitUserInterrupt | 1258 IOChannel::eBroadcastBitThreadShouldExit | 1259 IOChannel::eBroadcastBitThreadDidStart | 1260 IOChannel::eBroadcastBitThreadDidExit); 1261 1262 if (m_io_channel_ap->Start ()) 1263 { 1264 bool iochannel_thread_exited = false; 1265 1266 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(), 1267 SBCommandInterpreter::eBroadcastBitQuitCommandReceived | 1268 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | 1269 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); 1270 1271 // Before we handle any options from the command line, we parse the 1272 // .lldbinit file in the user's home directory. 1273 SBCommandReturnObject result; 1274 sb_interpreter.SourceInitFileInHomeDirectory(result); 1275 if (GetDebugMode()) 1276 { 1277 result.PutError (m_debugger.GetErrorFileHandle()); 1278 result.PutOutput (m_debugger.GetOutputFileHandle()); 1279 } 1280 1281 // Now we handle options we got from the command line 1282 char command_string[PATH_MAX * 2]; 1283 const size_t num_source_command_files = GetNumSourceCommandFiles(); 1284 if (num_source_command_files > 0) 1285 { 1286 for (size_t i=0; i < num_source_command_files; ++i) 1287 { 1288 const char *command_file = GetSourceCommandFileAtIndex(i); 1289 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file); 1290 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false); 1291 if (GetDebugMode()) 1292 { 1293 result.PutError (m_debugger.GetErrorFileHandle()); 1294 result.PutOutput (m_debugger.GetOutputFileHandle()); 1295 } 1296 } 1297 } 1298 1299 const size_t num_args = m_option_data.m_args.size(); 1300 if (num_args > 0) 1301 { 1302 char arch_name[64]; 1303 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) 1304 ::snprintf (command_string, 1305 sizeof (command_string), 1306 "target create --arch=%s '%s'", 1307 arch_name, 1308 m_option_data.m_args[0].c_str()); 1309 else 1310 ::snprintf (command_string, 1311 sizeof(command_string), 1312 "target create '%s'", 1313 m_option_data.m_args[0].c_str()); 1314 1315 m_debugger.HandleCommand (command_string); 1316 1317 if (num_args > 1) 1318 { 1319 m_debugger.HandleCommand ("settings clear target.run-args"); 1320 char arg_cstr[1024]; 1321 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) 1322 { 1323 ::snprintf (arg_cstr, 1324 sizeof(arg_cstr), 1325 "settings append target.run-args \"%s\"", 1326 m_option_data.m_args[arg_idx].c_str()); 1327 m_debugger.HandleCommand (arg_cstr); 1328 } 1329 } 1330 } 1331 1332 // Now that all option parsing is done, we try and parse the .lldbinit 1333 // file in the current working directory 1334 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result); 1335 if (GetDebugMode()) 1336 { 1337 result.PutError(m_debugger.GetErrorFileHandle()); 1338 result.PutOutput(m_debugger.GetOutputFileHandle()); 1339 } 1340 1341 SBEvent event; 1342 1343 // Make sure the IO channel is started up before we try to tell it we 1344 // are ready for input 1345 listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 1346 *m_io_channel_ap, 1347 IOChannel::eBroadcastBitThreadDidStart, 1348 event); 1349 // If we were asked to attach, then do that here: 1350 // I'm going to use the command string rather than directly 1351 // calling the API's because then I don't have to recode the 1352 // event handling here. 1353 if (!m_option_data.m_process_name.empty() 1354 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 1355 { 1356 std::string command_str("process attach "); 1357 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 1358 { 1359 command_str.append("-p "); 1360 char pid_buffer[32]; 1361 ::snprintf (pid_buffer, sizeof(pid_buffer), "%llu", m_option_data.m_process_pid); 1362 command_str.append(pid_buffer); 1363 } 1364 else 1365 { 1366 command_str.append("-n \""); 1367 command_str.append(m_option_data.m_process_name); 1368 command_str.push_back('\"'); 1369 if (m_option_data.m_wait_for) 1370 command_str.append(" -w"); 1371 } 1372 1373 if (m_debugger.GetOutputFileHandle()) 1374 ::fprintf (m_debugger.GetOutputFileHandle(), 1375 "Attaching to process with:\n %s\n", 1376 command_str.c_str()); 1377 1378 // Force the attach to be synchronous: 1379 bool orig_async = m_debugger.GetAsync(); 1380 m_debugger.SetAsync(true); 1381 m_debugger.HandleCommand(command_str.c_str()); 1382 m_debugger.SetAsync(orig_async); 1383 } 1384 1385 ReadyForCommand (); 1386 1387 while (!GetIsDone()) 1388 { 1389 listener.WaitForEvent (UINT32_MAX, event); 1390 if (event.IsValid()) 1391 { 1392 if (event.GetBroadcaster().IsValid()) 1393 { 1394 uint32_t event_type = event.GetType(); 1395 if (event.BroadcasterMatchesRef (*m_io_channel_ap)) 1396 { 1397 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 1398 (event_type & IOChannel::eBroadcastBitThreadDidExit)) 1399 { 1400 SetIsDone(); 1401 if (event_type & IOChannel::eBroadcastBitThreadDidExit) 1402 iochannel_thread_exited = true; 1403 } 1404 else 1405 { 1406 if (HandleIOEvent (event)) 1407 SetIsDone(); 1408 } 1409 } 1410 else if (SBProcess::EventIsProcessEvent (event)) 1411 { 1412 HandleProcessEvent (event); 1413 } 1414 else if (SBBreakpoint::EventIsBreakpointEvent (event)) 1415 { 1416 HandleBreakpointEvent (event); 1417 } 1418 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster())) 1419 { 1420 // TODO: deprecate the eBroadcastBitQuitCommandReceived event 1421 // now that we have SBCommandInterpreter::SetCommandOverrideCallback() 1422 // that can take over a command 1423 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived) 1424 { 1425 SetIsDone(); 1426 } 1427 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData) 1428 { 1429 const char *data = SBEvent::GetCStringFromEvent (event); 1430 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC); 1431 } 1432 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData) 1433 { 1434 const char *data = SBEvent::GetCStringFromEvent (event); 1435 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC); 1436 } 1437 } 1438 } 1439 } 1440 } 1441 1442 editline_output_pty.CloseMasterFileDescriptor(); 1443 master_out_comm.Disconnect(); 1444 out_comm_2.Disconnect(); 1445 reset_stdin_termios(); 1446 fclose (stdin); 1447 1448 CloseIOChannelFile (); 1449 1450 if (!iochannel_thread_exited) 1451 { 1452 event.Clear(); 1453 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap, 1454 IOChannel::eBroadcastBitThreadDidExit, 1455 event); 1456 if (!event.IsValid()) 1457 { 1458 // Send end EOF to the driver file descriptor 1459 m_io_channel_ap->Stop(); 1460 } 1461 } 1462 1463 SBDebugger::Destroy (m_debugger); 1464 } 1465 } 1466 } 1467 1468 1469 void 1470 Driver::ReadyForCommand () 1471 { 1472 if (m_waiting_for_command == false) 1473 { 1474 m_waiting_for_command = true; 1475 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true); 1476 } 1477 } 1478 1479 1480 void 1481 sigwinch_handler (int signo) 1482 { 1483 struct winsize window_size; 1484 if (isatty (STDIN_FILENO) 1485 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1486 { 1487 if ((window_size.ws_col > 0) && g_driver != NULL) 1488 { 1489 g_driver->GetDebugger().SetTerminalWidth (window_size.ws_col); 1490 } 1491 } 1492 } 1493 1494 void 1495 sigint_handler (int signo) 1496 { 1497 static bool g_interrupt_sent = false; 1498 if (g_driver) 1499 { 1500 if (!g_interrupt_sent) 1501 { 1502 g_interrupt_sent = true; 1503 g_driver->GetDebugger().DispatchInputInterrupt(); 1504 g_interrupt_sent = false; 1505 return; 1506 } 1507 } 1508 1509 exit (signo); 1510 } 1511 1512 int 1513 main (int argc, char const *argv[], const char *envp[]) 1514 { 1515 SBDebugger::Initialize(); 1516 1517 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>"); 1518 1519 signal (SIGPIPE, SIG_IGN); 1520 signal (SIGWINCH, sigwinch_handler); 1521 signal (SIGINT, sigint_handler); 1522 1523 // Create a scope for driver so that the driver object will destroy itself 1524 // before SBDebugger::Terminate() is called. 1525 { 1526 Driver driver; 1527 1528 bool exit = false; 1529 SBError error (driver.ParseArgs (argc, argv, stdout, exit)); 1530 if (error.Fail()) 1531 { 1532 const char *error_cstr = error.GetCString (); 1533 if (error_cstr) 1534 ::fprintf (stderr, "error: %s\n", error_cstr); 1535 } 1536 else if (!exit) 1537 { 1538 driver.MainLoop (); 1539 } 1540 } 1541 1542 SBDebugger::Terminate(); 1543 return 0; 1544 } 1545