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