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