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