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