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