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