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 <getopt.h>
13 #include <libgen.h>
14 #include <sys/ioctl.h>
15 #include <termios.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <limits.h>
20 #include <fcntl.h>
21 
22 #include <string>
23 
24 #include "IOChannel.h"
25 #include "lldb/API/SBBreakpoint.h"
26 #include "lldb/API/SBCommandInterpreter.h"
27 #include "lldb/API/SBCommandReturnObject.h"
28 #include "lldb/API/SBCommunication.h"
29 #include "lldb/API/SBDebugger.h"
30 #include "lldb/API/SBEvent.h"
31 #include "lldb/API/SBHostOS.h"
32 #include "lldb/API/SBListener.h"
33 #include "lldb/API/SBStream.h"
34 #include "lldb/API/SBTarget.h"
35 #include "lldb/API/SBThread.h"
36 #include "lldb/API/SBProcess.h"
37 
38 using namespace lldb;
39 
40 static void reset_stdin_termios ();
41 static bool g_old_stdin_termios_is_valid = false;
42 static struct termios g_old_stdin_termios;
43 
44 static char *g_debugger_name =  (char *) "";
45 static Driver *g_driver = NULL;
46 
47 // In the Driver::MainLoop, we change the terminal settings.  This function is
48 // added as an atexit handler to make sure we clean them up.
49 static void
50 reset_stdin_termios ()
51 {
52     if (g_old_stdin_termios_is_valid)
53     {
54         g_old_stdin_termios_is_valid = false;
55         ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
56     }
57 }
58 
59 typedef struct
60 {
61     uint32_t usage_mask;                     // Used to mark options that can be used together.  If (1 << n & usage_mask) != 0
62                                              // then this option belongs to option set n.
63     bool required;                           // This option is required (in the current usage level)
64     const char * long_option;                // Full name for this option.
65     char short_option;                       // Single character for this option.
66     int option_has_arg;                      // no_argument, required_argument or optional_argument
67     uint32_t completion_type;                // Cookie the option class can use to do define the argument completion.
68     lldb::CommandArgumentType argument_type; // Type of argument this option takes
69     const char *  usage_text;                // Full text explaining what this options does and what (if any) argument to
70                                              // pass it.
71 } OptionDefinition;
72 
73 #define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
74 #define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
75 
76 static OptionDefinition g_options[] =
77 {
78     { LLDB_OPT_SET_1,    true , "help"           , 'h', no_argument      , 0,  eArgTypeNone,
79         "Prints out the usage information for the LLDB debugger." },
80     { LLDB_OPT_SET_2,    true , "version"        , 'v', no_argument      , 0,  eArgTypeNone,
81         "Prints out the current version number of the LLDB debugger." },
82     { LLDB_OPT_SET_3,    true , "arch"           , 'a', required_argument, 0,  eArgTypeArchitecture,
83         "Tells the debugger to use the specified architecture when starting and running the program.  <architecture> must "
84         "be one of the architectures for which the program was compiled." },
85     { LLDB_OPT_SET_3,    true , "file"           , 'f', required_argument, 0,  eArgTypeFilename,
86         "Tells the debugger to use the file <filename> as the program to be debugged." },
87     { LLDB_OPT_SET_3,    false, "core"           , 'c', required_argument, 0,  eArgTypePath,
88         "Tells the debugger to use the fullpath to <path> as the core file." },
89     { LLDB_OPT_SET_4,    true , "attach-name"    , 'n', required_argument, 0,  eArgTypeProcessName,
90         "Tells the debugger to attach to a process with the given name." },
91     { LLDB_OPT_SET_4,    true , "wait-for"       , 'w', no_argument      , 0,  eArgTypeNone,
92         "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
93     { LLDB_OPT_SET_5,    true , "attach-pid"     , 'p', required_argument, 0,  eArgTypePid,
94         "Tells the debugger to attach to a process with the given pid." },
95     { LLDB_3_TO_5,       false, "script-language", 'l', required_argument, 0,  eArgTypeScriptLang,
96         "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default.  "
97         "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl.  Currently only the Python "
98         "extensions have been implemented." },
99     { LLDB_3_TO_5,       false, "debug"          , 'd', no_argument      , 0,  eArgTypeNone,
100         "Tells the debugger to print out extra information for debugging itself." },
101     { LLDB_3_TO_5,       false, "source"         , 's', required_argument, 0,  eArgTypeFilename,
102         "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
103     { LLDB_3_TO_5,       false, "editor"         , 'e', no_argument      , 0,  eArgTypeNone,
104         "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
105     { LLDB_3_TO_5,       false, "no-lldbinit"    , 'x', no_argument      , 0,  eArgTypeNone,
106         "Do not automatically parse any '.lldbinit' files." },
107     { 0,                 false, NULL             , 0  , 0                , 0,  eArgTypeNone,         NULL }
108 };
109 
110 static const uint32_t last_option_set_with_args = 2;
111 
112 Driver::Driver () :
113     SBBroadcaster ("Driver"),
114     m_debugger (SBDebugger::Create(false)),
115     m_editline_pty (),
116     m_editline_slave_fh (NULL),
117     m_editline_reader (),
118     m_io_channel_ap (),
119     m_option_data (),
120     m_waiting_for_command (false)
121 {
122     // We want to be able to handle CTRL+D in the terminal to have it terminate
123     // certain input
124     m_debugger.SetCloseInputOnEOF (false);
125     g_debugger_name = (char *) m_debugger.GetInstanceName();
126     if (g_debugger_name == NULL)
127         g_debugger_name = (char *) "";
128     g_driver = this;
129 }
130 
131 Driver::~Driver ()
132 {
133     g_driver = NULL;
134     g_debugger_name = NULL;
135 }
136 
137 void
138 Driver::CloseIOChannelFile ()
139 {
140     // Write an End of File sequence to the file descriptor to ensure any
141     // read functions can exit.
142     char eof_str[] = "\x04";
143     ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
144 
145     m_editline_pty.CloseMasterFileDescriptor();
146 
147     if (m_editline_slave_fh)
148     {
149         ::fclose (m_editline_slave_fh);
150         m_editline_slave_fh = NULL;
151     }
152 }
153 
154 // This function takes INDENT, which tells how many spaces to output at the front
155 // of each line; TEXT, which is the text that is to be output. It outputs the
156 // text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
157 // front of each line.  It breaks lines on spaces, tabs or newlines, shortening
158 // the line if necessary to not break in the middle of a word. It assumes that
159 // each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
160 
161 void
162 OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
163 {
164     int len = strlen (text);
165     std::string text_string (text);
166 
167     // Force indentation to be reasonable.
168     if (indent >= output_max_columns)
169         indent = 0;
170 
171     // Will it all fit on one line?
172 
173     if (len + indent < output_max_columns)
174         // Output as a single line
175         fprintf (out, "%*s%s\n", indent, "", text);
176     else
177     {
178         // We need to break it up into multiple lines.
179         int text_width = output_max_columns - indent - 1;
180         int start = 0;
181         int end = start;
182         int final_end = len;
183         int sub_len;
184 
185         while (end < final_end)
186         {
187               // Dont start the 'text' on a space, since we're already outputting the indentation.
188               while ((start < final_end) && (text[start] == ' '))
189                   start++;
190 
191               end = start + text_width;
192               if (end > final_end)
193                   end = final_end;
194               else
195               {
196                   // If we're not at the end of the text, make sure we break the line on white space.
197                   while (end > start
198                          && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
199                       end--;
200               }
201               sub_len = end - start;
202               std::string substring = text_string.substr (start, sub_len);
203               fprintf (out, "%*s%s\n", indent, "", substring.c_str());
204               start = end + 1;
205         }
206     }
207 }
208 
209 void
210 ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
211 {
212     uint32_t screen_width = 80;
213     uint32_t indent_level = 0;
214     const char *name = "lldb";
215 
216     fprintf (out, "\nUsage:\n\n");
217 
218     indent_level += 2;
219 
220 
221     // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
222     //                                                   <cmd> [options-for-level-1]
223     //                                                   etc.
224 
225     uint32_t num_options;
226     uint32_t num_option_sets = 0;
227 
228     for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
229     {
230         uint32_t this_usage_mask = option_table[num_options].usage_mask;
231         if (this_usage_mask == LLDB_OPT_SET_ALL)
232         {
233             if (num_option_sets == 0)
234                 num_option_sets = 1;
235         }
236         else
237         {
238             for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
239             {
240                 if (this_usage_mask & 1 << j)
241                 {
242                     if (num_option_sets <= j)
243                         num_option_sets = j + 1;
244                 }
245             }
246         }
247     }
248 
249     for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
250     {
251         uint32_t opt_set_mask;
252 
253         opt_set_mask = 1 << opt_set;
254 
255         if (opt_set > 0)
256             fprintf (out, "\n");
257         fprintf (out, "%*s%s", indent_level, "", name);
258         bool is_help_line = false;
259 
260         for (uint32_t i = 0; i < num_options; ++i)
261         {
262             if (option_table[i].usage_mask & opt_set_mask)
263             {
264                 CommandArgumentType arg_type = option_table[i].argument_type;
265                 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
266                 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
267                 // so we do it by hand here.
268                 if (option_table[i].short_option == 'h')
269                     is_help_line = true;
270 
271                 if (option_table[i].required)
272                 {
273                     if (option_table[i].option_has_arg == required_argument)
274                         fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
275                     else if (option_table[i].option_has_arg == optional_argument)
276                         fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
277                     else
278                         fprintf (out, " -%c", option_table[i].short_option);
279                 }
280                 else
281                 {
282                     if (option_table[i].option_has_arg == required_argument)
283                         fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
284                     else if (option_table[i].option_has_arg == optional_argument)
285                         fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
286                     else
287                         fprintf (out, " [-%c]", option_table[i].short_option);
288                 }
289             }
290         }
291         if (!is_help_line && (opt_set <= last_option_set_with_args))
292             fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
293     }
294 
295     fprintf (out, "\n\n");
296 
297     // Now print out all the detailed information about the various options:  long form, short form and help text:
298     //   -- long_name <argument>
299     //   - short <argument>
300     //   help text
301 
302     // This variable is used to keep track of which options' info we've printed out, because some options can be in
303     // more than one usage level, but we only want to print the long form of its information once.
304 
305     Driver::OptionData::OptionSet options_seen;
306     Driver::OptionData::OptionSet::iterator pos;
307 
308     indent_level += 5;
309 
310     for (uint32_t i = 0; i < num_options; ++i)
311     {
312         // Only print this option if we haven't already seen it.
313         pos = options_seen.find (option_table[i].short_option);
314         if (pos == options_seen.end())
315         {
316             CommandArgumentType arg_type = option_table[i].argument_type;
317             const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
318 
319             options_seen.insert (option_table[i].short_option);
320             fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
321             if (arg_type != eArgTypeNone)
322                 fprintf (out, "<%s>", arg_name);
323             fprintf (out, "\n");
324             fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
325             if (arg_type != eArgTypeNone)
326                 fprintf (out, "<%s>", arg_name);
327             fprintf (out, "\n");
328             indent_level += 5;
329             OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
330             indent_level -= 5;
331             fprintf (out, "\n");
332         }
333     }
334 
335     indent_level -= 5;
336 
337     fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
338                   "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
339                   "\n%*s 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_source_command_files (),
387     m_debug_mode (false),
388     m_print_version (false),
389     m_print_help (false),
390     m_wait_for(false),
391     m_process_name(),
392     m_process_pid(LLDB_INVALID_PROCESS_ID),
393     m_use_external_editor(false),
394     m_seen_options()
395 {
396 }
397 
398 Driver::OptionData::~OptionData ()
399 {
400 }
401 
402 void
403 Driver::OptionData::Clear ()
404 {
405     m_args.clear ();
406     m_script_lang = lldb::eScriptLanguageDefault;
407     m_source_command_files.clear ();
408     m_debug_mode = false;
409     m_print_help = false;
410     m_print_version = false;
411     m_use_external_editor = false;
412     m_wait_for = false;
413     m_process_name.erase();
414     m_process_pid = LLDB_INVALID_PROCESS_ID;
415 }
416 
417 void
418 Driver::ResetOptionValues ()
419 {
420     m_option_data.Clear ();
421 }
422 
423 const char *
424 Driver::GetFilename() const
425 {
426     if (m_option_data.m_args.empty())
427         return NULL;
428     return m_option_data.m_args.front().c_str();
429 }
430 
431 const char *
432 Driver::GetCrashLogFilename() const
433 {
434     if (m_option_data.m_crash_log.empty())
435         return NULL;
436     return m_option_data.m_crash_log.c_str();
437 }
438 
439 lldb::ScriptLanguage
440 Driver::GetScriptLanguage() const
441 {
442     return m_option_data.m_script_lang;
443 }
444 
445 size_t
446 Driver::GetNumSourceCommandFiles () const
447 {
448     return m_option_data.m_source_command_files.size();
449 }
450 
451 const char *
452 Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
453 {
454     if (idx < m_option_data.m_source_command_files.size())
455         return m_option_data.m_source_command_files[idx].c_str();
456     return NULL;
457 }
458 
459 bool
460 Driver::GetDebugMode() const
461 {
462     return m_option_data.m_debug_mode;
463 }
464 
465 
466 // Check the arguments that were passed to this program to make sure they are valid and to get their
467 // argument values (if any).  Return a boolean value indicating whether or not to start up the full
468 // debugger (i.e. the Command Interpreter) or not.  Return FALSE if the arguments were invalid OR
469 // if the user only wanted help or version information.
470 
471 SBError
472 Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
473 {
474     ResetOptionValues ();
475 
476     SBCommandReturnObject result;
477 
478     SBError error;
479     std::string option_string;
480     struct option *long_options = NULL;
481     std::vector<struct option> long_options_vector;
482     uint32_t num_options;
483 
484     for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
485         /* Do Nothing. */;
486 
487     if (num_options == 0)
488     {
489         if (argc > 1)
490             error.SetErrorStringWithFormat ("invalid number of options");
491         return error;
492     }
493 
494     BuildGetOptTable (g_options, long_options_vector, num_options);
495 
496     if (long_options_vector.empty())
497         long_options = NULL;
498     else
499         long_options = &long_options_vector.front();
500 
501     if (long_options == NULL)
502     {
503         error.SetErrorStringWithFormat ("invalid long options");
504         return error;
505     }
506 
507     // Build the option_string argument for call to getopt_long.
508 
509     for (int i = 0; long_options[i].name != NULL; ++i)
510     {
511         if (long_options[i].flag == NULL)
512         {
513             option_string.push_back ((char) long_options[i].val);
514             switch (long_options[i].has_arg)
515             {
516                 default:
517                 case no_argument:
518                     break;
519                 case required_argument:
520                     option_string.push_back (':');
521                     break;
522                 case optional_argument:
523                     option_string.append ("::");
524                     break;
525             }
526         }
527     }
528 
529     // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
530     // know at that point whether we should read in init files yet.  So we don't read them in in the
531     // Driver constructor, then set the flags back to "read them in" here, and then if we see the
532     // "-n" flag, we'll turn it off again.  Finally we have to read them in by hand later in the
533     // main loop.
534 
535     m_debugger.SkipLLDBInitFiles (false);
536     m_debugger.SkipAppInitFiles (false);
537 
538     // Prepare for & make calls to getopt_long.
539 #if __GLIBC__
540     optind = 0;
541 #else
542     optreset = 1;
543     optind = 1;
544 #endif
545     int val;
546     while (1)
547     {
548         int long_options_index = -1;
549         val = ::getopt_long (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
550 
551         if (val == -1)
552             break;
553         else if (val == '?')
554         {
555             m_option_data.m_print_help = true;
556             error.SetErrorStringWithFormat ("unknown or ambiguous option");
557             break;
558         }
559         else if (val == 0)
560             continue;
561         else
562         {
563             m_option_data.m_seen_options.insert ((char) val);
564             if (long_options_index == -1)
565             {
566                 for (int i = 0;
567                      long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
568                      ++i)
569                 {
570                     if (long_options[i].val == val)
571                     {
572                         long_options_index = i;
573                         break;
574                     }
575                 }
576             }
577 
578             if (long_options_index >= 0)
579             {
580                 const char short_option = (char) g_options[long_options_index].short_option;
581 
582                 switch (short_option)
583                 {
584                     case 'h':
585                         m_option_data.m_print_help = true;
586                         break;
587 
588                     case 'v':
589                         m_option_data.m_print_version = true;
590                         break;
591 
592                     case 'c':
593                         {
594                             SBFileSpec file(optarg);
595                             if (file.Exists())
596                             {
597                                 m_option_data.m_core_file = optarg;
598                             }
599                             else
600                                 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
601                         }
602                         break;
603 
604                     case 'e':
605                         m_option_data.m_use_external_editor = true;
606                         break;
607 
608                     case 'x':
609                         m_debugger.SkipLLDBInitFiles (true);
610                         m_debugger.SkipAppInitFiles (true);
611                         break;
612 
613                     case 'f':
614                         {
615                             SBFileSpec file(optarg);
616                             if (file.Exists())
617                             {
618                                 m_option_data.m_args.push_back (optarg);
619                             }
620                             else if (file.ResolveExecutableLocation())
621                             {
622                                 char path[PATH_MAX];
623                                 file.GetPath (path, sizeof(path));
624                                 m_option_data.m_args.push_back (path);
625                             }
626                             else
627                                 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
628                         }
629                         break;
630 
631                     case 'a':
632                         if (!m_debugger.SetDefaultArchitecture (optarg))
633                             error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
634                         break;
635 
636                     case 'l':
637                         m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
638                         break;
639 
640                     case 'd':
641                         m_option_data.m_debug_mode = true;
642                         break;
643 
644                     case 'n':
645                         m_option_data.m_process_name = optarg;
646                         break;
647 
648                     case 'w':
649                         m_option_data.m_wait_for = true;
650                         break;
651 
652                     case 'p':
653                         {
654                             char *remainder;
655                             m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
656                             if (remainder == optarg || *remainder != '\0')
657                                 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
658                                                                 optarg);
659                         }
660                         break;
661                     case 's':
662                         {
663                             SBFileSpec file(optarg);
664                             if (file.Exists())
665                                 m_option_data.m_source_command_files.push_back (optarg);
666                             else if (file.ResolveExecutableLocation())
667                             {
668                                 char final_path[PATH_MAX];
669                                 file.GetPath (final_path, sizeof(final_path));
670                                 std::string path_str (final_path);
671                                 m_option_data.m_source_command_files.push_back (path_str);
672                             }
673                             else
674                                 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
675                         }
676                         break;
677 
678                     default:
679                         m_option_data.m_print_help = true;
680                         error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
681                         break;
682                 }
683             }
684             else
685             {
686                 error.SetErrorStringWithFormat ("invalid option with value %i", val);
687             }
688             if (error.Fail())
689             {
690                 return error;
691             }
692         }
693     }
694 
695     if (error.Fail() || m_option_data.m_print_help)
696     {
697         ShowUsage (out_fh, g_options, m_option_data);
698         exit = true;
699     }
700     else if (m_option_data.m_print_version)
701     {
702         ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
703         exit = true;
704     }
705     else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
706     {
707         // Any arguments that are left over after option parsing are for
708         // the program. If a file was specified with -f then the filename
709         // is already in the m_option_data.m_args array, and any remaining args
710         // are arguments for the inferior program. If no file was specified with
711         // -f, then what is left is the program name followed by any arguments.
712 
713         // Skip any options we consumed with getopt_long
714         argc -= optind;
715         argv += optind;
716 
717         if (argc > 0)
718         {
719             for (int arg_idx=0; arg_idx<argc; ++arg_idx)
720             {
721                 const char *arg = argv[arg_idx];
722                 if (arg)
723                     m_option_data.m_args.push_back (arg);
724             }
725         }
726 
727     }
728     else
729     {
730         // Skip any options we consumed with getopt_long
731         argc -= optind;
732         //argv += optind; // Commented out to keep static analyzer happy
733 
734         if (argc > 0)
735             ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
736     }
737 
738     return error;
739 }
740 
741 size_t
742 Driver::GetProcessSTDOUT ()
743 {
744     //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
745     char stdio_buffer[1024];
746     size_t len;
747     size_t total_bytes = 0;
748     while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
749     {
750         m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC);
751         total_bytes += len;
752     }
753     return total_bytes;
754 }
755 
756 size_t
757 Driver::GetProcessSTDERR ()
758 {
759     //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
760     char stdio_buffer[1024];
761     size_t len;
762     size_t total_bytes = 0;
763     while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
764     {
765         m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC);
766         total_bytes += len;
767     }
768     return total_bytes;
769 }
770 
771 void
772 Driver::UpdateSelectedThread ()
773 {
774     using namespace lldb;
775     SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
776     if (process.IsValid())
777     {
778         SBThread curr_thread (process.GetSelectedThread());
779         SBThread thread;
780         StopReason curr_thread_stop_reason = eStopReasonInvalid;
781         curr_thread_stop_reason = curr_thread.GetStopReason();
782 
783         if (!curr_thread.IsValid() ||
784             curr_thread_stop_reason == eStopReasonInvalid ||
785             curr_thread_stop_reason == eStopReasonNone)
786         {
787             // Prefer a thread that has just completed its plan over another thread as current thread.
788             SBThread plan_thread;
789             SBThread other_thread;
790             const size_t num_threads = process.GetNumThreads();
791             size_t i;
792             for (i = 0; i < num_threads; ++i)
793             {
794                 thread = process.GetThreadAtIndex(i);
795                 StopReason thread_stop_reason = thread.GetStopReason();
796                 switch (thread_stop_reason)
797                 {
798                 default:
799                 case eStopReasonInvalid:
800                 case eStopReasonNone:
801                     break;
802 
803                 case eStopReasonTrace:
804                 case eStopReasonBreakpoint:
805                 case eStopReasonWatchpoint:
806                 case eStopReasonSignal:
807                 case eStopReasonException:
808                     if (!other_thread.IsValid())
809                         other_thread = thread;
810                     break;
811                 case eStopReasonPlanComplete:
812                     if (!plan_thread.IsValid())
813                         plan_thread = thread;
814                     break;
815                 }
816             }
817             if (plan_thread.IsValid())
818                 process.SetSelectedThread (plan_thread);
819             else if (other_thread.IsValid())
820                 process.SetSelectedThread (other_thread);
821             else
822             {
823                 if (curr_thread.IsValid())
824                     thread = curr_thread;
825                 else
826                     thread = process.GetThreadAtIndex(0);
827 
828                 if (thread.IsValid())
829                     process.SetSelectedThread (thread);
830             }
831         }
832     }
833 }
834 
835 // This function handles events that were broadcast by the process.
836 void
837 Driver::HandleBreakpointEvent (const SBEvent &event)
838 {
839     using namespace lldb;
840     const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
841 
842     if (event_type & eBreakpointEventTypeAdded
843         || event_type & eBreakpointEventTypeRemoved
844         || event_type & eBreakpointEventTypeEnabled
845         || event_type & eBreakpointEventTypeDisabled
846         || event_type & eBreakpointEventTypeCommandChanged
847         || event_type & eBreakpointEventTypeConditionChanged
848         || event_type & eBreakpointEventTypeIgnoreChanged
849         || event_type & eBreakpointEventTypeLocationsResolved)
850     {
851         // Don't do anything about these events, since the breakpoint commands already echo these actions.
852     }
853     else if (event_type & eBreakpointEventTypeLocationsAdded)
854     {
855         char message[256];
856         uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
857         if (num_new_locations > 0)
858         {
859             SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
860             int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n",
861                                           num_new_locations,
862                                           num_new_locations == 1 ? "" : "s",
863                                           breakpoint.GetID());
864             m_io_channel_ap->OutWrite(message, message_len, ASYNC);
865         }
866     }
867     else if (event_type & eBreakpointEventTypeLocationsRemoved)
868     {
869        // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
870     }
871     else if (event_type & eBreakpointEventTypeLocationsResolved)
872     {
873        // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
874     }
875 }
876 
877 // This function handles events that were broadcast by the process.
878 void
879 Driver::HandleProcessEvent (const SBEvent &event)
880 {
881     using namespace lldb;
882     const uint32_t event_type = event.GetType();
883 
884     if (event_type & SBProcess::eBroadcastBitSTDOUT)
885     {
886         // The process has stdout available, get it and write it out to the
887         // appropriate place.
888         GetProcessSTDOUT ();
889     }
890     else if (event_type & SBProcess::eBroadcastBitSTDERR)
891     {
892         // The process has stderr available, get it and write it out to the
893         // appropriate place.
894         GetProcessSTDERR ();
895     }
896     else if (event_type & SBProcess::eBroadcastBitStateChanged)
897     {
898         // Drain all stout and stderr so we don't see any output come after
899         // we print our prompts
900         GetProcessSTDOUT ();
901         GetProcessSTDERR ();
902         // Something changed in the process;  get the event and report the process's current status and location to
903         // the user.
904         StateType event_state = SBProcess::GetStateFromEvent (event);
905         if (event_state == eStateInvalid)
906             return;
907 
908         SBProcess process (SBProcess::GetProcessFromEvent (event));
909         assert (process.IsValid());
910 
911         switch (event_state)
912         {
913         case eStateInvalid:
914         case eStateUnloaded:
915         case eStateConnected:
916         case eStateAttaching:
917         case eStateLaunching:
918         case eStateStepping:
919         case eStateDetached:
920             {
921                 char message[1024];
922                 int message_len = ::snprintf (message, sizeof(message), "Process %llu %s\n", process.GetProcessID(),
923                                               m_debugger.StateAsCString (event_state));
924                 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
925             }
926             break;
927 
928         case eStateRunning:
929             // Don't be chatty when we run...
930             break;
931 
932         case eStateExited:
933             {
934                 SBCommandReturnObject result;
935                 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
936                 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
937                 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
938             }
939             break;
940 
941         case eStateStopped:
942         case eStateCrashed:
943         case eStateSuspended:
944             // Make sure the program hasn't been auto-restarted:
945             if (SBProcess::GetRestartedFromEvent (event))
946             {
947                 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
948                 char message[1024];
949                 int message_len = ::snprintf (message, sizeof(message), "Process %llu stopped and was programmatically restarted.\n",
950                                               process.GetProcessID());
951                 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
952             }
953             else
954             {
955                 if (GetDebugger().GetSelectedTarget() == process.GetTarget())
956                 {
957                     SBCommandReturnObject result;
958                     UpdateSelectedThread ();
959                     m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
960                     m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
961                     m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
962                 }
963                 else
964                 {
965                     SBStream out_stream;
966                     uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget());
967                     if (target_idx != UINT32_MAX)
968                         out_stream.Printf ("Target %d: (", target_idx);
969                     else
970                         out_stream.Printf ("Target <unknown index>: (");
971                     process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief);
972                     out_stream.Printf (") stopped.\n");
973                     m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC);
974                 }
975             }
976             break;
977         }
978     }
979 }
980 
981 void
982 Driver::HandleThreadEvent (const SBEvent &event)
983 {
984     // At present the only thread event we handle is the Frame Changed event, and all we do for that is just
985     // reprint the thread status for that thread.
986     using namespace lldb;
987     const uint32_t event_type = event.GetType();
988     if (event_type == SBThread::eBroadcastBitStackChanged)
989     {
990         SBThread thread = SBThread::GetThreadFromEvent (event);
991         if (thread.IsValid())
992         {
993             SBStream out_stream;
994             thread.GetStatus(out_stream);
995             m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
996         }
997     }
998 }
999 
1000 //  This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
1001 
1002 bool
1003 Driver::HandleIOEvent (const SBEvent &event)
1004 {
1005     bool quit = false;
1006 
1007     const uint32_t event_type = event.GetType();
1008 
1009     if (event_type & IOChannel::eBroadcastBitHasUserInput)
1010     {
1011         // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
1012         // handling.
1013 
1014         const char *command_string = SBEvent::GetCStringFromEvent(event);
1015         if (command_string == NULL)
1016             command_string = "";
1017         SBCommandReturnObject result;
1018 
1019         // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
1020         // output orderings and problems with the prompt.
1021         m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
1022 
1023         const bool only_if_no_immediate = true;
1024 
1025         const size_t output_size = result.GetOutputSize();
1026 
1027         if (output_size > 0)
1028             m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC);
1029 
1030         const size_t error_size = result.GetErrorSize();
1031 
1032         if (error_size > 0)
1033             m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC);
1034 
1035         // We are done getting and running our command, we can now clear the
1036         // m_waiting_for_command so we can get another one.
1037         m_waiting_for_command = false;
1038 
1039         // If our editline input reader is active, it means another input reader
1040         // got pushed onto the input reader and caused us to become deactivated.
1041         // When the input reader above us gets popped, we will get re-activated
1042         // and our prompt will refresh in our callback
1043         if (m_editline_reader.IsActive())
1044         {
1045             ReadyForCommand ();
1046         }
1047     }
1048     else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
1049     {
1050         // This is here to handle control-c interrupts from the user.  It has not yet really been implemented.
1051         // TO BE DONE:  PROPERLY HANDLE CONTROL-C FROM USER
1052         //m_io_channel_ap->CancelInput();
1053         // Anything else?  Send Interrupt to process?
1054     }
1055     else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1056              (event_type & IOChannel::eBroadcastBitThreadDidExit))
1057     {
1058         // If the IOChannel thread is trying to go away, then it is definitely
1059         // time to end the debugging session.
1060         quit = true;
1061     }
1062 
1063     return quit;
1064 }
1065 
1066 void
1067 Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
1068 {
1069     Driver *driver = (Driver*)baton;
1070     driver->GetFromMaster ((const char *)src, src_len);
1071 }
1072 
1073 void
1074 Driver::GetFromMaster (const char *src, size_t src_len)
1075 {
1076     // Echo the characters back to the Debugger's stdout, that way if you
1077     // type characters while a command is running, you'll see what you've typed.
1078     FILE *out_fh = m_debugger.GetOutputFileHandle();
1079     if (out_fh)
1080         ::fwrite (src, 1, src_len, out_fh);
1081 }
1082 
1083 size_t
1084 Driver::EditLineInputReaderCallback
1085 (
1086     void *baton,
1087     SBInputReader *reader,
1088     InputReaderAction notification,
1089     const char *bytes,
1090     size_t bytes_len
1091 )
1092 {
1093     Driver *driver = (Driver *)baton;
1094 
1095     switch (notification)
1096     {
1097     case eInputReaderActivate:
1098         break;
1099 
1100     case eInputReaderReactivate:
1101         driver->ReadyForCommand();
1102         break;
1103 
1104     case eInputReaderDeactivate:
1105         break;
1106 
1107     case eInputReaderAsynchronousOutputWritten:
1108         if (driver->m_io_channel_ap.get() != NULL)
1109             driver->m_io_channel_ap->RefreshPrompt();
1110         break;
1111 
1112     case eInputReaderInterrupt:
1113         if (driver->m_io_channel_ap.get() != NULL)
1114         {
1115             SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess());
1116             if (!driver->m_io_channel_ap->EditLineHasCharacters()
1117                 &&  process.IsValid()
1118                 && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching))
1119             {
1120                 process.SendAsyncInterrupt ();
1121             }
1122             else
1123             {
1124                 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
1125                 // I wish I could erase the entire input line, but there's no public API for that.
1126                 driver->m_io_channel_ap->EraseCharsBeforeCursor();
1127                 driver->m_io_channel_ap->RefreshPrompt();
1128             }
1129         }
1130         break;
1131 
1132     case eInputReaderEndOfFile:
1133         if (driver->m_io_channel_ap.get() != NULL)
1134         {
1135             driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
1136             driver->m_io_channel_ap->RefreshPrompt ();
1137         }
1138         write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
1139         break;
1140 
1141     case eInputReaderGotToken:
1142         write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
1143         break;
1144 
1145     case eInputReaderDone:
1146         break;
1147     }
1148     return bytes_len;
1149 }
1150 
1151 void
1152 Driver::MainLoop ()
1153 {
1154     char error_str[1024];
1155     if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
1156     {
1157         ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
1158         exit(1);
1159     }
1160     else
1161     {
1162         const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1163         if (driver_slave_name == NULL)
1164         {
1165             ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1166             exit(2);
1167         }
1168         else
1169         {
1170             m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1171             if (m_editline_slave_fh == NULL)
1172             {
1173                 SBError error;
1174                 error.SetErrorToErrno();
1175                 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1176                            error.GetCString());
1177                 exit(3);
1178             }
1179 
1180             ::setbuf (m_editline_slave_fh, NULL);
1181         }
1182     }
1183 
1184     lldb_utility::PseudoTerminal editline_output_pty;
1185     FILE *editline_output_slave_fh = NULL;
1186 
1187     if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
1188     {
1189         ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
1190         exit(1);
1191     }
1192     else
1193     {
1194         const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
1195         if (output_slave_name == NULL)
1196         {
1197             ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
1198             exit(2);
1199         }
1200         else
1201         {
1202             editline_output_slave_fh = ::fopen (output_slave_name, "r+");
1203             if (editline_output_slave_fh == NULL)
1204             {
1205                 SBError error;
1206                 error.SetErrorToErrno();
1207                 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
1208                            error.GetCString());
1209                 exit(3);
1210             }
1211             ::setbuf (editline_output_slave_fh, NULL);
1212         }
1213     }
1214 
1215    // struct termios stdin_termios;
1216 
1217     if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
1218     {
1219         g_old_stdin_termios_is_valid = true;
1220         atexit (reset_stdin_termios);
1221     }
1222 
1223     ::setbuf (stdin, NULL);
1224     ::setbuf (stdout, NULL);
1225 
1226     m_debugger.SetErrorFileHandle (stderr, false);
1227     m_debugger.SetOutputFileHandle (stdout, false);
1228     m_debugger.SetInputFileHandle (stdin, true);
1229 
1230     m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
1231 
1232     // You have to drain anything that comes to the master side of the PTY.  master_out_comm is
1233     // for that purpose.  The reason you need to do this is a curious reason...  editline will echo
1234     // characters to the PTY when it gets characters while el_gets is not running, and then when
1235     // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1236     // if there are unconsumed characters in the out buffer.
1237     // However, you don't need to do anything with the characters, since editline will dump these
1238     // unconsumed characters after printing the prompt again in el_gets.
1239 
1240     SBCommunication master_out_comm("driver.editline");
1241     master_out_comm.SetCloseOnEOF (false);
1242     master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1243     master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1244 
1245     if (master_out_comm.ReadThreadStart () == false)
1246     {
1247         ::fprintf (stderr, "error: failed to start master out read thread");
1248         exit(5);
1249     }
1250 
1251     SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
1252 
1253     m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
1254 
1255     SBCommunication out_comm_2("driver.editline_output");
1256     out_comm_2.SetCloseOnEOF (false);
1257     out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
1258     out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
1259 
1260     if (out_comm_2.ReadThreadStart () == false)
1261     {
1262         ::fprintf (stderr, "error: failed to start libedit output read thread");
1263         exit (5);
1264     }
1265 
1266 
1267     struct winsize window_size;
1268     if (isatty (STDIN_FILENO)
1269         && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1270     {
1271         if (window_size.ws_col > 0)
1272             m_debugger.SetTerminalWidth (window_size.ws_col);
1273     }
1274 
1275     // Since input can be redirected by the debugger, we must insert our editline
1276     // input reader in the queue so we know when our reader should be active
1277     // and so we can receive bytes only when we are supposed to.
1278     SBError err (m_editline_reader.Initialize (m_debugger,
1279                                                Driver::EditLineInputReaderCallback, // callback
1280                                                this,                              // baton
1281                                                eInputReaderGranularityByte,       // token_size
1282                                                NULL,                              // end token - NULL means never done
1283                                                NULL,                              // prompt - taken care of elsewhere
1284                                                false));                           // echo input - don't need Debugger
1285                                                                                   // to do this, we handle it elsewhere
1286 
1287     if (err.Fail())
1288     {
1289         ::fprintf (stderr, "error: %s", err.GetCString());
1290         exit (6);
1291     }
1292 
1293     m_debugger.PushInputReader (m_editline_reader);
1294 
1295     SBListener listener(m_debugger.GetListener());
1296     if (listener.IsValid())
1297     {
1298 
1299         listener.StartListeningForEventClass(m_debugger,
1300                                          SBTarget::GetBroadcasterClassName(),
1301                                          SBTarget::eBroadcastBitBreakpointChanged);
1302         listener.StartListeningForEventClass(m_debugger,
1303                                          SBThread::GetBroadcasterClassName(),
1304                                          SBThread::eBroadcastBitStackChanged);
1305         listener.StartListeningForEvents (*m_io_channel_ap,
1306                                           IOChannel::eBroadcastBitHasUserInput |
1307                                           IOChannel::eBroadcastBitUserInterrupt |
1308                                           IOChannel::eBroadcastBitThreadShouldExit |
1309                                           IOChannel::eBroadcastBitThreadDidStart |
1310                                           IOChannel::eBroadcastBitThreadDidExit);
1311 
1312         if (m_io_channel_ap->Start ())
1313         {
1314             bool iochannel_thread_exited = false;
1315 
1316             listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
1317                                               SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1318                                               SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1319                                               SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
1320 
1321             // Before we handle any options from the command line, we parse the
1322             // .lldbinit file in the user's home directory.
1323             SBCommandReturnObject result;
1324             sb_interpreter.SourceInitFileInHomeDirectory(result);
1325             if (GetDebugMode())
1326             {
1327                 result.PutError (m_debugger.GetErrorFileHandle());
1328                 result.PutOutput (m_debugger.GetOutputFileHandle());
1329             }
1330 
1331             // Now we handle options we got from the command line
1332             char command_string[PATH_MAX * 2];
1333             const size_t num_source_command_files = GetNumSourceCommandFiles();
1334             if (num_source_command_files > 0)
1335             {
1336                 for (size_t i=0; i < num_source_command_files; ++i)
1337                 {
1338                     const char *command_file = GetSourceCommandFileAtIndex(i);
1339                     ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
1340                     m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
1341                     if (GetDebugMode())
1342                     {
1343                         result.PutError (m_debugger.GetErrorFileHandle());
1344                         result.PutOutput (m_debugger.GetOutputFileHandle());
1345                     }
1346                 }
1347             }
1348 
1349             // Was there a core file specified?
1350             std::string core_file_spec("");
1351             if (!m_option_data.m_core_file.empty())
1352                 core_file_spec.append("--core ").append(m_option_data.m_core_file);
1353 
1354             const size_t num_args = m_option_data.m_args.size();
1355             if (num_args > 0)
1356             {
1357                 char arch_name[64];
1358                 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
1359                     ::snprintf (command_string,
1360                                 sizeof (command_string),
1361                                 "target create --arch=%s %s \"%s\"",
1362                                 arch_name,
1363                                 core_file_spec.c_str(),
1364                                 m_option_data.m_args[0].c_str());
1365                 else
1366                     ::snprintf (command_string,
1367                                 sizeof(command_string),
1368                                 "target create %s \"%s\"",
1369                                 core_file_spec.c_str(),
1370                                 m_option_data.m_args[0].c_str());
1371 
1372                 m_debugger.HandleCommand (command_string);
1373 
1374                 if (num_args > 1)
1375                 {
1376                     m_debugger.HandleCommand ("settings clear target.run-args");
1377                     char arg_cstr[1024];
1378                     for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1379                     {
1380                         ::snprintf (arg_cstr,
1381                                     sizeof(arg_cstr),
1382                                     "settings append target.run-args \"%s\"",
1383                                     m_option_data.m_args[arg_idx].c_str());
1384                         m_debugger.HandleCommand (arg_cstr);
1385                     }
1386                 }
1387             }
1388             else if (!core_file_spec.empty())
1389             {
1390                 ::snprintf (command_string,
1391                             sizeof(command_string),
1392                             "target create %s",
1393                             core_file_spec.c_str());
1394                 m_debugger.HandleCommand (command_string);;
1395             }
1396 
1397             // Now that all option parsing is done, we try and parse the .lldbinit
1398             // file in the current working directory
1399             sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1400             if (GetDebugMode())
1401             {
1402                 result.PutError(m_debugger.GetErrorFileHandle());
1403                 result.PutOutput(m_debugger.GetOutputFileHandle());
1404             }
1405 
1406             SBEvent event;
1407 
1408             // Make sure the IO channel is started up before we try to tell it we
1409             // are ready for input
1410             listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1411                                                          *m_io_channel_ap,
1412                                                          IOChannel::eBroadcastBitThreadDidStart,
1413                                                          event);
1414             // If we were asked to attach, then do that here:
1415             // I'm going to use the command string rather than directly
1416             // calling the API's because then I don't have to recode the
1417             // event handling here.
1418             if (!m_option_data.m_process_name.empty()
1419                 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1420             {
1421                 std::string command_str("process attach ");
1422                 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1423                 {
1424                     command_str.append("-p ");
1425                     char pid_buffer[32];
1426                     ::snprintf (pid_buffer, sizeof(pid_buffer), "%llu", m_option_data.m_process_pid);
1427                     command_str.append(pid_buffer);
1428                 }
1429                 else
1430                 {
1431                     command_str.append("-n \"");
1432                     command_str.append(m_option_data.m_process_name);
1433                     command_str.push_back('\"');
1434                     if (m_option_data.m_wait_for)
1435                         command_str.append(" -w");
1436                 }
1437 
1438                 if (m_debugger.GetOutputFileHandle())
1439                     ::fprintf (m_debugger.GetOutputFileHandle(),
1440                                "Attaching to process with:\n    %s\n",
1441                                command_str.c_str());
1442 
1443                 // Force the attach to be synchronous:
1444                 bool orig_async = m_debugger.GetAsync();
1445                 m_debugger.SetAsync(true);
1446                 m_debugger.HandleCommand(command_str.c_str());
1447                 m_debugger.SetAsync(orig_async);
1448             }
1449 
1450             ReadyForCommand ();
1451 
1452             while (!GetIsDone())
1453             {
1454                 listener.WaitForEvent (UINT32_MAX, event);
1455                 if (event.IsValid())
1456                 {
1457                     if (event.GetBroadcaster().IsValid())
1458                     {
1459                         uint32_t event_type = event.GetType();
1460                         if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1461                         {
1462                             if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1463                                 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1464                             {
1465                                 SetIsDone();
1466                                 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1467                                     iochannel_thread_exited = true;
1468                             }
1469                             else
1470                             {
1471                                 if (HandleIOEvent (event))
1472                                     SetIsDone();
1473                             }
1474                         }
1475                         else if (SBProcess::EventIsProcessEvent (event))
1476                         {
1477                             HandleProcessEvent (event);
1478                         }
1479                         else if (SBBreakpoint::EventIsBreakpointEvent (event))
1480                         {
1481                             HandleBreakpointEvent (event);
1482                         }
1483                         else if (SBThread::EventIsThreadEvent (event))
1484                         {
1485                             HandleThreadEvent (event);
1486                         }
1487                         else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1488                         {
1489                             // TODO: deprecate the eBroadcastBitQuitCommandReceived event
1490                             // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
1491                             // that can take over a command
1492                             if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
1493                             {
1494                                 SetIsDone();
1495                             }
1496                             else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1497                             {
1498                                 const char *data = SBEvent::GetCStringFromEvent (event);
1499                                 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1500                             }
1501                             else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1502                             {
1503                                 const char *data = SBEvent::GetCStringFromEvent (event);
1504                                 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1505                             }
1506                         }
1507                     }
1508                 }
1509             }
1510 
1511             editline_output_pty.CloseMasterFileDescriptor();
1512             master_out_comm.Disconnect();
1513             out_comm_2.Disconnect();
1514             reset_stdin_termios();
1515             fclose (stdin);
1516 
1517             CloseIOChannelFile ();
1518 
1519             if (!iochannel_thread_exited)
1520             {
1521                 event.Clear();
1522                 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1523                                                              IOChannel::eBroadcastBitThreadDidExit,
1524                                                              event);
1525                 if (!event.IsValid())
1526                 {
1527                     // Send end EOF to the driver file descriptor
1528                     m_io_channel_ap->Stop();
1529                 }
1530             }
1531 
1532             SBDebugger::Destroy (m_debugger);
1533         }
1534     }
1535 }
1536 
1537 
1538 void
1539 Driver::ReadyForCommand ()
1540 {
1541     if (m_waiting_for_command == false)
1542     {
1543         m_waiting_for_command = true;
1544         BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1545     }
1546 }
1547 
1548 
1549 void
1550 sigwinch_handler (int signo)
1551 {
1552     struct winsize window_size;
1553     if (isatty (STDIN_FILENO)
1554         && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1555     {
1556         if ((window_size.ws_col > 0) && g_driver != NULL)
1557         {
1558             g_driver->GetDebugger().SetTerminalWidth (window_size.ws_col);
1559         }
1560     }
1561 }
1562 
1563 void
1564 sigint_handler (int signo)
1565 {
1566 	static bool g_interrupt_sent = false;
1567     if (g_driver)
1568 	{
1569 		if (!g_interrupt_sent)
1570 		{
1571 			g_interrupt_sent = true;
1572         	g_driver->GetDebugger().DispatchInputInterrupt();
1573 			g_interrupt_sent = false;
1574 			return;
1575 		}
1576 	}
1577 
1578 	exit (signo);
1579 }
1580 
1581 int
1582 main (int argc, char const *argv[], const char *envp[])
1583 {
1584     SBDebugger::Initialize();
1585 
1586     SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
1587 
1588     signal (SIGPIPE, SIG_IGN);
1589     signal (SIGWINCH, sigwinch_handler);
1590     signal (SIGINT, sigint_handler);
1591 
1592     // Create a scope for driver so that the driver object will destroy itself
1593     // before SBDebugger::Terminate() is called.
1594     {
1595         Driver driver;
1596 
1597         bool exit = false;
1598         SBError error (driver.ParseArgs (argc, argv, stdout, exit));
1599         if (error.Fail())
1600         {
1601             const char *error_cstr = error.GetCString ();
1602             if (error_cstr)
1603                 ::fprintf (stderr, "error: %s\n", error_cstr);
1604         }
1605         else if (!exit)
1606         {
1607             driver.MainLoop ();
1608         }
1609     }
1610 
1611     SBDebugger::Terminate();
1612     return 0;
1613 }
1614