Driver.cpp revision 4a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7
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 38using namespace lldb; 39 40static void reset_stdin_termios (); 41static bool g_old_stdin_termios_is_valid = false; 42static struct termios g_old_stdin_termios; 43 44static char *g_debugger_name = (char *) ""; 45static 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. 49static void 50reset_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 59typedef 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 76static 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 108static const uint32_t last_option_set_with_args = 2; 109 110Driver::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 129Driver::~Driver () 130{ 131 g_driver = NULL; 132 g_debugger_name = NULL; 133} 134 135void 136Driver::CloseIOChannelFile () 137{ 138 // Write an 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 159void 160OutputFormattedUsageText (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 207void 208ShowUsage (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 344void 345BuildGetOptTable (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 379Driver::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 395Driver::OptionData::~OptionData () 396{ 397} 398 399void 400Driver::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 414void 415Driver::ResetOptionValues () 416{ 417 m_option_data.Clear (); 418} 419 420const char * 421Driver::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 428const char * 429Driver::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 436lldb::ScriptLanguage 437Driver::GetScriptLanguage() const 438{ 439 return m_option_data.m_script_lang; 440} 441 442size_t 443Driver::GetNumSourceCommandFiles () const 444{ 445 return m_option_data.m_source_command_files.size(); 446} 447 448const char * 449Driver::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 456bool 457Driver::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 468SBError 469Driver::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; // Commented out to keep static analyzer happy 726 727 if (argc > 0) 728 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n"); 729 } 730 731 return error; 732} 733 734size_t 735Driver::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 749size_t 750Driver::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 764void 765Driver::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. 829void 830Driver::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. 871void 872Driver::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 if (GetDebugger().GetSelectedTarget() == process.GetTarget()) 949 { 950 SBCommandReturnObject result; 951 UpdateSelectedThread (); 952 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false); 953 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC); 954 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC); 955 } 956 else 957 { 958 SBStream out_stream; 959 uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget()); 960 if (target_idx != UINT32_MAX) 961 out_stream.Printf ("Target %d: (", target_idx); 962 else 963 out_stream.Printf ("Target <unknown index>: ("); 964 process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief); 965 out_stream.Printf (") stopped.\n"); 966 m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC); 967 } 968 } 969 break; 970 } 971 } 972} 973 974// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit). 975 976bool 977Driver::HandleIOEvent (const SBEvent &event) 978{ 979 bool quit = false; 980 981 const uint32_t event_type = event.GetType(); 982 983 if (event_type & IOChannel::eBroadcastBitHasUserInput) 984 { 985 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for 986 // handling. 987 988 const char *command_string = SBEvent::GetCStringFromEvent(event); 989 if (command_string == NULL) 990 command_string = ""; 991 SBCommandReturnObject result; 992 993 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd 994 // output orderings and problems with the prompt. 995 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true); 996 997 if (result.GetOutputSize() > 0) 998 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC); 999 1000 if (result.GetErrorSize() > 0) 1001 m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC); 1002 1003 // We are done getting and running our command, we can now clear the 1004 // m_waiting_for_command so we can get another one. 1005 m_waiting_for_command = false; 1006 1007 // If our editline input reader is active, it means another input reader 1008 // got pushed onto the input reader and caused us to become deactivated. 1009 // When the input reader above us gets popped, we will get re-activated 1010 // and our prompt will refresh in our callback 1011 if (m_editline_reader.IsActive()) 1012 { 1013 ReadyForCommand (); 1014 } 1015 } 1016 else if (event_type & IOChannel::eBroadcastBitUserInterrupt) 1017 { 1018 // This is here to handle control-c interrupts from the user. It has not yet really been implemented. 1019 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER 1020 //m_io_channel_ap->CancelInput(); 1021 // Anything else? Send Interrupt to process? 1022 } 1023 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 1024 (event_type & IOChannel::eBroadcastBitThreadDidExit)) 1025 { 1026 // If the IOChannel thread is trying to go away, then it is definitely 1027 // time to end the debugging session. 1028 quit = true; 1029 } 1030 1031 return quit; 1032} 1033 1034void 1035Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len) 1036{ 1037 Driver *driver = (Driver*)baton; 1038 driver->GetFromMaster ((const char *)src, src_len); 1039} 1040 1041void 1042Driver::GetFromMaster (const char *src, size_t src_len) 1043{ 1044 // Echo the characters back to the Debugger's stdout, that way if you 1045 // type characters while a command is running, you'll see what you've typed. 1046 FILE *out_fh = m_debugger.GetOutputFileHandle(); 1047 if (out_fh) 1048 ::fwrite (src, 1, src_len, out_fh); 1049} 1050 1051size_t 1052Driver::EditLineInputReaderCallback 1053( 1054 void *baton, 1055 SBInputReader *reader, 1056 InputReaderAction notification, 1057 const char *bytes, 1058 size_t bytes_len 1059) 1060{ 1061 Driver *driver = (Driver *)baton; 1062 1063 switch (notification) 1064 { 1065 case eInputReaderActivate: 1066 break; 1067 1068 case eInputReaderReactivate: 1069 driver->ReadyForCommand(); 1070 break; 1071 1072 case eInputReaderDeactivate: 1073 break; 1074 1075 case eInputReaderAsynchronousOutputWritten: 1076 if (driver->m_io_channel_ap.get() != NULL) 1077 driver->m_io_channel_ap->RefreshPrompt(); 1078 break; 1079 1080 case eInputReaderInterrupt: 1081 if (driver->m_io_channel_ap.get() != NULL) 1082 { 1083 SBProcess process = driver->GetDebugger().GetSelectedTarget().GetProcess(); 1084 if (!driver->m_io_channel_ap->EditLineHasCharacters() 1085 && process.IsValid() && process.GetState() == lldb::eStateRunning) 1086 { 1087 process.Stop(); 1088 } 1089 else 1090 { 1091 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC); 1092 // I wish I could erase the entire input line, but there's no public API for that. 1093 driver->m_io_channel_ap->EraseCharsBeforeCursor(); 1094 driver->m_io_channel_ap->RefreshPrompt(); 1095 } 1096 } 1097 break; 1098 1099 case eInputReaderEndOfFile: 1100 if (driver->m_io_channel_ap.get() != NULL) 1101 { 1102 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC); 1103 driver->m_io_channel_ap->RefreshPrompt (); 1104 } 1105 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5); 1106 break; 1107 1108 case eInputReaderGotToken: 1109 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len); 1110 break; 1111 1112 case eInputReaderDone: 1113 break; 1114 } 1115 return bytes_len; 1116} 1117 1118void 1119Driver::MainLoop () 1120{ 1121 char error_str[1024]; 1122 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false) 1123 { 1124 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str); 1125 exit(1); 1126 } 1127 else 1128 { 1129 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str)); 1130 if (driver_slave_name == NULL) 1131 { 1132 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str); 1133 exit(2); 1134 } 1135 else 1136 { 1137 m_editline_slave_fh = ::fopen (driver_slave_name, "r+"); 1138 if (m_editline_slave_fh == NULL) 1139 { 1140 SBError error; 1141 error.SetErrorToErrno(); 1142 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s", 1143 error.GetCString()); 1144 exit(3); 1145 } 1146 1147 ::setbuf (m_editline_slave_fh, NULL); 1148 } 1149 } 1150 1151 lldb_utility::PseudoTerminal editline_output_pty; 1152 FILE *editline_output_slave_fh = NULL; 1153 1154 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false) 1155 { 1156 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str); 1157 exit(1); 1158 } 1159 else 1160 { 1161 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str)); 1162 if (output_slave_name == NULL) 1163 { 1164 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str); 1165 exit(2); 1166 } 1167 else 1168 { 1169 editline_output_slave_fh = ::fopen (output_slave_name, "r+"); 1170 if (editline_output_slave_fh == NULL) 1171 { 1172 SBError error; 1173 error.SetErrorToErrno(); 1174 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s", 1175 error.GetCString()); 1176 exit(3); 1177 } 1178 ::setbuf (editline_output_slave_fh, NULL); 1179 } 1180 } 1181 1182 // struct termios stdin_termios; 1183 1184 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) 1185 { 1186 g_old_stdin_termios_is_valid = true; 1187 atexit (reset_stdin_termios); 1188 } 1189 1190 ::setbuf (stdin, NULL); 1191 ::setbuf (stdout, NULL); 1192 1193 m_debugger.SetErrorFileHandle (stderr, false); 1194 m_debugger.SetOutputFileHandle (stdout, false); 1195 m_debugger.SetInputFileHandle (stdin, true); 1196 1197 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); 1198 1199 // You have to drain anything that comes to the master side of the PTY. master_out_comm is 1200 // for that purpose. The reason you need to do this is a curious reason... editline will echo 1201 // characters to the PTY when it gets characters while el_gets is not running, and then when 1202 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks 1203 // if there are unconsumed characters in the out buffer. 1204 // However, you don't need to do anything with the characters, since editline will dump these 1205 // unconsumed characters after printing the prompt again in el_gets. 1206 1207 SBCommunication master_out_comm("driver.editline"); 1208 master_out_comm.SetCloseOnEOF (false); 1209 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false); 1210 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this); 1211 1212 if (master_out_comm.ReadThreadStart () == false) 1213 { 1214 ::fprintf (stderr, "error: failed to start master out read thread"); 1215 exit(5); 1216 } 1217 1218 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); 1219 1220 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this)); 1221 1222 SBCommunication out_comm_2("driver.editline_output"); 1223 out_comm_2.SetCloseOnEOF (false); 1224 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false); 1225 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get()); 1226 1227 if (out_comm_2.ReadThreadStart () == false) 1228 { 1229 ::fprintf (stderr, "error: failed to start libedit output read thread"); 1230 exit (5); 1231 } 1232 1233 1234 struct winsize window_size; 1235 if (isatty (STDIN_FILENO) 1236 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1237 { 1238 if (window_size.ws_col > 0) 1239 m_debugger.SetTerminalWidth (window_size.ws_col); 1240 } 1241 1242 // Since input can be redirected by the debugger, we must insert our editline 1243 // input reader in the queue so we know when our reader should be active 1244 // and so we can receive bytes only when we are supposed to. 1245 SBError err (m_editline_reader.Initialize (m_debugger, 1246 Driver::EditLineInputReaderCallback, // callback 1247 this, // baton 1248 eInputReaderGranularityByte, // token_size 1249 NULL, // end token - NULL means never done 1250 NULL, // prompt - taken care of elsewhere 1251 false)); // echo input - don't need Debugger 1252 // to do this, we handle it elsewhere 1253 1254 if (err.Fail()) 1255 { 1256 ::fprintf (stderr, "error: %s", err.GetCString()); 1257 exit (6); 1258 } 1259 1260 m_debugger.PushInputReader (m_editline_reader); 1261 1262 SBListener listener(m_debugger.GetListener()); 1263 listener.StartListeningForEventClass(m_debugger, 1264 SBTarget::GetBroadcasterClassName(), 1265 SBTarget::eBroadcastBitBreakpointChanged); 1266 if (listener.IsValid()) 1267 { 1268 1269 listener.StartListeningForEvents (*m_io_channel_ap, 1270 IOChannel::eBroadcastBitHasUserInput | 1271 IOChannel::eBroadcastBitUserInterrupt | 1272 IOChannel::eBroadcastBitThreadShouldExit | 1273 IOChannel::eBroadcastBitThreadDidStart | 1274 IOChannel::eBroadcastBitThreadDidExit); 1275 1276 if (m_io_channel_ap->Start ()) 1277 { 1278 bool iochannel_thread_exited = false; 1279 1280 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(), 1281 SBCommandInterpreter::eBroadcastBitQuitCommandReceived | 1282 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData | 1283 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData); 1284 1285 // Before we handle any options from the command line, we parse the 1286 // .lldbinit file in the user's home directory. 1287 SBCommandReturnObject result; 1288 sb_interpreter.SourceInitFileInHomeDirectory(result); 1289 if (GetDebugMode()) 1290 { 1291 result.PutError (m_debugger.GetErrorFileHandle()); 1292 result.PutOutput (m_debugger.GetOutputFileHandle()); 1293 } 1294 1295 // Now we handle options we got from the command line 1296 char command_string[PATH_MAX * 2]; 1297 const size_t num_source_command_files = GetNumSourceCommandFiles(); 1298 if (num_source_command_files > 0) 1299 { 1300 for (size_t i=0; i < num_source_command_files; ++i) 1301 { 1302 const char *command_file = GetSourceCommandFileAtIndex(i); 1303 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file); 1304 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false); 1305 if (GetDebugMode()) 1306 { 1307 result.PutError (m_debugger.GetErrorFileHandle()); 1308 result.PutOutput (m_debugger.GetOutputFileHandle()); 1309 } 1310 } 1311 } 1312 1313 const size_t num_args = m_option_data.m_args.size(); 1314 if (num_args > 0) 1315 { 1316 char arch_name[64]; 1317 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) 1318 ::snprintf (command_string, 1319 sizeof (command_string), 1320 "target create --arch=%s \"%s\"", 1321 arch_name, 1322 m_option_data.m_args[0].c_str()); 1323 else 1324 ::snprintf (command_string, 1325 sizeof(command_string), 1326 "target create \"%s\"", 1327 m_option_data.m_args[0].c_str()); 1328 1329 m_debugger.HandleCommand (command_string); 1330 1331 if (num_args > 1) 1332 { 1333 m_debugger.HandleCommand ("settings clear target.run-args"); 1334 char arg_cstr[1024]; 1335 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) 1336 { 1337 ::snprintf (arg_cstr, 1338 sizeof(arg_cstr), 1339 "settings append target.run-args \"%s\"", 1340 m_option_data.m_args[arg_idx].c_str()); 1341 m_debugger.HandleCommand (arg_cstr); 1342 } 1343 } 1344 } 1345 1346 // Now that all option parsing is done, we try and parse the .lldbinit 1347 // file in the current working directory 1348 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result); 1349 if (GetDebugMode()) 1350 { 1351 result.PutError(m_debugger.GetErrorFileHandle()); 1352 result.PutOutput(m_debugger.GetOutputFileHandle()); 1353 } 1354 1355 SBEvent event; 1356 1357 // Make sure the IO channel is started up before we try to tell it we 1358 // are ready for input 1359 listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 1360 *m_io_channel_ap, 1361 IOChannel::eBroadcastBitThreadDidStart, 1362 event); 1363 // If we were asked to attach, then do that here: 1364 // I'm going to use the command string rather than directly 1365 // calling the API's because then I don't have to recode the 1366 // event handling here. 1367 if (!m_option_data.m_process_name.empty() 1368 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 1369 { 1370 std::string command_str("process attach "); 1371 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID) 1372 { 1373 command_str.append("-p "); 1374 char pid_buffer[32]; 1375 ::snprintf (pid_buffer, sizeof(pid_buffer), "%llu", m_option_data.m_process_pid); 1376 command_str.append(pid_buffer); 1377 } 1378 else 1379 { 1380 command_str.append("-n \""); 1381 command_str.append(m_option_data.m_process_name); 1382 command_str.push_back('\"'); 1383 if (m_option_data.m_wait_for) 1384 command_str.append(" -w"); 1385 } 1386 1387 if (m_debugger.GetOutputFileHandle()) 1388 ::fprintf (m_debugger.GetOutputFileHandle(), 1389 "Attaching to process with:\n %s\n", 1390 command_str.c_str()); 1391 1392 // Force the attach to be synchronous: 1393 bool orig_async = m_debugger.GetAsync(); 1394 m_debugger.SetAsync(true); 1395 m_debugger.HandleCommand(command_str.c_str()); 1396 m_debugger.SetAsync(orig_async); 1397 } 1398 1399 ReadyForCommand (); 1400 1401 while (!GetIsDone()) 1402 { 1403 listener.WaitForEvent (UINT32_MAX, event); 1404 if (event.IsValid()) 1405 { 1406 if (event.GetBroadcaster().IsValid()) 1407 { 1408 uint32_t event_type = event.GetType(); 1409 if (event.BroadcasterMatchesRef (*m_io_channel_ap)) 1410 { 1411 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || 1412 (event_type & IOChannel::eBroadcastBitThreadDidExit)) 1413 { 1414 SetIsDone(); 1415 if (event_type & IOChannel::eBroadcastBitThreadDidExit) 1416 iochannel_thread_exited = true; 1417 } 1418 else 1419 { 1420 if (HandleIOEvent (event)) 1421 SetIsDone(); 1422 } 1423 } 1424 else if (SBProcess::EventIsProcessEvent (event)) 1425 { 1426 HandleProcessEvent (event); 1427 } 1428 else if (SBBreakpoint::EventIsBreakpointEvent (event)) 1429 { 1430 HandleBreakpointEvent (event); 1431 } 1432 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster())) 1433 { 1434 // TODO: deprecate the eBroadcastBitQuitCommandReceived event 1435 // now that we have SBCommandInterpreter::SetCommandOverrideCallback() 1436 // that can take over a command 1437 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived) 1438 { 1439 SetIsDone(); 1440 } 1441 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData) 1442 { 1443 const char *data = SBEvent::GetCStringFromEvent (event); 1444 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC); 1445 } 1446 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData) 1447 { 1448 const char *data = SBEvent::GetCStringFromEvent (event); 1449 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC); 1450 } 1451 } 1452 } 1453 } 1454 } 1455 1456 editline_output_pty.CloseMasterFileDescriptor(); 1457 master_out_comm.Disconnect(); 1458 out_comm_2.Disconnect(); 1459 reset_stdin_termios(); 1460 fclose (stdin); 1461 1462 CloseIOChannelFile (); 1463 1464 if (!iochannel_thread_exited) 1465 { 1466 event.Clear(); 1467 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap, 1468 IOChannel::eBroadcastBitThreadDidExit, 1469 event); 1470 if (!event.IsValid()) 1471 { 1472 // Send end EOF to the driver file descriptor 1473 m_io_channel_ap->Stop(); 1474 } 1475 } 1476 1477 SBDebugger::Destroy (m_debugger); 1478 } 1479 } 1480} 1481 1482 1483void 1484Driver::ReadyForCommand () 1485{ 1486 if (m_waiting_for_command == false) 1487 { 1488 m_waiting_for_command = true; 1489 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true); 1490 } 1491} 1492 1493 1494void 1495sigwinch_handler (int signo) 1496{ 1497 struct winsize window_size; 1498 if (isatty (STDIN_FILENO) 1499 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 1500 { 1501 if ((window_size.ws_col > 0) && g_driver != NULL) 1502 { 1503 g_driver->GetDebugger().SetTerminalWidth (window_size.ws_col); 1504 } 1505 } 1506} 1507 1508void 1509sigint_handler (int signo) 1510{ 1511 static bool g_interrupt_sent = false; 1512 if (g_driver) 1513 { 1514 if (!g_interrupt_sent) 1515 { 1516 g_interrupt_sent = true; 1517 g_driver->GetDebugger().DispatchInputInterrupt(); 1518 g_interrupt_sent = false; 1519 return; 1520 } 1521 } 1522 1523 exit (signo); 1524} 1525 1526int 1527main (int argc, char const *argv[], const char *envp[]) 1528{ 1529 SBDebugger::Initialize(); 1530 1531 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>"); 1532 1533 signal (SIGPIPE, SIG_IGN); 1534 signal (SIGWINCH, sigwinch_handler); 1535 signal (SIGINT, sigint_handler); 1536 1537 // Create a scope for driver so that the driver object will destroy itself 1538 // before SBDebugger::Terminate() is called. 1539 { 1540 Driver driver; 1541 1542 bool exit = false; 1543 SBError error (driver.ParseArgs (argc, argv, stdout, exit)); 1544 if (error.Fail()) 1545 { 1546 const char *error_cstr = error.GetCString (); 1547 if (error_cstr) 1548 ::fprintf (stderr, "error: %s\n", error_cstr); 1549 } 1550 else if (!exit) 1551 { 1552 driver.MainLoop (); 1553 } 1554 } 1555 1556 SBDebugger::Terminate(); 1557 return 0; 1558} 1559