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 <algorithm>
13 #include <atomic>
14 #include <bitset>
15 #include <csignal>
16 #include <fcntl.h>
17 #include <limits.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 // Includes for pipe()
23 #if defined(_WIN32)
24 #include <fcntl.h>
25 #include <io.h>
26 #else
27 #include <unistd.h>
28 #endif
29 
30 #include <string>
31 
32 #include "lldb/API/SBBreakpoint.h"
33 #include "lldb/API/SBCommandInterpreter.h"
34 #include "lldb/API/SBCommandReturnObject.h"
35 #include "lldb/API/SBCommunication.h"
36 #include "lldb/API/SBDebugger.h"
37 #include "lldb/API/SBEvent.h"
38 #include "lldb/API/SBHostOS.h"
39 #include "lldb/API/SBLanguageRuntime.h"
40 #include "lldb/API/SBListener.h"
41 #include "lldb/API/SBProcess.h"
42 #include "lldb/API/SBStream.h"
43 #include "lldb/API/SBStringList.h"
44 #include "lldb/API/SBTarget.h"
45 #include "lldb/API/SBThread.h"
46 #include "llvm/ADT/StringRef.h"
47 #include "llvm/Support/ConvertUTF.h"
48 #include "llvm/Support/PrettyStackTrace.h"
49 #include "llvm/Support/Signals.h"
50 #include <thread>
51 #include <utility>
52 
53 #if !defined(__APPLE__)
54 #include "llvm/Support/DataTypes.h"
55 #endif
56 
57 using namespace lldb;
58 
59 static void reset_stdin_termios();
60 static bool g_old_stdin_termios_is_valid = false;
61 static struct termios g_old_stdin_termios;
62 
63 static Driver *g_driver = NULL;
64 
65 // In the Driver::MainLoop, we change the terminal settings.  This function is
66 // added as an atexit handler to make sure we clean them up.
67 static void reset_stdin_termios() {
68   if (g_old_stdin_termios_is_valid) {
69     g_old_stdin_termios_is_valid = false;
70     ::tcsetattr(STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
71   }
72 }
73 
74 typedef struct {
75   uint32_t usage_mask; // Used to mark options that can be used together.  If (1
76                        // << n & usage_mask) != 0
77                        // then this option belongs to option set n.
78   bool required;       // This option is required (in the current usage level)
79   const char *long_option; // Full name for this option.
80   int short_option;        // Single character for this option.
81   int option_has_arg; // no_argument, required_argument or optional_argument
82   uint32_t completion_type; // Cookie the option class can use to do define the
83                             // argument completion.
84   lldb::CommandArgumentType argument_type; // Type of argument this option takes
85   const char *usage_text; // Full text explaining what this options does and
86                           // what (if any) argument to
87                           // pass it.
88 } OptionDefinition;
89 
90 #define LLDB_3_TO_5 LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5
91 #define LLDB_4_TO_5 LLDB_OPT_SET_4 | LLDB_OPT_SET_5
92 
93 static constexpr OptionDefinition g_options[] = {
94     {LLDB_OPT_SET_1, true, "help", 'h', no_argument, 0, eArgTypeNone,
95      "Prints out the usage information for the LLDB debugger."},
96     {LLDB_OPT_SET_2, true, "version", 'v', no_argument, 0, eArgTypeNone,
97      "Prints out the current version number of the LLDB debugger."},
98     {LLDB_OPT_SET_3, true, "arch", 'a', required_argument, 0,
99      eArgTypeArchitecture,
100      "Tells the debugger to use the specified architecture when starting and "
101      "running the program.  <architecture> must "
102      "be one of the architectures for which the program was compiled."},
103     {LLDB_OPT_SET_3, true, "file", 'f', required_argument, 0, eArgTypeFilename,
104      "Tells the debugger to use the file <filename> as the program to be "
105      "debugged."},
106     {LLDB_OPT_SET_3, false, "core", 'c', required_argument, 0, eArgTypeFilename,
107      "Tells the debugger to use the fullpath to <path> as the core file."},
108     {LLDB_OPT_SET_5, true, "attach-pid", 'p', required_argument, 0, eArgTypePid,
109      "Tells the debugger to attach to a process with the given pid."},
110     {LLDB_OPT_SET_4, true, "attach-name", 'n', required_argument, 0,
111      eArgTypeProcessName,
112      "Tells the debugger to attach to a process with the given name."},
113     {LLDB_OPT_SET_4, true, "wait-for", 'w', no_argument, 0, eArgTypeNone,
114      "Tells the debugger to wait for a process with the given pid or name to "
115      "launch before attaching."},
116     {LLDB_3_TO_5, false, "source", 's', required_argument, 0, eArgTypeFilename,
117      "Tells the debugger to read in and execute the lldb commands in the given "
118      "file, after any file provided on the command line has been loaded."},
119     {LLDB_3_TO_5, false, "one-line", 'o', required_argument, 0, eArgTypeNone,
120      "Tells the debugger to execute this one-line lldb command after any file "
121      "provided on the command line has been loaded."},
122     {LLDB_3_TO_5, false, "source-before-file", 'S', required_argument, 0,
123      eArgTypeFilename,
124      "Tells the debugger to read in and execute the lldb "
125      "commands in the given file, before any file provided "
126      "on the command line has been loaded."},
127     {LLDB_3_TO_5, false, "one-line-before-file", 'O', required_argument, 0,
128      eArgTypeNone,
129      "Tells the debugger to execute this one-line lldb command "
130      "before any file provided on the command line has been "
131      "loaded."},
132     {LLDB_3_TO_5, false, "one-line-on-crash", 'k', required_argument, 0,
133      eArgTypeNone,
134      "When in batch mode, tells the debugger to execute this "
135      "one-line lldb command if the target crashes."},
136     {LLDB_3_TO_5, false, "source-on-crash", 'K', required_argument, 0,
137      eArgTypeFilename,
138      "When in batch mode, tells the debugger to source this "
139      "file of lldb commands if the target crashes."},
140     {LLDB_3_TO_5, false, "source-quietly", 'Q', no_argument, 0, eArgTypeNone,
141      "Tells the debugger to execute this one-line lldb command before any file "
142      "provided on the command line has been loaded."},
143     {LLDB_3_TO_5, false, "batch", 'b', no_argument, 0, eArgTypeNone,
144      "Tells the debugger to run the commands from -s, -S, -o & -O, and "
145      "then quit.  However if any run command stopped due to a signal or crash, "
146      "the debugger will return to the interactive prompt at the place of the "
147      "crash."},
148     {LLDB_3_TO_5, false, "editor", 'e', no_argument, 0, eArgTypeNone,
149      "Tells the debugger to open source files using the host's \"external "
150      "editor\" mechanism."},
151     {LLDB_3_TO_5, false, "no-lldbinit", 'x', no_argument, 0, eArgTypeNone,
152      "Do not automatically parse any '.lldbinit' files."},
153     {LLDB_3_TO_5, false, "no-use-colors", 'X', no_argument, 0, eArgTypeNone,
154      "Do not use colors."},
155     {LLDB_OPT_SET_6, true, "python-path", 'P', no_argument, 0, eArgTypeNone,
156      "Prints out the path to the lldb.py file for this version of lldb."},
157     {LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0,
158      eArgTypeScriptLang,
159      "Tells the debugger to use the specified scripting language for "
160      "user-defined scripts, rather than the default.  "
161      "Valid scripting languages that can be specified include Python, Perl, "
162      "Ruby and Tcl.  Currently only the Python "
163      "extensions have been implemented."},
164     {LLDB_3_TO_5, false, "debug", 'd', no_argument, 0, eArgTypeNone,
165      "Tells the debugger to print out extra information for debugging itself."},
166     {LLDB_3_TO_5, false, "reproducer", 'z', required_argument, 0,
167      eArgTypeFilename,
168      "Tells the debugger to use the fullpath to <path> as a reproducer."},
169     {LLDB_OPT_SET_7, true, "repl", 'r', optional_argument, 0, eArgTypeNone,
170      "Runs lldb in REPL mode with a stub process."},
171     {LLDB_OPT_SET_7, true, "repl-language", 'R', required_argument, 0,
172      eArgTypeNone, "Chooses the language for the REPL."}};
173 
174 static constexpr auto g_num_options = sizeof(g_options)/sizeof(OptionDefinition);
175 
176 static const uint32_t last_option_set_with_args = 2;
177 
178 Driver::Driver()
179     : SBBroadcaster("Driver"), m_debugger(SBDebugger::Create(false)),
180       m_option_data() {
181   // We want to be able to handle CTRL+D in the terminal to have it terminate
182   // certain input
183   m_debugger.SetCloseInputOnEOF(false);
184   g_driver = this;
185 }
186 
187 Driver::~Driver() { g_driver = NULL; }
188 
189 // This function takes INDENT, which tells how many spaces to output at the
190 // front
191 // of each line; TEXT, which is the text that is to be output. It outputs the
192 // text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
193 // front of each line.  It breaks lines on spaces, tabs or newlines, shortening
194 // the line if necessary to not break in the middle of a word. It assumes that
195 // each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
196 
197 void OutputFormattedUsageText(FILE *out, int indent, const char *text,
198                               int output_max_columns) {
199   int len = strlen(text);
200   std::string text_string(text);
201 
202   // Force indentation to be reasonable.
203   if (indent >= output_max_columns)
204     indent = 0;
205 
206   // Will it all fit on one line?
207 
208   if (len + indent < output_max_columns)
209     // Output as a single line
210     fprintf(out, "%*s%s\n", indent, "", text);
211   else {
212     // We need to break it up into multiple lines.
213     int text_width = output_max_columns - indent - 1;
214     int start = 0;
215     int end = start;
216     int final_end = len;
217     int sub_len;
218 
219     while (end < final_end) {
220       // Dont start the 'text' on a space, since we're already outputting the
221       // indentation.
222       while ((start < final_end) && (text[start] == ' '))
223         start++;
224 
225       end = start + text_width;
226       if (end > final_end)
227         end = final_end;
228       else {
229         // If we're not at the end of the text, make sure we break the line on
230         // white space.
231         while (end > start && text[end] != ' ' && text[end] != '\t' &&
232                text[end] != '\n')
233           end--;
234       }
235       sub_len = end - start;
236       std::string substring = text_string.substr(start, sub_len);
237       fprintf(out, "%*s%s\n", indent, "", substring.c_str());
238       start = end + 1;
239     }
240   }
241 }
242 
243 static void ShowUsage(FILE *out, Driver::OptionData data) {
244   uint32_t screen_width = 80;
245   uint32_t indent_level = 0;
246   const char *name = "lldb";
247 
248   fprintf(out, "\nUsage:\n\n");
249 
250   indent_level += 2;
251 
252   // First, show each usage level set of options, e.g. <cmd>
253   // [options-for-level-0]
254   //                                                   <cmd>
255   //                                                   [options-for-level-1]
256   //                                                   etc.
257 
258   uint32_t num_option_sets = 0;
259 
260   for (const auto &opt : g_options) {
261     uint32_t this_usage_mask = opt.usage_mask;
262     if (this_usage_mask == LLDB_OPT_SET_ALL) {
263       if (num_option_sets == 0)
264         num_option_sets = 1;
265     } else {
266       for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) {
267         if (this_usage_mask & 1 << j) {
268           if (num_option_sets <= j)
269             num_option_sets = j + 1;
270         }
271       }
272     }
273   }
274 
275   for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++) {
276     uint32_t opt_set_mask;
277 
278     opt_set_mask = 1 << opt_set;
279 
280     if (opt_set > 0)
281       fprintf(out, "\n");
282     fprintf(out, "%*s%s", indent_level, "", name);
283     bool is_help_line = false;
284 
285     for (const auto &opt : g_options) {
286       if (opt.usage_mask & opt_set_mask) {
287         CommandArgumentType arg_type = opt.argument_type;
288         const char *arg_name =
289             SBCommandInterpreter::GetArgumentTypeAsCString(arg_type);
290         // This is a bit of a hack, but there's no way to say certain options
291         // don't have arguments yet...
292         // so we do it by hand here.
293         if (opt.short_option == 'h')
294           is_help_line = true;
295 
296         if (opt.required) {
297           if (opt.option_has_arg == required_argument)
298             fprintf(out, " -%c <%s>", opt.short_option, arg_name);
299           else if (opt.option_has_arg == optional_argument)
300             fprintf(out, " -%c [<%s>]", opt.short_option, arg_name);
301           else
302             fprintf(out, " -%c", opt.short_option);
303         } else {
304           if (opt.option_has_arg == required_argument)
305             fprintf(out, " [-%c <%s>]", opt.short_option, arg_name);
306           else if (opt.option_has_arg == optional_argument)
307             fprintf(out, " [-%c [<%s>]]", opt.short_option,
308                     arg_name);
309           else
310             fprintf(out, " [-%c]", opt.short_option);
311         }
312       }
313     }
314     if (!is_help_line && (opt_set <= last_option_set_with_args))
315       fprintf(out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
316   }
317 
318   fprintf(out, "\n\n");
319 
320   // Now print out all the detailed information about the various options:  long
321   // form, short form and help text:
322   //   -- long_name <argument>
323   //   - short <argument>
324   //   help text
325 
326   // This variable is used to keep track of which options' info we've printed
327   // out, because some options can be in
328   // more than one usage level, but we only want to print the long form of its
329   // information once.
330 
331   Driver::OptionData::OptionSet options_seen;
332   Driver::OptionData::OptionSet::iterator pos;
333 
334   indent_level += 5;
335 
336   for (const auto &opt : g_options) {
337     // Only print this option if we haven't already seen it.
338     pos = options_seen.find(opt.short_option);
339     if (pos == options_seen.end()) {
340       CommandArgumentType arg_type = opt.argument_type;
341       const char *arg_name =
342           SBCommandInterpreter::GetArgumentTypeAsCString(arg_type);
343 
344       options_seen.insert(opt.short_option);
345       fprintf(out, "%*s-%c ", indent_level, "", opt.short_option);
346       if (arg_type != eArgTypeNone)
347         fprintf(out, "<%s>", arg_name);
348       fprintf(out, "\n");
349       fprintf(out, "%*s--%s ", indent_level, "", opt.long_option);
350       if (arg_type != eArgTypeNone)
351         fprintf(out, "<%s>", arg_name);
352       fprintf(out, "\n");
353       indent_level += 5;
354       OutputFormattedUsageText(out, indent_level, opt.usage_text,
355                                screen_width);
356       indent_level -= 5;
357       fprintf(out, "\n");
358     }
359   }
360 
361   indent_level -= 5;
362 
363   fprintf(out, "\n%*sNotes:\n", indent_level, "");
364   indent_level += 5;
365 
366   fprintf(out,
367           "\n%*sMultiple \"-s\" and \"-o\" options can be provided.  They will "
368           "be processed"
369           "\n%*sfrom left to right in order, with the source files and commands"
370           "\n%*sinterleaved.  The same is true of the \"-S\" and \"-O\" "
371           "options.  The before"
372           "\n%*sfile and after file sets can intermixed freely, the command "
373           "parser will"
374           "\n%*ssort them out.  The order of the file specifiers (\"-c\", "
375           "\"-f\", etc.) is"
376           "\n%*snot significant in this regard.\n\n",
377           indent_level, "", indent_level, "", indent_level, "", indent_level,
378           "", indent_level, "", indent_level, "");
379 
380   fprintf(
381       out,
382       "\n%*sIf you don't provide -f then the first argument will be the file "
383       "to be"
384       "\n%*sdebugged which means that '%s -- <filename> [<ARG1> [<ARG2>]]' also"
385       "\n%*sworks.  But remember to end the options with \"--\" if any of your"
386       "\n%*sarguments have a \"-\" in them.\n\n",
387       indent_level, "", indent_level, "", name, indent_level, "", indent_level,
388       "");
389 }
390 
391  static void BuildGetOptTable(std::vector<option> &getopt_table) {
392   getopt_table.resize(g_num_options + 1);
393 
394   std::bitset<256> option_seen;
395   uint32_t j = 0;
396   for (const auto &opt : g_options) {
397     char short_opt = opt.short_option;
398 
399     if (option_seen.test(short_opt) == false) {
400       getopt_table[j].name = opt.long_option;
401       getopt_table[j].has_arg = opt.option_has_arg;
402       getopt_table[j].flag = NULL;
403       getopt_table[j].val = opt.short_option;
404       option_seen.set(short_opt);
405       ++j;
406     }
407   }
408 
409   getopt_table[j].name = NULL;
410   getopt_table[j].has_arg = 0;
411   getopt_table[j].flag = NULL;
412   getopt_table[j].val = 0;
413 }
414 
415 Driver::OptionData::OptionData()
416     : m_args(), m_script_lang(lldb::eScriptLanguageDefault), m_core_file(),
417       m_crash_log(), m_initial_commands(), m_after_file_commands(),
418       m_after_crash_commands(), m_debug_mode(false), m_source_quietly(false),
419       m_print_version(false), m_print_python_path(false), m_print_help(false),
420       m_wait_for(false), m_repl(false), m_repl_lang(eLanguageTypeUnknown),
421       m_repl_options(), m_process_name(),
422       m_process_pid(LLDB_INVALID_PROCESS_ID), m_use_external_editor(false),
423       m_batch(false), m_seen_options() {}
424 
425 Driver::OptionData::~OptionData() {}
426 
427 void Driver::OptionData::Clear() {
428   m_args.clear();
429   m_script_lang = lldb::eScriptLanguageDefault;
430   m_initial_commands.clear();
431   m_after_file_commands.clear();
432 
433   // If there is a local .lldbinit, add that to the
434   // list of things to be sourced, if the settings
435   // permit it.
436   SBFileSpec local_lldbinit(".lldbinit", true);
437 
438   SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory();
439   homedir_dot_lldb.AppendPathComponent(".lldbinit");
440 
441   // Only read .lldbinit in the current working directory
442   // if it's not the same as the .lldbinit in the home
443   // directory (which is already being read in).
444   if (local_lldbinit.Exists() &&
445       strcmp(local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) !=
446           0) {
447     char path[2048];
448     local_lldbinit.GetPath(path, 2047);
449     InitialCmdEntry entry(path, true, true, true);
450     m_after_file_commands.push_back(entry);
451   }
452 
453   m_debug_mode = false;
454   m_source_quietly = false;
455   m_print_help = false;
456   m_print_version = false;
457   m_print_python_path = false;
458   m_use_external_editor = false;
459   m_wait_for = false;
460   m_process_name.erase();
461   m_batch = false;
462   m_after_crash_commands.clear();
463 
464   m_process_pid = LLDB_INVALID_PROCESS_ID;
465 }
466 
467 void Driver::OptionData::AddInitialCommand(const char *command,
468                                            CommandPlacement placement,
469                                            bool is_file, SBError &error) {
470   std::vector<InitialCmdEntry> *command_set;
471   switch (placement) {
472   case eCommandPlacementBeforeFile:
473     command_set = &(m_initial_commands);
474     break;
475   case eCommandPlacementAfterFile:
476     command_set = &(m_after_file_commands);
477     break;
478   case eCommandPlacementAfterCrash:
479     command_set = &(m_after_crash_commands);
480     break;
481   }
482 
483   if (is_file) {
484     SBFileSpec file(command);
485     if (file.Exists())
486       command_set->push_back(InitialCmdEntry(command, is_file, false));
487     else if (file.ResolveExecutableLocation()) {
488       char final_path[PATH_MAX];
489       file.GetPath(final_path, sizeof(final_path));
490       command_set->push_back(InitialCmdEntry(final_path, is_file, false));
491     } else
492       error.SetErrorStringWithFormat(
493           "file specified in --source (-s) option doesn't exist: '%s'", optarg);
494   } else
495     command_set->push_back(InitialCmdEntry(command, is_file, false));
496 }
497 
498 void Driver::ResetOptionValues() { m_option_data.Clear(); }
499 
500 const char *Driver::GetFilename() const {
501   if (m_option_data.m_args.empty())
502     return NULL;
503   return m_option_data.m_args.front().c_str();
504 }
505 
506 const char *Driver::GetCrashLogFilename() const {
507   if (m_option_data.m_crash_log.empty())
508     return NULL;
509   return m_option_data.m_crash_log.c_str();
510 }
511 
512 lldb::ScriptLanguage Driver::GetScriptLanguage() const {
513   return m_option_data.m_script_lang;
514 }
515 
516 void Driver::WriteCommandsForSourcing(CommandPlacement placement,
517                                       SBStream &strm) {
518   std::vector<OptionData::InitialCmdEntry> *command_set;
519   switch (placement) {
520   case eCommandPlacementBeforeFile:
521     command_set = &m_option_data.m_initial_commands;
522     break;
523   case eCommandPlacementAfterFile:
524     command_set = &m_option_data.m_after_file_commands;
525     break;
526   case eCommandPlacementAfterCrash:
527     command_set = &m_option_data.m_after_crash_commands;
528     break;
529   }
530 
531   for (const auto &command_entry : *command_set) {
532     const char *command = command_entry.contents.c_str();
533     if (command_entry.is_file) {
534       // If this command_entry is a file to be sourced, and it's the ./.lldbinit
535       // file (the .lldbinit
536       // file in the current working directory), only read it if
537       // target.load-cwd-lldbinit is 'true'.
538       if (command_entry.is_cwd_lldbinit_file_read) {
539         SBStringList strlist = m_debugger.GetInternalVariableValue(
540             "target.load-cwd-lldbinit", m_debugger.GetInstanceName());
541         if (strlist.GetSize() == 1 &&
542             strcmp(strlist.GetStringAtIndex(0), "warn") == 0) {
543           FILE *output = m_debugger.GetOutputFileHandle();
544           ::fprintf(
545               output,
546               "There is a .lldbinit file in the current directory which is not "
547               "being read.\n"
548               "To silence this warning without sourcing in the local "
549               ".lldbinit,\n"
550               "add the following to the lldbinit file in your home directory:\n"
551               "    settings set target.load-cwd-lldbinit false\n"
552               "To allow lldb to source .lldbinit files in the current working "
553               "directory,\n"
554               "set the value of this variable to true.  Only do so if you "
555               "understand and\n"
556               "accept the security risk.\n");
557           return;
558         }
559         if (strlist.GetSize() == 1 &&
560             strcmp(strlist.GetStringAtIndex(0), "false") == 0) {
561           return;
562         }
563       }
564       bool source_quietly =
565           m_option_data.m_source_quietly || command_entry.source_quietly;
566       strm.Printf("command source -s %i '%s'\n", source_quietly, command);
567     } else
568       strm.Printf("%s\n", command);
569   }
570 }
571 
572 bool Driver::GetDebugMode() const { return m_option_data.m_debug_mode; }
573 
574 // Check the arguments that were passed to this program to make sure they are
575 // valid and to get their
576 // argument values (if any).  Return a boolean value indicating whether or not
577 // to start up the full
578 // debugger (i.e. the Command Interpreter) or not.  Return FALSE if the
579 // arguments were invalid OR
580 // if the user only wanted help or version information.
581 
582 SBError Driver::ParseArgs(int argc, const char *argv[], FILE *out_fh,
583                           bool &exiting) {
584   static_assert(g_num_options > 0, "cannot handle arguments");
585 
586   ResetOptionValues();
587 
588   SBError error;
589   std::vector<option> long_options_vector;
590   BuildGetOptTable(long_options_vector);
591   if (long_options_vector.empty()) {
592     error.SetErrorStringWithFormat("invalid long options");
593     return error;
594   }
595 
596   // Build the option_string argument for call to getopt_long_only.
597   std::string option_string;
598   auto sentinel_it = std::prev(std::end(long_options_vector));
599   for (auto long_opt_it = std::begin(long_options_vector);
600             long_opt_it != sentinel_it; ++long_opt_it) {
601     if (long_opt_it->flag == nullptr) {
602       option_string.push_back(static_cast<char>(long_opt_it->val));
603       switch (long_opt_it->has_arg) {
604       default:
605       case no_argument:
606         break;
607       case required_argument:
608         option_string.push_back(':');
609         break;
610       case optional_argument:
611         option_string.append("::");
612         break;
613       }
614     }
615   }
616 
617   // This is kind of a pain, but since we make the debugger in the Driver's
618   // constructor, we can't
619   // know at that point whether we should read in init files yet.  So we don't
620   // read them in in the
621   // Driver constructor, then set the flags back to "read them in" here, and
622   // then if we see the
623   // "-n" flag, we'll turn it off again.  Finally we have to read them in by
624   // hand later in the
625   // main loop.
626 
627   m_debugger.SkipLLDBInitFiles(false);
628   m_debugger.SkipAppInitFiles(false);
629 
630 // Prepare for & make calls to getopt_long_only.
631 #if __GLIBC__
632   optind = 0;
633 #else
634   optreset = 1;
635   optind = 1;
636 #endif
637   int val;
638   while (1) {
639     int long_options_index = -1;
640     val = ::getopt_long_only(argc, const_cast<char **>(argv),
641                              option_string.c_str(), long_options_vector.data(),
642                              &long_options_index);
643 
644     if (val == -1)
645       break;
646     else if (val == '?') {
647       m_option_data.m_print_help = true;
648       error.SetErrorStringWithFormat("unknown or ambiguous option");
649       break;
650     } else if (val == 0)
651       continue;
652     else {
653       m_option_data.m_seen_options.insert((char)val);
654       if (long_options_index == -1) {
655         auto long_opt_it = std::find_if(std::begin(long_options_vector), sentinel_it,
656             [val](const option &long_option) { return long_option.val == val; });
657         if (std::end(long_options_vector) != long_opt_it)
658           long_options_index =
659               std::distance(std::begin(long_options_vector), long_opt_it);
660       }
661 
662       if (long_options_index >= 0) {
663         const int short_option = g_options[long_options_index].short_option;
664 
665         switch (short_option) {
666         case 'h':
667           m_option_data.m_print_help = true;
668           break;
669 
670         case 'v':
671           m_option_data.m_print_version = true;
672           break;
673 
674         case 'P':
675           m_option_data.m_print_python_path = true;
676           break;
677 
678         case 'b':
679           m_option_data.m_batch = true;
680           break;
681 
682         case 'c': {
683           SBFileSpec file(optarg);
684           if (file.Exists()) {
685             m_option_data.m_core_file = optarg;
686           } else
687             error.SetErrorStringWithFormat(
688                 "file specified in --core (-c) option doesn't exist: '%s'",
689                 optarg);
690         } break;
691 
692         case 'e':
693           m_option_data.m_use_external_editor = true;
694           break;
695 
696         case 'x':
697           m_debugger.SkipLLDBInitFiles(true);
698           m_debugger.SkipAppInitFiles(true);
699           break;
700 
701         case 'X':
702           m_debugger.SetUseColor(false);
703           break;
704 
705         case 'f': {
706           SBFileSpec file(optarg);
707           if (file.Exists()) {
708             m_option_data.m_args.push_back(optarg);
709           } else if (file.ResolveExecutableLocation()) {
710             char path[PATH_MAX];
711             file.GetPath(path, sizeof(path));
712             m_option_data.m_args.push_back(path);
713           } else
714             error.SetErrorStringWithFormat(
715                 "file specified in --file (-f) option doesn't exist: '%s'",
716                 optarg);
717         } break;
718 
719         case 'a':
720           if (!m_debugger.SetDefaultArchitecture(optarg))
721             error.SetErrorStringWithFormat(
722                 "invalid architecture in the -a or --arch option: '%s'",
723                 optarg);
724           break;
725 
726         case 'l':
727           m_option_data.m_script_lang = m_debugger.GetScriptingLanguage(optarg);
728           break;
729 
730         case 'd':
731           m_option_data.m_debug_mode = true;
732           break;
733 
734         case 'z': {
735           SBFileSpec file(optarg);
736           if (file.Exists()) {
737             m_debugger.SetReproducerPath(optarg);
738           } else
739             error.SetErrorStringWithFormat("file specified in --reproducer "
740                                            "(-z) option doesn't exist: '%s'",
741                                            optarg);
742         } break;
743 
744         case 'Q':
745           m_option_data.m_source_quietly = true;
746           break;
747 
748         case 'K':
749           m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash,
750                                           true, error);
751           break;
752         case 'k':
753           m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash,
754                                           false, error);
755           break;
756 
757         case 'n':
758           m_option_data.m_process_name = optarg;
759           break;
760 
761         case 'w':
762           m_option_data.m_wait_for = true;
763           break;
764 
765         case 'p': {
766           char *remainder;
767           m_option_data.m_process_pid = strtol(optarg, &remainder, 0);
768           if (remainder == optarg || *remainder != '\0')
769             error.SetErrorStringWithFormat(
770                 "Could not convert process PID: \"%s\" into a pid.", optarg);
771         } break;
772 
773         case 'r':
774           m_option_data.m_repl = true;
775           if (optarg && optarg[0])
776             m_option_data.m_repl_options = optarg;
777           else
778             m_option_data.m_repl_options.clear();
779           break;
780 
781         case 'R':
782           m_option_data.m_repl_lang =
783               SBLanguageRuntime::GetLanguageTypeFromString(optarg);
784           if (m_option_data.m_repl_lang == eLanguageTypeUnknown) {
785             error.SetErrorStringWithFormat("Unrecognized language name: \"%s\"",
786                                            optarg);
787           }
788           break;
789 
790         case 's':
791           m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile,
792                                           true, error);
793           break;
794         case 'o':
795           m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile,
796                                           false, error);
797           break;
798         case 'S':
799           m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile,
800                                           true, error);
801           break;
802         case 'O':
803           m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile,
804                                           false, error);
805           break;
806         default:
807           m_option_data.m_print_help = true;
808           error.SetErrorStringWithFormat("unrecognized option %c",
809                                          short_option);
810           break;
811         }
812       } else {
813         error.SetErrorStringWithFormat("invalid option with value %i", val);
814       }
815       if (error.Fail()) {
816         return error;
817       }
818     }
819   }
820 
821   if (error.Fail() || m_option_data.m_print_help) {
822     ShowUsage(out_fh, m_option_data);
823     exiting = true;
824   } else if (m_option_data.m_print_version) {
825     ::fprintf(out_fh, "%s\n", m_debugger.GetVersionString());
826     exiting = true;
827   } else if (m_option_data.m_print_python_path) {
828     SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
829     if (python_file_spec.IsValid()) {
830       char python_path[PATH_MAX];
831       size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
832       if (num_chars < PATH_MAX) {
833         ::fprintf(out_fh, "%s\n", python_path);
834       } else
835         ::fprintf(out_fh, "<PATH TOO LONG>\n");
836     } else
837       ::fprintf(out_fh, "<COULD NOT FIND PATH>\n");
838     exiting = true;
839   } else if (m_option_data.m_process_name.empty() &&
840              m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID) {
841     // Any arguments that are left over after option parsing are for
842     // the program. If a file was specified with -f then the filename
843     // is already in the m_option_data.m_args array, and any remaining args
844     // are arguments for the inferior program. If no file was specified with
845     // -f, then what is left is the program name followed by any arguments.
846 
847     // Skip any options we consumed with getopt_long_only
848     argc -= optind;
849     argv += optind;
850 
851     if (argc > 0) {
852       for (int arg_idx = 0; arg_idx < argc; ++arg_idx) {
853         const char *arg = argv[arg_idx];
854         if (arg)
855           m_option_data.m_args.push_back(arg);
856       }
857     }
858 
859   } else {
860     // Skip any options we consumed with getopt_long_only
861     argc -= optind;
862 
863     if (argc > 0)
864       ::fprintf(out_fh,
865                 "Warning: program arguments are ignored when attaching.\n");
866   }
867 
868   return error;
869 }
870 
871 static ::FILE *PrepareCommandsForSourcing(const char *commands_data,
872                                           size_t commands_size, int fds[2]) {
873   enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
874 
875   ::FILE *commands_file = NULL;
876   fds[0] = -1;
877   fds[1] = -1;
878   int err = 0;
879 #ifdef _WIN32
880   err = _pipe(fds, commands_size, O_BINARY);
881 #else
882   err = pipe(fds);
883 #endif
884   if (err == 0) {
885     ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
886     if (nrwr < 0) {
887       fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
888                       "when trying to open LLDB commands pipe\n",
889               fds[WRITE], static_cast<const void *>(commands_data),
890               static_cast<uint64_t>(commands_size), errno);
891     } else if (static_cast<size_t>(nrwr) == commands_size) {
892 // Close the write end of the pipe so when we give the read end to
893 // the debugger/command interpreter it will exit when it consumes all
894 // of the data
895 #ifdef _WIN32
896       _close(fds[WRITE]);
897       fds[WRITE] = -1;
898 #else
899       close(fds[WRITE]);
900       fds[WRITE] = -1;
901 #endif
902       // Now open the read file descriptor in a FILE * that we can give to
903       // the debugger as an input handle
904       commands_file = fdopen(fds[READ], "r");
905       if (commands_file) {
906         fds[READ] =
907             -1; // The FILE * 'commands_file' now owns the read descriptor
908                 // Hand ownership if the FILE * over to the debugger for
909                 // "commands_file".
910       } else {
911         fprintf(stderr, "error: fdopen(%i, \"r\") failed (errno = %i) when "
912                         "trying to open LLDB commands pipe\n",
913                 fds[READ], errno);
914       }
915     }
916   } else {
917     fprintf(stderr,
918             "error: can't create pipe file descriptors for LLDB commands\n");
919   }
920 
921   return commands_file;
922 }
923 
924 void CleanupAfterCommandSourcing(int fds[2]) {
925   enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
926 
927   // Close any pipes that we still have ownership of
928   if (fds[WRITE] != -1) {
929 #ifdef _WIN32
930     _close(fds[WRITE]);
931     fds[WRITE] = -1;
932 #else
933     close(fds[WRITE]);
934     fds[WRITE] = -1;
935 #endif
936   }
937 
938   if (fds[READ] != -1) {
939 #ifdef _WIN32
940     _close(fds[READ]);
941     fds[READ] = -1;
942 #else
943     close(fds[READ]);
944     fds[READ] = -1;
945 #endif
946   }
947 }
948 
949 std::string EscapeString(std::string arg) {
950   std::string::size_type pos = 0;
951   while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) {
952     arg.insert(pos, 1, '\\');
953     pos += 2;
954   }
955   return '"' + arg + '"';
956 }
957 
958 int Driver::MainLoop() {
959   if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0) {
960     g_old_stdin_termios_is_valid = true;
961     atexit(reset_stdin_termios);
962   }
963 
964 #ifndef _MSC_VER
965   // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets
966   // which causes it to miss newlines depending on whether there have been an
967   // odd or even number of characters.  Bug has been reported to MS via Connect.
968   ::setbuf(stdin, NULL);
969 #endif
970   ::setbuf(stdout, NULL);
971 
972   m_debugger.SetErrorFileHandle(stderr, false);
973   m_debugger.SetOutputFileHandle(stdout, false);
974   m_debugger.SetInputFileHandle(stdin,
975                                 false); // Don't take ownership of STDIN yet...
976 
977   m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
978 
979   struct winsize window_size;
980   if (isatty(STDIN_FILENO) &&
981       ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
982     if (window_size.ws_col > 0)
983       m_debugger.SetTerminalWidth(window_size.ws_col);
984   }
985 
986   SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
987 
988   // Before we handle any options from the command line, we parse the
989   // .lldbinit file in the user's home directory.
990   SBCommandReturnObject result;
991   sb_interpreter.SourceInitFileInHomeDirectory(result);
992   if (GetDebugMode()) {
993     result.PutError(m_debugger.GetErrorFileHandle());
994     result.PutOutput(m_debugger.GetOutputFileHandle());
995   }
996 
997   // We allow the user to specify an exit code when calling quit which we will
998   // return when exiting.
999   m_debugger.GetCommandInterpreter().AllowExitCodeOnQuit(true);
1000 
1001   // Now we handle options we got from the command line
1002   SBStream commands_stream;
1003 
1004   // First source in the commands specified to be run before the file arguments
1005   // are processed.
1006   WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream);
1007 
1008   const size_t num_args = m_option_data.m_args.size();
1009   if (num_args > 0) {
1010     char arch_name[64];
1011     if (m_debugger.GetDefaultArchitecture(arch_name, sizeof(arch_name)))
1012       commands_stream.Printf("target create --arch=%s %s", arch_name,
1013                              EscapeString(m_option_data.m_args[0]).c_str());
1014     else
1015       commands_stream.Printf("target create %s",
1016                              EscapeString(m_option_data.m_args[0]).c_str());
1017 
1018     if (!m_option_data.m_core_file.empty()) {
1019       commands_stream.Printf(" --core %s",
1020                              EscapeString(m_option_data.m_core_file).c_str());
1021     }
1022     commands_stream.Printf("\n");
1023 
1024     if (num_args > 1) {
1025       commands_stream.Printf("settings set -- target.run-args ");
1026       for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1027         commands_stream.Printf(
1028             " %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
1029       commands_stream.Printf("\n");
1030     }
1031   } else if (!m_option_data.m_core_file.empty()) {
1032     commands_stream.Printf("target create --core %s\n",
1033                            EscapeString(m_option_data.m_core_file).c_str());
1034   } else if (!m_option_data.m_process_name.empty()) {
1035     commands_stream.Printf("process attach --name %s",
1036                            EscapeString(m_option_data.m_process_name).c_str());
1037 
1038     if (m_option_data.m_wait_for)
1039       commands_stream.Printf(" --waitfor");
1040 
1041     commands_stream.Printf("\n");
1042 
1043   } else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid) {
1044     commands_stream.Printf("process attach --pid %" PRIu64 "\n",
1045                            m_option_data.m_process_pid);
1046   }
1047 
1048   WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
1049 
1050   if (GetDebugMode()) {
1051     result.PutError(m_debugger.GetErrorFileHandle());
1052     result.PutOutput(m_debugger.GetOutputFileHandle());
1053   }
1054 
1055   bool handle_events = true;
1056   bool spawn_thread = false;
1057 
1058   if (m_option_data.m_repl) {
1059     const char *repl_options = NULL;
1060     if (!m_option_data.m_repl_options.empty())
1061       repl_options = m_option_data.m_repl_options.c_str();
1062     SBError error(m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
1063     if (error.Fail()) {
1064       const char *error_cstr = error.GetCString();
1065       if (error_cstr && error_cstr[0])
1066         fprintf(stderr, "error: %s\n", error_cstr);
1067       else
1068         fprintf(stderr, "error: %u\n", error.GetError());
1069     }
1070   } else {
1071     // Check if we have any data in the commands stream, and if so, save it to a
1072     // temp file
1073     // so we can then run the command interpreter using the file contents.
1074     const char *commands_data = commands_stream.GetData();
1075     const size_t commands_size = commands_stream.GetSize();
1076 
1077     // The command file might have requested that we quit, this variable will
1078     // track that.
1079     bool quit_requested = false;
1080     bool stopped_for_crash = false;
1081     if (commands_data && commands_size) {
1082       int initial_commands_fds[2];
1083       bool success = true;
1084       FILE *commands_file = PrepareCommandsForSourcing(
1085           commands_data, commands_size, initial_commands_fds);
1086       if (commands_file) {
1087         m_debugger.SetInputFileHandle(commands_file, true);
1088 
1089         // Set the debugger into Sync mode when running the command file.
1090         // Otherwise command files
1091         // that run the target won't run in a sensible way.
1092         bool old_async = m_debugger.GetAsync();
1093         m_debugger.SetAsync(false);
1094         int num_errors;
1095 
1096         SBCommandInterpreterRunOptions options;
1097         options.SetStopOnError(true);
1098         if (m_option_data.m_batch)
1099           options.SetStopOnCrash(true);
1100 
1101         m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options,
1102                                          num_errors, quit_requested,
1103                                          stopped_for_crash);
1104 
1105         if (m_option_data.m_batch && stopped_for_crash &&
1106             !m_option_data.m_after_crash_commands.empty()) {
1107           int crash_command_fds[2];
1108           SBStream crash_commands_stream;
1109           WriteCommandsForSourcing(eCommandPlacementAfterCrash,
1110                                    crash_commands_stream);
1111           const char *crash_commands_data = crash_commands_stream.GetData();
1112           const size_t crash_commands_size = crash_commands_stream.GetSize();
1113           commands_file = PrepareCommandsForSourcing(
1114               crash_commands_data, crash_commands_size, crash_command_fds);
1115           if (commands_file) {
1116             bool local_quit_requested;
1117             bool local_stopped_for_crash;
1118             m_debugger.SetInputFileHandle(commands_file, true);
1119 
1120             m_debugger.RunCommandInterpreter(
1121                 handle_events, spawn_thread, options, num_errors,
1122                 local_quit_requested, local_stopped_for_crash);
1123             if (local_quit_requested)
1124               quit_requested = true;
1125           }
1126         }
1127         m_debugger.SetAsync(old_async);
1128       } else
1129         success = false;
1130 
1131       // Close any pipes that we still have ownership of
1132       CleanupAfterCommandSourcing(initial_commands_fds);
1133 
1134       // Something went wrong with command pipe
1135       if (!success) {
1136         exit(1);
1137       }
1138     }
1139 
1140     // Now set the input file handle to STDIN and run the command
1141     // interpreter again in interactive mode and let the debugger
1142     // take ownership of stdin
1143 
1144     bool go_interactive = true;
1145     if (quit_requested)
1146       go_interactive = false;
1147     else if (m_option_data.m_batch && !stopped_for_crash)
1148       go_interactive = false;
1149 
1150     if (go_interactive) {
1151       m_debugger.SetInputFileHandle(stdin, true);
1152       m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
1153     }
1154   }
1155 
1156   reset_stdin_termios();
1157   fclose(stdin);
1158 
1159   int exit_code = sb_interpreter.GetQuitStatus();
1160   SBDebugger::Destroy(m_debugger);
1161   return exit_code;
1162 }
1163 
1164 void Driver::ResizeWindow(unsigned short col) {
1165   GetDebugger().SetTerminalWidth(col);
1166 }
1167 
1168 void sigwinch_handler(int signo) {
1169   struct winsize window_size;
1170   if (isatty(STDIN_FILENO) &&
1171       ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0) {
1172     if ((window_size.ws_col > 0) && g_driver != NULL) {
1173       g_driver->ResizeWindow(window_size.ws_col);
1174     }
1175   }
1176 }
1177 
1178 void sigint_handler(int signo) {
1179   static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT;
1180   if (g_driver) {
1181     if (!g_interrupt_sent.test_and_set()) {
1182       g_driver->GetDebugger().DispatchInputInterrupt();
1183       g_interrupt_sent.clear();
1184       return;
1185     }
1186   }
1187 
1188   _exit(signo);
1189 }
1190 
1191 void sigtstp_handler(int signo) {
1192   if (g_driver)
1193     g_driver->GetDebugger().SaveInputTerminalState();
1194 
1195   signal(signo, SIG_DFL);
1196   kill(getpid(), signo);
1197   signal(signo, sigtstp_handler);
1198 }
1199 
1200 void sigcont_handler(int signo) {
1201   if (g_driver)
1202     g_driver->GetDebugger().RestoreInputTerminalState();
1203 
1204   signal(signo, SIG_DFL);
1205   kill(getpid(), signo);
1206   signal(signo, sigcont_handler);
1207 }
1208 
1209 int
1210 #ifdef _MSC_VER
1211 wmain(int argc, wchar_t const *wargv[])
1212 #else
1213 main(int argc, char const *argv[])
1214 #endif
1215 {
1216 #ifdef _MSC_VER
1217   // Convert wide arguments to UTF-8
1218   std::vector<std::string> argvStrings(argc);
1219   std::vector<const char *> argvPointers(argc);
1220   for (int i = 0; i != argc; ++i) {
1221     llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
1222     argvPointers[i] = argvStrings[i].c_str();
1223   }
1224   const char **argv = argvPointers.data();
1225 #endif
1226 
1227   llvm::StringRef ToolName = argv[0];
1228   llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
1229   llvm::PrettyStackTraceProgram X(argc, argv);
1230 
1231   SBDebugger::Initialize();
1232 
1233   SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
1234 
1235   signal(SIGINT, sigint_handler);
1236 #if !defined(_MSC_VER)
1237   signal(SIGPIPE, SIG_IGN);
1238   signal(SIGWINCH, sigwinch_handler);
1239   signal(SIGTSTP, sigtstp_handler);
1240   signal(SIGCONT, sigcont_handler);
1241 #endif
1242 
1243   int exit_code = 0;
1244   // Create a scope for driver so that the driver object will destroy itself
1245   // before SBDebugger::Terminate() is called.
1246   {
1247     Driver driver;
1248 
1249     bool exiting = false;
1250     SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
1251     if (error.Fail()) {
1252       exit_code = 1;
1253       const char *error_cstr = error.GetCString();
1254       if (error_cstr)
1255         ::fprintf(stderr, "error: %s\n", error_cstr);
1256     } else if (!exiting) {
1257       exit_code = driver.MainLoop();
1258     }
1259   }
1260 
1261   SBDebugger::Terminate();
1262   return exit_code;
1263 }
1264