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