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