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 <stdio.h> 13 #include <string.h> 14 #include <stdlib.h> 15 #include <limits.h> 16 #include <fcntl.h> 17 18 #include <string> 19 20 #include <thread> 21 #include "lldb/API/SBBreakpoint.h" 22 #include "lldb/API/SBCommandInterpreter.h" 23 #include "lldb/API/SBCommandReturnObject.h" 24 #include "lldb/API/SBCommunication.h" 25 #include "lldb/API/SBDebugger.h" 26 #include "lldb/API/SBEvent.h" 27 #include "lldb/API/SBHostOS.h" 28 #include "lldb/API/SBListener.h" 29 #include "lldb/API/SBStream.h" 30 #include "lldb/API/SBTarget.h" 31 #include "lldb/API/SBThread.h" 32 #include "lldb/API/SBProcess.h" 33 34 using namespace lldb; 35 36 static void reset_stdin_termios (); 37 static bool g_old_stdin_termios_is_valid = false; 38 static struct termios g_old_stdin_termios; 39 40 static char *g_debugger_name = (char *) ""; 41 static Driver *g_driver = NULL; 42 43 // In the Driver::MainLoop, we change the terminal settings. This function is 44 // added as an atexit handler to make sure we clean them up. 45 static void 46 reset_stdin_termios () 47 { 48 if (g_old_stdin_termios_is_valid) 49 { 50 g_old_stdin_termios_is_valid = false; 51 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios); 52 } 53 } 54 55 typedef struct 56 { 57 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0 58 // then this option belongs to option set n. 59 bool required; // This option is required (in the current usage level) 60 const char * long_option; // Full name for this option. 61 int short_option; // Single character for this option. 62 int option_has_arg; // no_argument, required_argument or optional_argument 63 uint32_t completion_type; // Cookie the option class can use to do define the argument completion. 64 lldb::CommandArgumentType argument_type; // Type of argument this option takes 65 const char * usage_text; // Full text explaining what this options does and what (if any) argument to 66 // pass it. 67 } OptionDefinition; 68 69 #define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5 70 #define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5 71 72 static OptionDefinition g_options[] = 73 { 74 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone, 75 "Prints out the usage information for the LLDB debugger." }, 76 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone, 77 "Prints out the current version number of the LLDB debugger." }, 78 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture, 79 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must " 80 "be one of the architectures for which the program was compiled." }, 81 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename, 82 "Tells the debugger to use the file <filename> as the program to be debugged." }, 83 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename, 84 "Tells the debugger to use the fullpath to <path> as the core file." }, 85 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName, 86 "Tells the debugger to attach to a process with the given name." }, 87 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone, 88 "Tells the debugger to wait for a process with the given pid or name to launch before attaching." }, 89 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid, 90 "Tells the debugger to attach to a process with the given pid." }, 91 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang, 92 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. " 93 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python " 94 "extensions have been implemented." }, 95 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone, 96 "Tells the debugger to print out extra information for debugging itself." }, 97 { LLDB_3_TO_5, false, "source-quietly" , 'b', no_argument , 0, eArgTypeNone, 98 "Tells the debugger to print out extra information for debugging itself." }, 99 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename, 100 "Tells the debugger to read in and execute the lldb commands in the given file, after any file provided on the command line has been loaded." }, 101 { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone, 102 "Tells the debugger to execute this one-line lldb command after any file provided on the command line has been loaded." }, 103 { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename, 104 "Tells the debugger to read in and execute the lldb commands in the given file, before any file provided on the command line has been loaded." }, 105 { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone, 106 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." }, 107 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone, 108 "Tells the debugger to open source files using the host's \"external editor\" mechanism." }, 109 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone, 110 "Do not automatically parse any '.lldbinit' files." }, 111 { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone, 112 "Do not use colors." }, 113 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone, 114 "Prints out the path to the lldb.py file for this version of lldb." }, 115 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL } 116 }; 117 118 static const uint32_t last_option_set_with_args = 2; 119 120 Driver::Driver () : 121 SBBroadcaster ("Driver"), 122 m_debugger (SBDebugger::Create(false)), 123 m_option_data () 124 { 125 // We want to be able to handle CTRL+D in the terminal to have it terminate 126 // certain input 127 m_debugger.SetCloseInputOnEOF (false); 128 g_debugger_name = (char *) m_debugger.GetInstanceName(); 129 if (g_debugger_name == NULL) 130 g_debugger_name = (char *) ""; 131 g_driver = this; 132 } 133 134 Driver::~Driver () 135 { 136 g_driver = NULL; 137 g_debugger_name = NULL; 138 } 139 140 141 // This function takes INDENT, which tells how many spaces to output at the front 142 // of each line; TEXT, which is the text that is to be output. It outputs the 143 // text, on multiple lines if necessary, to RESULT, with INDENT spaces at the 144 // front of each line. It breaks lines on spaces, tabs or newlines, shortening 145 // the line if necessary to not break in the middle of a word. It assumes that 146 // each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters. 147 148 void 149 OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns) 150 { 151 int len = strlen (text); 152 std::string text_string (text); 153 154 // Force indentation to be reasonable. 155 if (indent >= output_max_columns) 156 indent = 0; 157 158 // Will it all fit on one line? 159 160 if (len + indent < output_max_columns) 161 // Output as a single line 162 fprintf (out, "%*s%s\n", indent, "", text); 163 else 164 { 165 // We need to break it up into multiple lines. 166 int text_width = output_max_columns - indent - 1; 167 int start = 0; 168 int end = start; 169 int final_end = len; 170 int sub_len; 171 172 while (end < final_end) 173 { 174 // Dont start the 'text' on a space, since we're already outputting the indentation. 175 while ((start < final_end) && (text[start] == ' ')) 176 start++; 177 178 end = start + text_width; 179 if (end > final_end) 180 end = final_end; 181 else 182 { 183 // If we're not at the end of the text, make sure we break the line on white space. 184 while (end > start 185 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 186 end--; 187 } 188 sub_len = end - start; 189 std::string substring = text_string.substr (start, sub_len); 190 fprintf (out, "%*s%s\n", indent, "", substring.c_str()); 191 start = end + 1; 192 } 193 } 194 } 195 196 void 197 ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data) 198 { 199 uint32_t screen_width = 80; 200 uint32_t indent_level = 0; 201 const char *name = "lldb"; 202 203 fprintf (out, "\nUsage:\n\n"); 204 205 indent_level += 2; 206 207 208 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0] 209 // <cmd> [options-for-level-1] 210 // etc. 211 212 uint32_t num_options; 213 uint32_t num_option_sets = 0; 214 215 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options) 216 { 217 uint32_t this_usage_mask = option_table[num_options].usage_mask; 218 if (this_usage_mask == LLDB_OPT_SET_ALL) 219 { 220 if (num_option_sets == 0) 221 num_option_sets = 1; 222 } 223 else 224 { 225 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) 226 { 227 if (this_usage_mask & 1 << j) 228 { 229 if (num_option_sets <= j) 230 num_option_sets = j + 1; 231 } 232 } 233 } 234 } 235 236 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++) 237 { 238 uint32_t opt_set_mask; 239 240 opt_set_mask = 1 << opt_set; 241 242 if (opt_set > 0) 243 fprintf (out, "\n"); 244 fprintf (out, "%*s%s", indent_level, "", name); 245 bool is_help_line = false; 246 247 for (uint32_t i = 0; i < num_options; ++i) 248 { 249 if (option_table[i].usage_mask & opt_set_mask) 250 { 251 CommandArgumentType arg_type = option_table[i].argument_type; 252 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type); 253 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet... 254 // so we do it by hand here. 255 if (option_table[i].short_option == 'h') 256 is_help_line = true; 257 258 if (option_table[i].required) 259 { 260 if (option_table[i].option_has_arg == required_argument) 261 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name); 262 else if (option_table[i].option_has_arg == optional_argument) 263 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name); 264 else 265 fprintf (out, " -%c", option_table[i].short_option); 266 } 267 else 268 { 269 if (option_table[i].option_has_arg == required_argument) 270 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name); 271 else if (option_table[i].option_has_arg == optional_argument) 272 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name); 273 else 274 fprintf (out, " [-%c]", option_table[i].short_option); 275 } 276 } 277 } 278 if (!is_help_line && (opt_set <= last_option_set_with_args)) 279 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]"); 280 } 281 282 fprintf (out, "\n\n"); 283 284 // Now print out all the detailed information about the various options: long form, short form and help text: 285 // -- long_name <argument> 286 // - short <argument> 287 // help text 288 289 // This variable is used to keep track of which options' info we've printed out, because some options can be in 290 // more than one usage level, but we only want to print the long form of its information once. 291 292 Driver::OptionData::OptionSet options_seen; 293 Driver::OptionData::OptionSet::iterator pos; 294 295 indent_level += 5; 296 297 for (uint32_t i = 0; i < num_options; ++i) 298 { 299 // Only print this option if we haven't already seen it. 300 pos = options_seen.find (option_table[i].short_option); 301 if (pos == options_seen.end()) 302 { 303 CommandArgumentType arg_type = option_table[i].argument_type; 304 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type); 305 306 options_seen.insert (option_table[i].short_option); 307 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option); 308 if (arg_type != eArgTypeNone) 309 fprintf (out, "<%s>", arg_name); 310 fprintf (out, "\n"); 311 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option); 312 if (arg_type != eArgTypeNone) 313 fprintf (out, "<%s>", arg_name); 314 fprintf (out, "\n"); 315 indent_level += 5; 316 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width); 317 indent_level -= 5; 318 fprintf (out, "\n"); 319 } 320 } 321 322 indent_level -= 5; 323 324 fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed from left to right in order, " 325 "\n%*swith the source files and commands interleaved. The same is true of the \"-S\" and \"-O\" options." 326 "\n%*sThe before file and after file sets can intermixed freely, the command parser will sort them out." 327 "\n%*sThe order of the file specifiers (\"-c\", \"-f\", etc.) is not significant in this regard.\n\n", 328 indent_level, "", 329 indent_level, "", 330 indent_level, "", 331 indent_level, ""); 332 333 fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged" 334 "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works." 335 "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n", 336 indent_level, "", 337 indent_level, "", 338 name, 339 indent_level, ""); 340 } 341 342 void 343 BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table, 344 uint32_t num_options) 345 { 346 if (num_options == 0) 347 return; 348 349 uint32_t i; 350 uint32_t j; 351 std::bitset<256> option_seen; 352 353 getopt_table.resize (num_options + 1); 354 355 for (i = 0, j = 0; i < num_options; ++i) 356 { 357 char short_opt = expanded_option_table[i].short_option; 358 359 if (option_seen.test(short_opt) == false) 360 { 361 getopt_table[j].name = expanded_option_table[i].long_option; 362 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg; 363 getopt_table[j].flag = NULL; 364 getopt_table[j].val = expanded_option_table[i].short_option; 365 option_seen.set(short_opt); 366 ++j; 367 } 368 } 369 370 getopt_table[j].name = NULL; 371 getopt_table[j].has_arg = 0; 372 getopt_table[j].flag = NULL; 373 getopt_table[j].val = 0; 374 375 } 376 377 Driver::OptionData::OptionData () : 378 m_args(), 379 m_script_lang (lldb::eScriptLanguageDefault), 380 m_core_file (), 381 m_crash_log (), 382 m_initial_commands (), 383 m_after_file_commands (), 384 m_debug_mode (false), 385 m_source_quietly(false), 386 m_print_version (false), 387 m_print_python_path (false), 388 m_print_help (false), 389 m_wait_for(false), 390 m_process_name(), 391 m_process_pid(LLDB_INVALID_PROCESS_ID), 392 m_use_external_editor(false), 393 m_seen_options() 394 { 395 } 396 397 Driver::OptionData::~OptionData () 398 { 399 } 400 401 void 402 Driver::OptionData::Clear () 403 { 404 m_args.clear (); 405 m_script_lang = lldb::eScriptLanguageDefault; 406 m_initial_commands.clear (); 407 m_after_file_commands.clear (); 408 m_debug_mode = false; 409 m_source_quietly = false; 410 m_print_help = false; 411 m_print_version = false; 412 m_print_python_path = false; 413 m_use_external_editor = false; 414 m_wait_for = false; 415 m_process_name.erase(); 416 m_process_pid = LLDB_INVALID_PROCESS_ID; 417 } 418 419 void 420 Driver::OptionData::AddInitialCommand (const char *command, bool before_file, bool is_file, SBError &error) 421 { 422 std::vector<std::pair<bool, std::string> > *command_set; 423 if (before_file) 424 command_set = &(m_initial_commands); 425 else 426 command_set = &(m_after_file_commands); 427 428 if (is_file) 429 { 430 SBFileSpec file(command); 431 if (file.Exists()) 432 command_set->push_back (std::pair<bool, std::string> (true, optarg)); 433 else if (file.ResolveExecutableLocation()) 434 { 435 char final_path[PATH_MAX]; 436 file.GetPath (final_path, sizeof(final_path)); 437 std::string path_str (final_path); 438 command_set->push_back (std::pair<bool, std::string> (true, path_str)); 439 } 440 else 441 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); 442 } 443 else 444 command_set->push_back (std::pair<bool, std::string> (false, optarg)); 445 } 446 447 void 448 Driver::ResetOptionValues () 449 { 450 m_option_data.Clear (); 451 } 452 453 const char * 454 Driver::GetFilename() const 455 { 456 if (m_option_data.m_args.empty()) 457 return NULL; 458 return m_option_data.m_args.front().c_str(); 459 } 460 461 const char * 462 Driver::GetCrashLogFilename() const 463 { 464 if (m_option_data.m_crash_log.empty()) 465 return NULL; 466 return m_option_data.m_crash_log.c_str(); 467 } 468 469 lldb::ScriptLanguage 470 Driver::GetScriptLanguage() const 471 { 472 return m_option_data.m_script_lang; 473 } 474 475 void 476 Driver::ExecuteInitialCommands (bool before_file) 477 { 478 size_t num_commands; 479 std::vector<std::pair<bool, std::string> > *command_set; 480 if (before_file) 481 command_set = &(m_option_data.m_initial_commands); 482 else 483 command_set = &(m_option_data.m_after_file_commands); 484 485 num_commands = command_set->size(); 486 SBCommandReturnObject result; 487 bool old_async = GetDebugger().GetAsync(); 488 GetDebugger().SetAsync(false); 489 for (size_t idx = 0; idx < num_commands; idx++) 490 { 491 bool is_file = (*command_set)[idx].first; 492 const char *command = (*command_set)[idx].second.c_str(); 493 char command_string[PATH_MAX * 2]; 494 const bool dump_stream_only_if_no_immediate = true; 495 const char *executed_command = command; 496 if (is_file) 497 { 498 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command); 499 executed_command = command_string; 500 } 501 502 m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false); 503 if (!m_option_data.m_source_quietly || result.Succeeded() == false) 504 { 505 const size_t output_size = result.GetOutputSize(); 506 if (output_size > 0) 507 { 508 const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate); 509 if (cstr) 510 printf ("%s", cstr); 511 } 512 const size_t error_size = result.GetErrorSize(); 513 if (error_size > 0) 514 { 515 const char *cstr = result.GetError(dump_stream_only_if_no_immediate); 516 if (cstr) 517 printf ("%s", cstr); 518 } 519 } 520 521 if (result.Succeeded() == false) 522 { 523 const char *type = before_file ? "before file" : "after_file"; 524 if (is_file) 525 ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command); 526 else 527 ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command); 528 break; 529 } 530 result.Clear(); 531 } 532 GetDebugger().SetAsync(old_async); 533 } 534 535 bool 536 Driver::GetDebugMode() const 537 { 538 return m_option_data.m_debug_mode; 539 } 540 541 542 // Check the arguments that were passed to this program to make sure they are valid and to get their 543 // argument values (if any). Return a boolean value indicating whether or not to start up the full 544 // debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR 545 // if the user only wanted help or version information. 546 547 SBError 548 Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting) 549 { 550 ResetOptionValues (); 551 552 SBCommandReturnObject result; 553 554 SBError error; 555 std::string option_string; 556 struct option *long_options = NULL; 557 std::vector<struct option> long_options_vector; 558 uint32_t num_options; 559 560 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options) 561 /* Do Nothing. */; 562 563 if (num_options == 0) 564 { 565 if (argc > 1) 566 error.SetErrorStringWithFormat ("invalid number of options"); 567 return error; 568 } 569 570 BuildGetOptTable (g_options, long_options_vector, num_options); 571 572 if (long_options_vector.empty()) 573 long_options = NULL; 574 else 575 long_options = &long_options_vector.front(); 576 577 if (long_options == NULL) 578 { 579 error.SetErrorStringWithFormat ("invalid long options"); 580 return error; 581 } 582 583 // Build the option_string argument for call to getopt_long_only. 584 585 for (int i = 0; long_options[i].name != NULL; ++i) 586 { 587 if (long_options[i].flag == NULL) 588 { 589 option_string.push_back ((char) long_options[i].val); 590 switch (long_options[i].has_arg) 591 { 592 default: 593 case no_argument: 594 break; 595 case required_argument: 596 option_string.push_back (':'); 597 break; 598 case optional_argument: 599 option_string.append ("::"); 600 break; 601 } 602 } 603 } 604 605 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't 606 // know at that point whether we should read in init files yet. So we don't read them in in the 607 // Driver constructor, then set the flags back to "read them in" here, and then if we see the 608 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the 609 // main loop. 610 611 m_debugger.SkipLLDBInitFiles (false); 612 m_debugger.SkipAppInitFiles (false); 613 614 // Prepare for & make calls to getopt_long_only. 615 #if __GLIBC__ 616 optind = 0; 617 #else 618 optreset = 1; 619 optind = 1; 620 #endif 621 int val; 622 while (1) 623 { 624 int long_options_index = -1; 625 val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index); 626 627 if (val == -1) 628 break; 629 else if (val == '?') 630 { 631 m_option_data.m_print_help = true; 632 error.SetErrorStringWithFormat ("unknown or ambiguous option"); 633 break; 634 } 635 else if (val == 0) 636 continue; 637 else 638 { 639 m_option_data.m_seen_options.insert ((char) val); 640 if (long_options_index == -1) 641 { 642 for (int i = 0; 643 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val; 644 ++i) 645 { 646 if (long_options[i].val == val) 647 { 648 long_options_index = i; 649 break; 650 } 651 } 652 } 653 654 if (long_options_index >= 0) 655 { 656 const int short_option = g_options[long_options_index].short_option; 657 658 switch (short_option) 659 { 660 case 'h': 661 m_option_data.m_print_help = true; 662 break; 663 664 case 'v': 665 m_option_data.m_print_version = true; 666 break; 667 668 case 'P': 669 m_option_data.m_print_python_path = true; 670 break; 671 672 case 'c': 673 { 674 SBFileSpec file(optarg); 675 if (file.Exists()) 676 { 677 m_option_data.m_core_file = optarg; 678 } 679 else 680 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg); 681 } 682 break; 683 684 case 'e': 685 m_option_data.m_use_external_editor = true; 686 break; 687 688 case 'x': 689 m_debugger.SkipLLDBInitFiles (true); 690 m_debugger.SkipAppInitFiles (true); 691 break; 692 693 case 'X': 694 m_debugger.SetUseColor (false); 695 break; 696 697 case 'f': 698 { 699 SBFileSpec file(optarg); 700 if (file.Exists()) 701 { 702 m_option_data.m_args.push_back (optarg); 703 } 704 else if (file.ResolveExecutableLocation()) 705 { 706 char path[PATH_MAX]; 707 file.GetPath (path, sizeof(path)); 708 m_option_data.m_args.push_back (path); 709 } 710 else 711 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg); 712 } 713 break; 714 715 case 'a': 716 if (!m_debugger.SetDefaultArchitecture (optarg)) 717 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg); 718 break; 719 720 case 'l': 721 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg); 722 break; 723 724 case 'd': 725 m_option_data.m_debug_mode = true; 726 break; 727 728 case 'q': 729 m_option_data.m_source_quietly = true; 730 break; 731 732 case 'n': 733 m_option_data.m_process_name = optarg; 734 break; 735 736 case 'w': 737 m_option_data.m_wait_for = true; 738 break; 739 740 case 'p': 741 { 742 char *remainder; 743 m_option_data.m_process_pid = strtol (optarg, &remainder, 0); 744 if (remainder == optarg || *remainder != '\0') 745 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.", 746 optarg); 747 } 748 break; 749 case 's': 750 m_option_data.AddInitialCommand(optarg, false, true, error); 751 break; 752 case 'o': 753 m_option_data.AddInitialCommand(optarg, false, false, error); 754 break; 755 case 'S': 756 m_option_data.AddInitialCommand(optarg, true, true, error); 757 break; 758 case 'O': 759 m_option_data.AddInitialCommand(optarg, true, false, error); 760 break; 761 default: 762 m_option_data.m_print_help = true; 763 error.SetErrorStringWithFormat ("unrecognized option %c", short_option); 764 break; 765 } 766 } 767 else 768 { 769 error.SetErrorStringWithFormat ("invalid option with value %i", val); 770 } 771 if (error.Fail()) 772 { 773 return error; 774 } 775 } 776 } 777 778 if (error.Fail() || m_option_data.m_print_help) 779 { 780 ShowUsage (out_fh, g_options, m_option_data); 781 exiting = true; 782 } 783 else if (m_option_data.m_print_version) 784 { 785 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString()); 786 exiting = true; 787 } 788 else if (m_option_data.m_print_python_path) 789 { 790 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath(); 791 if (python_file_spec.IsValid()) 792 { 793 char python_path[PATH_MAX]; 794 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX); 795 if (num_chars < PATH_MAX) 796 { 797 ::fprintf (out_fh, "%s\n", python_path); 798 } 799 else 800 ::fprintf (out_fh, "<PATH TOO LONG>\n"); 801 } 802 else 803 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n"); 804 exiting = true; 805 } 806 else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) 807 { 808 // Any arguments that are left over after option parsing are for 809 // the program. If a file was specified with -f then the filename 810 // is already in the m_option_data.m_args array, and any remaining args 811 // are arguments for the inferior program. If no file was specified with 812 // -f, then what is left is the program name followed by any arguments. 813 814 // Skip any options we consumed with getopt_long_only 815 argc -= optind; 816 argv += optind; 817 818 if (argc > 0) 819 { 820 for (int arg_idx=0; arg_idx<argc; ++arg_idx) 821 { 822 const char *arg = argv[arg_idx]; 823 if (arg) 824 m_option_data.m_args.push_back (arg); 825 } 826 } 827 828 } 829 else 830 { 831 // Skip any options we consumed with getopt_long_only 832 argc -= optind; 833 //argv += optind; // Commented out to keep static analyzer happy 834 835 if (argc > 0) 836 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n"); 837 } 838 839 return error; 840 } 841 842 void 843 Driver::MainLoop () 844 { 845 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) 846 { 847 g_old_stdin_termios_is_valid = true; 848 atexit (reset_stdin_termios); 849 } 850 851 ::setbuf (stdin, NULL); 852 ::setbuf (stdout, NULL); 853 854 m_debugger.SetErrorFileHandle (stderr, false); 855 m_debugger.SetOutputFileHandle (stdout, false); 856 m_debugger.SetInputFileHandle (stdin, true); 857 858 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); 859 860 struct winsize window_size; 861 if (isatty (STDIN_FILENO) 862 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 863 { 864 if (window_size.ws_col > 0) 865 m_debugger.SetTerminalWidth (window_size.ws_col); 866 } 867 868 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter(); 869 870 // Before we handle any options from the command line, we parse the 871 // .lldbinit file in the user's home directory. 872 SBCommandReturnObject result; 873 sb_interpreter.SourceInitFileInHomeDirectory(result); 874 if (GetDebugMode()) 875 { 876 result.PutError (m_debugger.GetErrorFileHandle()); 877 result.PutOutput (m_debugger.GetOutputFileHandle()); 878 } 879 880 // Now we handle options we got from the command line 881 // First source in the commands specified to be run before the file arguments are processed. 882 ExecuteInitialCommands(true); 883 884 // Was there a core file specified? 885 std::string core_file_spec(""); 886 if (!m_option_data.m_core_file.empty()) 887 core_file_spec.append("--core ").append(m_option_data.m_core_file); 888 889 char command_string[PATH_MAX * 2]; 890 const size_t num_args = m_option_data.m_args.size(); 891 if (num_args > 0) 892 { 893 char arch_name[64]; 894 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) 895 ::snprintf (command_string, 896 sizeof (command_string), 897 "target create --arch=%s %s \"%s\"", 898 arch_name, 899 core_file_spec.c_str(), 900 m_option_data.m_args[0].c_str()); 901 else 902 ::snprintf (command_string, 903 sizeof(command_string), 904 "target create %s \"%s\"", 905 core_file_spec.c_str(), 906 m_option_data.m_args[0].c_str()); 907 908 m_debugger.HandleCommand (command_string); 909 910 if (num_args > 1) 911 { 912 m_debugger.HandleCommand ("settings clear target.run-args"); 913 char arg_cstr[1024]; 914 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) 915 { 916 ::snprintf (arg_cstr, 917 sizeof(arg_cstr), 918 "settings append target.run-args \"%s\"", 919 m_option_data.m_args[arg_idx].c_str()); 920 m_debugger.HandleCommand (arg_cstr); 921 } 922 } 923 } 924 else if (!core_file_spec.empty()) 925 { 926 ::snprintf (command_string, 927 sizeof(command_string), 928 "target create %s", 929 core_file_spec.c_str()); 930 m_debugger.HandleCommand (command_string);; 931 } 932 933 ExecuteInitialCommands(false); 934 935 // Now that all option parsing is done, we try and parse the .lldbinit 936 // file in the current working directory 937 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result); 938 if (GetDebugMode()) 939 { 940 result.PutError(m_debugger.GetErrorFileHandle()); 941 result.PutOutput(m_debugger.GetOutputFileHandle()); 942 } 943 944 bool handle_events = true; 945 bool spawn_thread = false; 946 m_debugger.RunCommandInterpreter(handle_events, spawn_thread); 947 948 reset_stdin_termios(); 949 fclose (stdin); 950 951 SBDebugger::Destroy (m_debugger); 952 } 953 954 955 void 956 Driver::ResizeWindow (unsigned short col) 957 { 958 GetDebugger().SetTerminalWidth (col); 959 } 960 961 void 962 sigwinch_handler (int signo) 963 { 964 struct winsize window_size; 965 if (isatty (STDIN_FILENO) 966 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) 967 { 968 if ((window_size.ws_col > 0) && g_driver != NULL) 969 { 970 g_driver->ResizeWindow (window_size.ws_col); 971 } 972 } 973 } 974 975 void 976 sigint_handler (int signo) 977 { 978 static bool g_interrupt_sent = false; 979 if (g_driver) 980 { 981 if (!g_interrupt_sent) 982 { 983 g_interrupt_sent = true; 984 g_driver->GetDebugger().DispatchInputInterrupt(); 985 g_interrupt_sent = false; 986 return; 987 } 988 } 989 990 exit (signo); 991 } 992 993 void 994 sigtstp_handler (int signo) 995 { 996 g_driver->GetDebugger().SaveInputTerminalState(); 997 signal (signo, SIG_DFL); 998 kill (getpid(), signo); 999 signal (signo, sigtstp_handler); 1000 } 1001 1002 void 1003 sigcont_handler (int signo) 1004 { 1005 g_driver->GetDebugger().RestoreInputTerminalState(); 1006 signal (signo, SIG_DFL); 1007 kill (getpid(), signo); 1008 signal (signo, sigcont_handler); 1009 } 1010 1011 int 1012 main (int argc, char const *argv[], const char *envp[]) 1013 { 1014 SBDebugger::Initialize(); 1015 1016 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>"); 1017 1018 signal (SIGPIPE, SIG_IGN); 1019 signal (SIGWINCH, sigwinch_handler); 1020 signal (SIGINT, sigint_handler); 1021 signal (SIGTSTP, sigtstp_handler); 1022 signal (SIGCONT, sigcont_handler); 1023 1024 // Create a scope for driver so that the driver object will destroy itself 1025 // before SBDebugger::Terminate() is called. 1026 { 1027 Driver driver; 1028 1029 bool exiting = false; 1030 SBError error (driver.ParseArgs (argc, argv, stdout, exiting)); 1031 if (error.Fail()) 1032 { 1033 const char *error_cstr = error.GetCString (); 1034 if (error_cstr) 1035 ::fprintf (stderr, "error: %s\n", error_cstr); 1036 } 1037 else if (!exiting) 1038 { 1039 driver.MainLoop (); 1040 } 1041 } 1042 1043 SBDebugger::Terminate(); 1044 return 0; 1045 } 1046