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