blob: e2742425dd4c4433b696ba5b2b6ef0f12b6424da [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Deepak Panickal429222c2013-10-15 15:46:40 +000012#include <stdio.h>
Eli Friedmana382d472010-06-09 09:50:17 +000013#include <string.h>
14#include <stdlib.h>
15#include <limits.h>
Eli Friedman07b16272010-06-09 19:11:30 +000016#include <fcntl.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
18#include <string>
19
Deepak Panickal429222c2013-10-15 15:46:40 +000020#include <thread>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "IOChannel.h"
Jim Inghame6bc6cb2012-02-08 05:23:15 +000022#include "lldb/API/SBBreakpoint.h"
Eli Friedmana382d472010-06-09 09:50:17 +000023#include "lldb/API/SBCommandInterpreter.h"
24#include "lldb/API/SBCommandReturnObject.h"
25#include "lldb/API/SBCommunication.h"
26#include "lldb/API/SBDebugger.h"
27#include "lldb/API/SBEvent.h"
28#include "lldb/API/SBHostOS.h"
29#include "lldb/API/SBListener.h"
Jim Ingham85e8b812011-02-19 02:53:09 +000030#include "lldb/API/SBStream.h"
Eli Friedmana382d472010-06-09 09:50:17 +000031#include "lldb/API/SBTarget.h"
32#include "lldb/API/SBThread.h"
33#include "lldb/API/SBProcess.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
35using namespace lldb;
36
37static void reset_stdin_termios ();
Greg Claytonf571b892012-02-02 19:28:31 +000038static bool g_old_stdin_termios_is_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039static struct termios g_old_stdin_termios;
40
Caroline Ticedd759852010-09-09 17:45:09 +000041static char *g_debugger_name = (char *) "";
Caroline Ticeefed6132010-11-19 20:47:54 +000042static Driver *g_driver = NULL;
Caroline Ticedd759852010-09-09 17:45:09 +000043
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044// In the Driver::MainLoop, we change the terminal settings. This function is
45// added as an atexit handler to make sure we clean them up.
46static void
47reset_stdin_termios ()
48{
Greg Claytonf571b892012-02-02 19:28:31 +000049 if (g_old_stdin_termios_is_valid)
50 {
51 g_old_stdin_termios_is_valid = false;
52 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
53 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054}
55
Greg Claytone0d378b2011-03-24 21:19:54 +000056typedef struct
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057{
Greg Claytone0d378b2011-03-24 21:19:54 +000058 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
59 // then this option belongs to option set n.
60 bool required; // This option is required (in the current usage level)
61 const char * long_option; // Full name for this option.
Greg Clayton3bcdfc02012-12-04 00:32:51 +000062 int short_option; // Single character for this option.
Greg Claytone0d378b2011-03-24 21:19:54 +000063 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Claytonab65b342011-04-13 22:47:15 +000064 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytone0d378b2011-03-24 21:19:54 +000065 lldb::CommandArgumentType argument_type; // Type of argument this option takes
66 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
67 // pass it.
68} OptionDefinition;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069
Jim Inghame64f0dc2011-09-13 23:25:31 +000070#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
71#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
72
Greg Claytone0d378b2011-03-24 21:19:54 +000073static OptionDefinition g_options[] =
74{
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000075 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000076 "Prints out the usage information for the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000077 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000078 "Prints out the current version number of the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000079 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
Jim Ingham12e9a202011-09-15 21:30:02 +000080 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
81 "be one of the architectures for which the program was compiled." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000082 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +000083 "Tells the debugger to use the file <filename> as the program to be debugged." },
Jason Molenda67c3cf52012-10-24 03:29:40 +000084 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
Johnny Cheneb46f782012-08-15 22:10:42 +000085 "Tells the debugger to use the fullpath to <path> as the core file." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000086 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
Jim Ingham12e9a202011-09-15 21:30:02 +000087 "Tells the debugger to attach to a process with the given name." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000088 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000089 "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000090 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
Jim Ingham12e9a202011-09-15 21:30:02 +000091 "Tells the debugger to attach to a process with the given pid." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000092 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
Jim Ingham12e9a202011-09-15 21:30:02 +000093 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
94 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
95 "extensions have been implemented." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000096 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000097 "Tells the debugger to print out extra information for debugging itself." },
Jim Inghamed3252f2013-09-14 00:20:24 +000098 { LLDB_3_TO_5, false, "source-quietly" , 'b', no_argument , 0, eArgTypeNone,
99 "Tells the debugger to print out extra information for debugging itself." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000100 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000101 "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." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000102 { LLDB_3_TO_5, false, "one-line" , 'o', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000103 "Tells the debugger to execute this one-line lldb command after any file provided on the command line has been loaded." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000104 { LLDB_3_TO_5, false, "source-before-file" , 'S', required_argument, 0, eArgTypeFilename,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000105 "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." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000106 { LLDB_3_TO_5, false, "one-line-before-file" , 'O', required_argument, 0, eArgTypeNone,
Jim Ingham47ea51f2013-09-17 01:53:35 +0000107 "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000108 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000109 "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000110 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000111 "Do not automatically parse any '.lldbinit' files." },
Jim Inghamed3252f2013-09-14 00:20:24 +0000112 { LLDB_3_TO_5, false, "no-use-colors" , 'X', no_argument , 0, eArgTypeNone,
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000113 "Do not use colors." },
114 { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
Jim Inghame2231ac2012-12-21 22:22:26 +0000115 "Prints out the path to the lldb.py file for this version of lldb." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000116 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117};
118
Jim Inghame64f0dc2011-09-13 23:25:31 +0000119static const uint32_t last_option_set_with_args = 2;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120
121Driver::Driver () :
122 SBBroadcaster ("Driver"),
Jim Ingham06942692011-08-13 00:22:20 +0000123 m_debugger (SBDebugger::Create(false)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124 m_editline_pty (),
125 m_editline_slave_fh (NULL),
126 m_editline_reader (),
127 m_io_channel_ap (),
128 m_option_data (),
Greg Claytoneea37ee2013-05-14 17:36:51 +0000129 m_executing_user_command (false),
Daniel Malea926758b2012-12-17 17:40:07 +0000130 m_waiting_for_command (false),
131 m_done(false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132{
Greg Claytonfc3f0272011-05-29 04:06:55 +0000133 // We want to be able to handle CTRL+D in the terminal to have it terminate
134 // certain input
135 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticedd759852010-09-09 17:45:09 +0000136 g_debugger_name = (char *) m_debugger.GetInstanceName();
137 if (g_debugger_name == NULL)
138 g_debugger_name = (char *) "";
Caroline Ticeefed6132010-11-19 20:47:54 +0000139 g_driver = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140}
141
142Driver::~Driver ()
143{
Caroline Ticeefed6132010-11-19 20:47:54 +0000144 g_driver = NULL;
145 g_debugger_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146}
147
148void
149Driver::CloseIOChannelFile ()
150{
Johnny Chene26c7212012-05-16 22:01:10 +0000151 // Write an End of File sequence to the file descriptor to ensure any
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 // read functions can exit.
153 char eof_str[] = "\x04";
Deepak Panickal429222c2013-10-15 15:46:40 +0000154 int mfd = m_editline_pty.GetMasterFileDescriptor();
155 if (mfd != -1)
156 ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157
158 m_editline_pty.CloseMasterFileDescriptor();
159
160 if (m_editline_slave_fh)
161 {
162 ::fclose (m_editline_slave_fh);
163 m_editline_slave_fh = NULL;
164 }
165}
166
Greg Claytonc982c762010-07-09 20:39:50 +0000167// This function takes INDENT, which tells how many spaces to output at the front
168// of each line; TEXT, which is the text that is to be output. It outputs the
169// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
170// front of each line. It breaks lines on spaces, tabs or newlines, shortening
171// the line if necessary to not break in the middle of a word. It assumes that
172// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173
174void
Greg Claytonc982c762010-07-09 20:39:50 +0000175OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176{
177 int len = strlen (text);
178 std::string text_string (text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179
180 // Force indentation to be reasonable.
181 if (indent >= output_max_columns)
182 indent = 0;
183
184 // Will it all fit on one line?
185
186 if (len + indent < output_max_columns)
187 // Output as a single line
Greg Claytonc982c762010-07-09 20:39:50 +0000188 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 else
190 {
191 // We need to break it up into multiple lines.
192 int text_width = output_max_columns - indent - 1;
193 int start = 0;
194 int end = start;
195 int final_end = len;
196 int sub_len;
197
198 while (end < final_end)
199 {
200 // Dont start the 'text' on a space, since we're already outputting the indentation.
201 while ((start < final_end) && (text[start] == ' '))
202 start++;
203
204 end = start + text_width;
205 if (end > final_end)
206 end = final_end;
207 else
208 {
209 // If we're not at the end of the text, make sure we break the line on white space.
210 while (end > start
211 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
212 end--;
213 }
214 sub_len = end - start;
215 std::string substring = text_string.substr (start, sub_len);
Greg Claytonc982c762010-07-09 20:39:50 +0000216 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217 start = end + 1;
218 }
219 }
220}
221
222void
Greg Claytone0d378b2011-03-24 21:19:54 +0000223ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224{
225 uint32_t screen_width = 80;
226 uint32_t indent_level = 0;
227 const char *name = "lldb";
Jim Ingham86511212010-06-15 18:47:14 +0000228
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 fprintf (out, "\nUsage:\n\n");
230
231 indent_level += 2;
232
233
234 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
235 // <cmd> [options-for-level-1]
236 // etc.
237
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238 uint32_t num_options;
Jim Ingham86511212010-06-15 18:47:14 +0000239 uint32_t num_option_sets = 0;
240
241 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242 {
Jim Ingham86511212010-06-15 18:47:14 +0000243 uint32_t this_usage_mask = option_table[num_options].usage_mask;
244 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 {
Jim Ingham86511212010-06-15 18:47:14 +0000246 if (num_option_sets == 0)
247 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248 }
249 else
250 {
Greg Claytonc982c762010-07-09 20:39:50 +0000251 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham86511212010-06-15 18:47:14 +0000252 {
253 if (this_usage_mask & 1 << j)
254 {
255 if (num_option_sets <= j)
256 num_option_sets = j + 1;
257 }
258 }
259 }
260 }
261
262 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
263 {
264 uint32_t opt_set_mask;
265
266 opt_set_mask = 1 << opt_set;
267
268 if (opt_set > 0)
269 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000270 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham556e6532011-08-16 23:15:02 +0000271 bool is_help_line = false;
Jim Ingham86511212010-06-15 18:47:14 +0000272
273 for (uint32_t i = 0; i < num_options; ++i)
274 {
275 if (option_table[i].usage_mask & opt_set_mask)
276 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000277 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000278 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham556e6532011-08-16 23:15:02 +0000279 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
280 // so we do it by hand here.
281 if (option_table[i].short_option == 'h')
282 is_help_line = true;
283
Jim Ingham86511212010-06-15 18:47:14 +0000284 if (option_table[i].required)
285 {
286 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000287 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000288 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000289 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000290 else
291 fprintf (out, " -%c", option_table[i].short_option);
292 }
293 else
294 {
295 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000296 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000297 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000298 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000299 else
300 fprintf (out, " [-%c]", option_table[i].short_option);
301 }
302 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000304 if (!is_help_line && (opt_set <= last_option_set_with_args))
Jim Ingham556e6532011-08-16 23:15:02 +0000305 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306 }
307
308 fprintf (out, "\n\n");
309
310 // Now print out all the detailed information about the various options: long form, short form and help text:
311 // -- long_name <argument>
312 // - short <argument>
313 // help text
314
315 // This variable is used to keep track of which options' info we've printed out, because some options can be in
316 // more than one usage level, but we only want to print the long form of its information once.
317
318 Driver::OptionData::OptionSet options_seen;
319 Driver::OptionData::OptionSet::iterator pos;
320
321 indent_level += 5;
322
Jim Ingham86511212010-06-15 18:47:14 +0000323 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324 {
325 // Only print this option if we haven't already seen it.
326 pos = options_seen.find (option_table[i].short_option);
327 if (pos == options_seen.end())
328 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000329 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000330 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Ticedeaab222010-10-01 19:59:14 +0000331
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332 options_seen.insert (option_table[i].short_option);
Greg Claytonc982c762010-07-09 20:39:50 +0000333 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000334 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000335 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000337 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000338 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000339 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 fprintf (out, "\n");
341 indent_level += 5;
Greg Claytonc982c762010-07-09 20:39:50 +0000342 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 indent_level -= 5;
344 fprintf (out, "\n");
345 }
346 }
347
348 indent_level -= 5;
349
Jim Ingham47ea51f2013-09-17 01:53:35 +0000350 fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed from left to right in order, "
351 "\n%*swith the source files and commands interleaved. The same is true of the \"-S\" and \"-O\" options."
352 "\n%*sThe before file and after file sets can intermixed freely, the command parser will sort them out."
353 "\n%*sThe order of the file specifiers (\"-c\", \"-f\", etc.) is not significant in this regard.\n\n",
354 indent_level, "",
355 indent_level, "",
356 indent_level, "",
357 indent_level, "");
358
Jim Inghama9deaf92011-08-16 23:57:58 +0000359 fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
360 "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
361 "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
362 indent_level, "",
363 indent_level, "",
364 name,
365 indent_level, "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366}
367
368void
Greg Claytone0d378b2011-03-24 21:19:54 +0000369BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Tice4ab31c92010-10-12 21:57:09 +0000370 uint32_t num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371{
372 if (num_options == 0)
373 return;
374
375 uint32_t i;
376 uint32_t j;
377 std::bitset<256> option_seen;
378
Caroline Tice4ab31c92010-10-12 21:57:09 +0000379 getopt_table.resize (num_options + 1);
380
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381 for (i = 0, j = 0; i < num_options; ++i)
Greg Claytonc982c762010-07-09 20:39:50 +0000382 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383 char short_opt = expanded_option_table[i].short_option;
Greg Claytonc982c762010-07-09 20:39:50 +0000384
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 if (option_seen.test(short_opt) == false)
Greg Claytonc982c762010-07-09 20:39:50 +0000386 {
Caroline Tice4ab31c92010-10-12 21:57:09 +0000387 getopt_table[j].name = expanded_option_table[i].long_option;
388 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
389 getopt_table[j].flag = NULL;
390 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 option_seen.set(short_opt);
392 ++j;
Greg Claytonc982c762010-07-09 20:39:50 +0000393 }
394 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395
Caroline Tice4ab31c92010-10-12 21:57:09 +0000396 getopt_table[j].name = NULL;
397 getopt_table[j].has_arg = 0;
398 getopt_table[j].flag = NULL;
399 getopt_table[j].val = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400
401}
402
Greg Clayton66111032010-06-23 01:19:29 +0000403Driver::OptionData::OptionData () :
Greg Clayton8d846da2010-12-08 22:23:24 +0000404 m_args(),
Greg Clayton66111032010-06-23 01:19:29 +0000405 m_script_lang (lldb::eScriptLanguageDefault),
Johnny Cheneb46f782012-08-15 22:10:42 +0000406 m_core_file (),
Greg Claytonc982c762010-07-09 20:39:50 +0000407 m_crash_log (),
Jim Inghamed3252f2013-09-14 00:20:24 +0000408 m_initial_commands (),
409 m_after_file_commands (),
Greg Clayton66111032010-06-23 01:19:29 +0000410 m_debug_mode (false),
Jim Inghamed3252f2013-09-14 00:20:24 +0000411 m_source_quietly(false),
Greg Claytonc982c762010-07-09 20:39:50 +0000412 m_print_version (false),
Jim Inghame2231ac2012-12-21 22:22:26 +0000413 m_print_python_path (false),
Greg Clayton66111032010-06-23 01:19:29 +0000414 m_print_help (false),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000415 m_wait_for(false),
416 m_process_name(),
417 m_process_pid(LLDB_INVALID_PROCESS_ID),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000418 m_use_external_editor(false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000419 m_seen_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420{
Greg Clayton66111032010-06-23 01:19:29 +0000421}
422
423Driver::OptionData::~OptionData ()
424{
425}
426
427void
428Driver::OptionData::Clear ()
429{
Greg Clayton8d846da2010-12-08 22:23:24 +0000430 m_args.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000431 m_script_lang = lldb::eScriptLanguageDefault;
Jim Inghamed3252f2013-09-14 00:20:24 +0000432 m_initial_commands.clear ();
433 m_after_file_commands.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000434 m_debug_mode = false;
Jim Inghamed3252f2013-09-14 00:20:24 +0000435 m_source_quietly = false;
Greg Clayton66111032010-06-23 01:19:29 +0000436 m_print_help = false;
437 m_print_version = false;
Jim Inghame2231ac2012-12-21 22:22:26 +0000438 m_print_python_path = false;
Jim Inghame40e4212010-08-30 19:44:40 +0000439 m_use_external_editor = false;
Jim Inghame64f0dc2011-09-13 23:25:31 +0000440 m_wait_for = false;
441 m_process_name.erase();
442 m_process_pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton66111032010-06-23 01:19:29 +0000443}
444
445void
Jim Inghamed3252f2013-09-14 00:20:24 +0000446Driver::OptionData::AddInitialCommand (const char *command, bool before_file, bool is_file, SBError &error)
447{
448 std::vector<std::pair<bool, std::string> > *command_set;
449 if (before_file)
450 command_set = &(m_initial_commands);
451 else
452 command_set = &(m_after_file_commands);
453
454 if (is_file)
455 {
456 SBFileSpec file(command);
457 if (file.Exists())
458 command_set->push_back (std::pair<bool, std::string> (true, optarg));
459 else if (file.ResolveExecutableLocation())
460 {
461 char final_path[PATH_MAX];
462 file.GetPath (final_path, sizeof(final_path));
463 std::string path_str (final_path);
464 command_set->push_back (std::pair<bool, std::string> (true, path_str));
465 }
466 else
467 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
468 }
469 else
470 command_set->push_back (std::pair<bool, std::string> (false, optarg));
471}
472
473void
Greg Clayton66111032010-06-23 01:19:29 +0000474Driver::ResetOptionValues ()
475{
476 m_option_data.Clear ();
477}
478
479const char *
480Driver::GetFilename() const
481{
Greg Clayton8d846da2010-12-08 22:23:24 +0000482 if (m_option_data.m_args.empty())
Greg Clayton66111032010-06-23 01:19:29 +0000483 return NULL;
Greg Clayton8d846da2010-12-08 22:23:24 +0000484 return m_option_data.m_args.front().c_str();
Greg Clayton66111032010-06-23 01:19:29 +0000485}
486
487const char *
488Driver::GetCrashLogFilename() const
489{
490 if (m_option_data.m_crash_log.empty())
491 return NULL;
492 return m_option_data.m_crash_log.c_str();
493}
494
495lldb::ScriptLanguage
496Driver::GetScriptLanguage() const
497{
498 return m_option_data.m_script_lang;
499}
500
Jim Inghamed3252f2013-09-14 00:20:24 +0000501void
502Driver::ExecuteInitialCommands (bool before_file)
Greg Clayton66111032010-06-23 01:19:29 +0000503{
Jim Inghamed3252f2013-09-14 00:20:24 +0000504 size_t num_commands;
505 std::vector<std::pair<bool, std::string> > *command_set;
506 if (before_file)
507 command_set = &(m_option_data.m_initial_commands);
508 else
509 command_set = &(m_option_data.m_after_file_commands);
510
511 num_commands = command_set->size();
512 SBCommandReturnObject result;
513 bool old_async = GetDebugger().GetAsync();
514 GetDebugger().SetAsync(false);
515 for (size_t idx = 0; idx < num_commands; idx++)
516 {
517 bool is_file = (*command_set)[idx].first;
518 const char *command = (*command_set)[idx].second.c_str();
519 char command_string[PATH_MAX * 2];
520 const bool dump_stream_only_if_no_immediate = true;
521 const char *executed_command = command;
522 if (is_file)
523 {
524 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command);
525 executed_command = command_string;
526 }
527
528 m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false);
529 if (!m_option_data.m_source_quietly || result.Succeeded() == false)
530 {
531 const size_t output_size = result.GetOutputSize();
532 if (output_size > 0)
533 m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC);
534 const size_t error_size = result.GetErrorSize();
535 if (error_size > 0)
536 m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC);
537 }
538
539 if (result.Succeeded() == false)
540 {
541 char error_buffer[1024];
542 size_t error_size;
543 const char *type = before_file ? "before file" : "after_file";
544 if (is_file)
545 error_size = ::snprintf(error_buffer, sizeof(error_buffer), "Aborting %s command execution, command file: '%s' failed.\n", type, command);
546 else
547 error_size = ::snprintf(error_buffer, sizeof(error_buffer), "Aborting %s command execution, command: '%s' failed.\n", type, command);
548
549 m_io_channel_ap->OutWrite(error_buffer, error_size, NO_ASYNC);
550 break;
551 }
552 result.Clear();
553 }
554 GetDebugger().SetAsync(old_async);
Greg Clayton66111032010-06-23 01:19:29 +0000555}
556
557bool
558Driver::GetDebugMode() const
559{
560 return m_option_data.m_debug_mode;
561}
562
563
564// Check the arguments that were passed to this program to make sure they are valid and to get their
565// argument values (if any). Return a boolean value indicating whether or not to start up the full
566// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
567// if the user only wanted help or version information.
568
569SBError
Deepak Panickal429222c2013-10-15 15:46:40 +0000570Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
Greg Clayton66111032010-06-23 01:19:29 +0000571{
572 ResetOptionValues ();
573
574 SBCommandReturnObject result;
575
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576 SBError error;
577 std::string option_string;
578 struct option *long_options = NULL;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000579 std::vector<struct option> long_options_vector;
Greg Claytonc982c762010-07-09 20:39:50 +0000580 uint32_t num_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581
Greg Claytonc982c762010-07-09 20:39:50 +0000582 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
583 /* Do Nothing. */;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584
585 if (num_options == 0)
586 {
587 if (argc > 1)
588 error.SetErrorStringWithFormat ("invalid number of options");
589 return error;
590 }
591
Caroline Tice4ab31c92010-10-12 21:57:09 +0000592 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593
Caroline Tice4ab31c92010-10-12 21:57:09 +0000594 if (long_options_vector.empty())
595 long_options = NULL;
596 else
597 long_options = &long_options_vector.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598
599 if (long_options == NULL)
600 {
601 error.SetErrorStringWithFormat ("invalid long options");
602 return error;
603 }
604
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000605 // Build the option_string argument for call to getopt_long_only.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606
607 for (int i = 0; long_options[i].name != NULL; ++i)
608 {
609 if (long_options[i].flag == NULL)
610 {
611 option_string.push_back ((char) long_options[i].val);
612 switch (long_options[i].has_arg)
613 {
614 default:
615 case no_argument:
616 break;
617 case required_argument:
618 option_string.push_back (':');
619 break;
620 case optional_argument:
621 option_string.append ("::");
622 break;
623 }
624 }
625 }
626
Jim Ingham06942692011-08-13 00:22:20 +0000627 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
628 // know at that point whether we should read in init files yet. So we don't read them in in the
629 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
630 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
631 // main loop.
632
633 m_debugger.SkipLLDBInitFiles (false);
634 m_debugger.SkipAppInitFiles (false);
635
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000636 // Prepare for & make calls to getopt_long_only.
Eli Friedmanadb35022010-06-13 19:18:49 +0000637#if __GLIBC__
638 optind = 0;
639#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 optreset = 1;
641 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49 +0000642#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000643 int val;
644 while (1)
645 {
646 int long_options_index = -1;
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000647 val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000648
649 if (val == -1)
650 break;
651 else if (val == '?')
652 {
Greg Clayton66111032010-06-23 01:19:29 +0000653 m_option_data.m_print_help = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654 error.SetErrorStringWithFormat ("unknown or ambiguous option");
655 break;
656 }
657 else if (val == 0)
658 continue;
659 else
660 {
Greg Clayton66111032010-06-23 01:19:29 +0000661 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 if (long_options_index == -1)
663 {
664 for (int i = 0;
665 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
666 ++i)
667 {
668 if (long_options[i].val == val)
669 {
670 long_options_index = i;
671 break;
672 }
673 }
674 }
675
676 if (long_options_index >= 0)
677 {
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000678 const int short_option = g_options[long_options_index].short_option;
Greg Clayton66111032010-06-23 01:19:29 +0000679
680 switch (short_option)
681 {
682 case 'h':
683 m_option_data.m_print_help = true;
684 break;
685
686 case 'v':
687 m_option_data.m_print_version = true;
688 break;
689
Jim Inghame2231ac2012-12-21 22:22:26 +0000690 case 'P':
691 m_option_data.m_print_python_path = true;
692 break;
693
Greg Clayton66111032010-06-23 01:19:29 +0000694 case 'c':
Johnny Cheneb46f782012-08-15 22:10:42 +0000695 {
696 SBFileSpec file(optarg);
697 if (file.Exists())
698 {
699 m_option_data.m_core_file = optarg;
700 }
701 else
702 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
703 }
Greg Clayton66111032010-06-23 01:19:29 +0000704 break;
Johnny Cheneb46f782012-08-15 22:10:42 +0000705
Jim Inghame40e4212010-08-30 19:44:40 +0000706 case 'e':
707 m_option_data.m_use_external_editor = true;
708 break;
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000709
Jim Inghame64f0dc2011-09-13 23:25:31 +0000710 case 'x':
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000711 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham06942692011-08-13 00:22:20 +0000712 m_debugger.SkipAppInitFiles (true);
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000713 break;
714
Jim Inghamed3252f2013-09-14 00:20:24 +0000715 case 'X':
Michael Sartainc3ce7f272013-05-23 20:47:45 +0000716 m_debugger.SetUseColor (false);
717 break;
718
Greg Clayton66111032010-06-23 01:19:29 +0000719 case 'f':
720 {
721 SBFileSpec file(optarg);
722 if (file.Exists())
Greg Clayton8d846da2010-12-08 22:23:24 +0000723 {
724 m_option_data.m_args.push_back (optarg);
725 }
Caroline Tice428a9a52010-09-10 04:48:55 +0000726 else if (file.ResolveExecutableLocation())
727 {
728 char path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000729 file.GetPath (path, sizeof(path));
Greg Clayton8d846da2010-12-08 22:23:24 +0000730 m_option_data.m_args.push_back (path);
Caroline Tice428a9a52010-09-10 04:48:55 +0000731 }
Greg Clayton66111032010-06-23 01:19:29 +0000732 else
733 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
734 }
735 break;
736
737 case 'a':
738 if (!m_debugger.SetDefaultArchitecture (optarg))
739 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
740 break;
741
742 case 'l':
743 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
744 break;
745
746 case 'd':
747 m_option_data.m_debug_mode = true;
748 break;
749
Jim Inghamed3252f2013-09-14 00:20:24 +0000750 case 'q':
751 m_option_data.m_source_quietly = true;
752 break;
753
Jim Inghame64f0dc2011-09-13 23:25:31 +0000754 case 'n':
755 m_option_data.m_process_name = optarg;
756 break;
757
758 case 'w':
759 m_option_data.m_wait_for = true;
760 break;
761
762 case 'p':
763 {
764 char *remainder;
765 m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
766 if (remainder == optarg || *remainder != '\0')
767 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
768 optarg);
769 }
770 break;
Greg Clayton66111032010-06-23 01:19:29 +0000771 case 's':
Jim Inghamed3252f2013-09-14 00:20:24 +0000772 m_option_data.AddInitialCommand(optarg, false, true, error);
Greg Clayton66111032010-06-23 01:19:29 +0000773 break;
Jim Inghamed3252f2013-09-14 00:20:24 +0000774 case 'o':
775 m_option_data.AddInitialCommand(optarg, false, false, error);
776 break;
777 case 'S':
778 m_option_data.AddInitialCommand(optarg, true, true, error);
779 break;
780 case 'O':
781 m_option_data.AddInitialCommand(optarg, true, false, error);
782 break;
Greg Clayton66111032010-06-23 01:19:29 +0000783 default:
784 m_option_data.m_print_help = true;
785 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
786 break;
787 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000788 }
789 else
790 {
791 error.SetErrorStringWithFormat ("invalid option with value %i", val);
792 }
793 if (error.Fail())
Caroline Tice4ab31c92010-10-12 21:57:09 +0000794 {
Greg Clayton66111032010-06-23 01:19:29 +0000795 return error;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000796 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000797 }
798 }
Jim Ingham86511212010-06-15 18:47:14 +0000799
Greg Clayton66111032010-06-23 01:19:29 +0000800 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000801 {
802 ShowUsage (out_fh, g_options, m_option_data);
Deepak Panickal429222c2013-10-15 15:46:40 +0000803 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804 }
805 else if (m_option_data.m_print_version)
806 {
Greg Clayton66111032010-06-23 01:19:29 +0000807 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
Deepak Panickal429222c2013-10-15 15:46:40 +0000808 exiting = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000809 }
Jim Inghame2231ac2012-12-21 22:22:26 +0000810 else if (m_option_data.m_print_python_path)
811 {
812 SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
813 if (python_file_spec.IsValid())
814 {
815 char python_path[PATH_MAX];
816 size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
817 if (num_chars < PATH_MAX)
818 {
819 ::fprintf (out_fh, "%s\n", python_path);
820 }
821 else
822 ::fprintf (out_fh, "<PATH TOO LONG>\n");
823 }
824 else
825 ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
Deepak Panickal429222c2013-10-15 15:46:40 +0000826 exiting = true;
Jim Inghame2231ac2012-12-21 22:22:26 +0000827 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000828 else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 {
Greg Clayton8d846da2010-12-08 22:23:24 +0000830 // Any arguments that are left over after option parsing are for
831 // the program. If a file was specified with -f then the filename
832 // is already in the m_option_data.m_args array, and any remaining args
833 // are arguments for the inferior program. If no file was specified with
834 // -f, then what is left is the program name followed by any arguments.
835
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000836 // Skip any options we consumed with getopt_long_only
Greg Clayton8d846da2010-12-08 22:23:24 +0000837 argc -= optind;
838 argv += optind;
839
840 if (argc > 0)
841 {
842 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
843 {
844 const char *arg = argv[arg_idx];
845 if (arg)
846 m_option_data.m_args.push_back (arg);
847 }
848 }
849
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000850 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000851 else
852 {
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000853 // Skip any options we consumed with getopt_long_only
Jim Inghame64f0dc2011-09-13 23:25:31 +0000854 argc -= optind;
Greg Clayton23f59502012-07-17 03:23:13 +0000855 //argv += optind; // Commented out to keep static analyzer happy
Jim Inghame64f0dc2011-09-13 23:25:31 +0000856
857 if (argc > 0)
858 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
859 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860
Greg Clayton66111032010-06-23 01:19:29 +0000861 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000862}
863
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000864size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865Driver::GetProcessSTDOUT ()
866{
867 // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
868 char stdio_buffer[1024];
869 size_t len;
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000870 size_t total_bytes = 0;
Jim Ingham2976d002010-08-26 21:32:51 +0000871 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000872 {
Greg Claytoneea37ee2013-05-14 17:36:51 +0000873 m_io_channel_ap->OutWrite (stdio_buffer, len, NO_ASYNC);
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000874 total_bytes += len;
875 }
876 return total_bytes;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000877}
878
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000879size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000880Driver::GetProcessSTDERR ()
881{
882 // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
883 char stdio_buffer[1024];
884 size_t len;
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000885 size_t total_bytes = 0;
Jim Ingham2976d002010-08-26 21:32:51 +0000886 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000887 {
Greg Claytoneea37ee2013-05-14 17:36:51 +0000888 m_io_channel_ap->ErrWrite (stdio_buffer, len, NO_ASYNC);
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000889 total_bytes += len;
890 }
891 return total_bytes;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000892}
893
894void
Jim Ingham2976d002010-08-26 21:32:51 +0000895Driver::UpdateSelectedThread ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000896{
897 using namespace lldb;
Jim Ingham2976d002010-08-26 21:32:51 +0000898 SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000899 if (process.IsValid())
900 {
Jim Ingham2976d002010-08-26 21:32:51 +0000901 SBThread curr_thread (process.GetSelectedThread());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000902 SBThread thread;
903 StopReason curr_thread_stop_reason = eStopReasonInvalid;
904 curr_thread_stop_reason = curr_thread.GetStopReason();
905
906 if (!curr_thread.IsValid() ||
907 curr_thread_stop_reason == eStopReasonInvalid ||
908 curr_thread_stop_reason == eStopReasonNone)
909 {
910 // Prefer a thread that has just completed its plan over another thread as current thread.
911 SBThread plan_thread;
912 SBThread other_thread;
913 const size_t num_threads = process.GetNumThreads();
914 size_t i;
915 for (i = 0; i < num_threads; ++i)
916 {
917 thread = process.GetThreadAtIndex(i);
918 StopReason thread_stop_reason = thread.GetStopReason();
919 switch (thread_stop_reason)
920 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921 case eStopReasonInvalid:
922 case eStopReasonNone:
923 break;
924
925 case eStopReasonTrace:
926 case eStopReasonBreakpoint:
927 case eStopReasonWatchpoint:
928 case eStopReasonSignal:
929 case eStopReasonException:
Greg Clayton90ba8112012-12-05 00:16:59 +0000930 case eStopReasonExec:
Andrew Kaylorf85defa2012-12-20 23:08:03 +0000931 case eStopReasonThreadExiting:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932 if (!other_thread.IsValid())
933 other_thread = thread;
934 break;
935 case eStopReasonPlanComplete:
936 if (!plan_thread.IsValid())
937 plan_thread = thread;
938 break;
939 }
940 }
941 if (plan_thread.IsValid())
Jim Ingham2976d002010-08-26 21:32:51 +0000942 process.SetSelectedThread (plan_thread);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000943 else if (other_thread.IsValid())
Jim Ingham2976d002010-08-26 21:32:51 +0000944 process.SetSelectedThread (other_thread);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000945 else
946 {
947 if (curr_thread.IsValid())
948 thread = curr_thread;
949 else
950 thread = process.GetThreadAtIndex(0);
951
952 if (thread.IsValid())
Jim Ingham2976d002010-08-26 21:32:51 +0000953 process.SetSelectedThread (thread);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954 }
955 }
956 }
957}
958
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000959// This function handles events that were broadcast by the process.
960void
961Driver::HandleBreakpointEvent (const SBEvent &event)
962{
963 using namespace lldb;
964 const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
965
966 if (event_type & eBreakpointEventTypeAdded
967 || event_type & eBreakpointEventTypeRemoved
968 || event_type & eBreakpointEventTypeEnabled
969 || event_type & eBreakpointEventTypeDisabled
970 || event_type & eBreakpointEventTypeCommandChanged
971 || event_type & eBreakpointEventTypeConditionChanged
972 || event_type & eBreakpointEventTypeIgnoreChanged
973 || event_type & eBreakpointEventTypeLocationsResolved)
974 {
975 // Don't do anything about these events, since the breakpoint commands already echo these actions.
976 }
977 else if (event_type & eBreakpointEventTypeLocationsAdded)
978 {
979 char message[256];
980 uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
981 if (num_new_locations > 0)
982 {
983 SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
Jim Inghamfab10e82012-03-06 00:37:27 +0000984 int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n",
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000985 num_new_locations,
Jason Molenda65c28cb2012-09-28 01:50:47 +0000986 num_new_locations == 1 ? "" : "s",
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000987 breakpoint.GetID());
988 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
989 }
990 }
991 else if (event_type & eBreakpointEventTypeLocationsRemoved)
992 {
993 // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
994 }
995 else if (event_type & eBreakpointEventTypeLocationsResolved)
996 {
997 // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
998 }
999}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000
1001// This function handles events that were broadcast by the process.
1002void
1003Driver::HandleProcessEvent (const SBEvent &event)
1004{
1005 using namespace lldb;
1006 const uint32_t event_type = event.GetType();
1007
1008 if (event_type & SBProcess::eBroadcastBitSTDOUT)
1009 {
1010 // The process has stdout available, get it and write it out to the
1011 // appropriate place.
Caroline Tice969ed3d2011-05-02 20:41:46 +00001012 GetProcessSTDOUT ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013 }
1014 else if (event_type & SBProcess::eBroadcastBitSTDERR)
1015 {
1016 // The process has stderr available, get it and write it out to the
1017 // appropriate place.
Caroline Tice969ed3d2011-05-02 20:41:46 +00001018 GetProcessSTDERR ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019 }
1020 else if (event_type & SBProcess::eBroadcastBitStateChanged)
1021 {
1022 // Drain all stout and stderr so we don't see any output come after
1023 // we print our prompts
Caroline Tice969ed3d2011-05-02 20:41:46 +00001024 GetProcessSTDOUT ();
1025 GetProcessSTDERR ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026 // Something changed in the process; get the event and report the process's current status and location to
1027 // the user.
1028 StateType event_state = SBProcess::GetStateFromEvent (event);
1029 if (event_state == eStateInvalid)
1030 return;
1031
1032 SBProcess process (SBProcess::GetProcessFromEvent (event));
1033 assert (process.IsValid());
1034
1035 switch (event_state)
1036 {
1037 case eStateInvalid:
1038 case eStateUnloaded:
Greg Claytonb766a732011-02-04 01:58:07 +00001039 case eStateConnected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001040 case eStateAttaching:
1041 case eStateLaunching:
1042 case eStateStepping:
1043 case eStateDetached:
1044 {
1045 char message[1024];
Daniel Malead01b2952012-11-29 21:49:15 +00001046 int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(),
Greg Clayton66111032010-06-23 01:19:29 +00001047 m_debugger.StateAsCString (event_state));
Caroline Tice969ed3d2011-05-02 20:41:46 +00001048 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049 }
1050 break;
1051
1052 case eStateRunning:
1053 // Don't be chatty when we run...
1054 break;
1055
1056 case eStateExited:
Caroline Ticebd13b8d2010-09-29 18:35:42 +00001057 {
1058 SBCommandReturnObject result;
1059 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
Caroline Tice969ed3d2011-05-02 20:41:46 +00001060 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
1061 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
Caroline Ticebd13b8d2010-09-29 18:35:42 +00001062 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063 break;
1064
1065 case eStateStopped:
1066 case eStateCrashed:
1067 case eStateSuspended:
1068 // Make sure the program hasn't been auto-restarted:
1069 if (SBProcess::GetRestartedFromEvent (event))
1070 {
Jim Ingham0161b492013-02-09 01:29:05 +00001071 size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event);
1072 if (num_reasons > 0)
1073 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
Jim Ingham0161b492013-02-09 01:29:05 +00001075 if (num_reasons == 1)
1076 {
1077 char message[1024];
1078 const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0);
1079 int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n",
1080 process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>");
1081 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
1082 }
1083 else
1084 {
1085 char message[1024];
1086 int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087 process.GetProcessID());
Jim Ingham0161b492013-02-09 01:29:05 +00001088 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
1089 for (size_t i = 0; i < num_reasons; i++)
1090 {
1091 const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i);
1092 int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>");
1093 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
1094 }
1095 }
1096 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 }
1098 else
1099 {
Jim Ingham8499e1a2012-05-08 23:06:07 +00001100 if (GetDebugger().GetSelectedTarget() == process.GetTarget())
1101 {
1102 SBCommandReturnObject result;
1103 UpdateSelectedThread ();
1104 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
1105 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
1106 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
1107 }
1108 else
1109 {
1110 SBStream out_stream;
1111 uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget());
1112 if (target_idx != UINT32_MAX)
1113 out_stream.Printf ("Target %d: (", target_idx);
1114 else
1115 out_stream.Printf ("Target <unknown index>: (");
1116 process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief);
1117 out_stream.Printf (") stopped.\n");
1118 m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC);
1119 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120 }
1121 break;
1122 }
1123 }
1124}
1125
Jim Ingham4f465cf2012-10-10 18:32:14 +00001126void
1127Driver::HandleThreadEvent (const SBEvent &event)
1128{
1129 // At present the only thread event we handle is the Frame Changed event, and all we do for that is just
1130 // reprint the thread status for that thread.
1131 using namespace lldb;
1132 const uint32_t event_type = event.GetType();
Jim Inghamc3faa192012-12-11 02:31:48 +00001133 if (event_type == SBThread::eBroadcastBitStackChanged
1134 || event_type == SBThread::eBroadcastBitThreadSelected)
Jim Ingham4f465cf2012-10-10 18:32:14 +00001135 {
1136 SBThread thread = SBThread::GetThreadFromEvent (event);
1137 if (thread.IsValid())
1138 {
1139 SBStream out_stream;
1140 thread.GetStatus(out_stream);
1141 m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
1142 }
1143 }
1144}
1145
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001146// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
1147
1148bool
1149Driver::HandleIOEvent (const SBEvent &event)
1150{
1151 bool quit = false;
1152
1153 const uint32_t event_type = event.GetType();
1154
1155 if (event_type & IOChannel::eBroadcastBitHasUserInput)
1156 {
1157 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
1158 // handling.
1159
1160 const char *command_string = SBEvent::GetCStringFromEvent(event);
1161 if (command_string == NULL)
Greg Claytonc982c762010-07-09 20:39:50 +00001162 command_string = "";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163 SBCommandReturnObject result;
Jim Ingham85e8b812011-02-19 02:53:09 +00001164
Caroline Ticeb5059ac2011-05-16 19:20:50 +00001165 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
1166 // output orderings and problems with the prompt.
Greg Claytoneea37ee2013-05-14 17:36:51 +00001167
1168 // Note that we are in the process of executing a command
1169 m_executing_user_command = true;
1170
Jim Ingham85e8b812011-02-19 02:53:09 +00001171 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
1172
Greg Claytoneea37ee2013-05-14 17:36:51 +00001173 // Note that we are back from executing a user command
1174 m_executing_user_command = false;
1175
1176 // Display any STDOUT/STDERR _prior_ to emitting the command result text
1177 GetProcessSTDOUT ();
1178 GetProcessSTDERR ();
1179
Enrico Granatacd4d24d2012-10-16 20:57:12 +00001180 const bool only_if_no_immediate = true;
1181
Greg Claytoneea37ee2013-05-14 17:36:51 +00001182 // Now emit the command output text from the command we just executed
Enrico Granata430e5402012-10-16 21:11:14 +00001183 const size_t output_size = result.GetOutputSize();
Enrico Granatacd4d24d2012-10-16 20:57:12 +00001184 if (output_size > 0)
1185 m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC);
1186
Greg Claytoneea37ee2013-05-14 17:36:51 +00001187 // Now emit the command error text from the command we just executed
Enrico Granata430e5402012-10-16 21:11:14 +00001188 const size_t error_size = result.GetErrorSize();
Enrico Granatacd4d24d2012-10-16 20:57:12 +00001189 if (error_size > 0)
1190 m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC);
Caroline Ticeb5059ac2011-05-16 19:20:50 +00001191
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192 // We are done getting and running our command, we can now clear the
1193 // m_waiting_for_command so we can get another one.
1194 m_waiting_for_command = false;
1195
1196 // If our editline input reader is active, it means another input reader
1197 // got pushed onto the input reader and caused us to become deactivated.
1198 // When the input reader above us gets popped, we will get re-activated
1199 // and our prompt will refresh in our callback
1200 if (m_editline_reader.IsActive())
1201 {
1202 ReadyForCommand ();
1203 }
1204 }
1205 else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
1206 {
1207 // This is here to handle control-c interrupts from the user. It has not yet really been implemented.
1208 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER
1209 //m_io_channel_ap->CancelInput();
1210 // Anything else? Send Interrupt to process?
1211 }
1212 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1213 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1214 {
1215 // If the IOChannel thread is trying to go away, then it is definitely
1216 // time to end the debugging session.
1217 quit = true;
1218 }
1219
1220 return quit;
1221}
1222
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001223void
1224Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
1225{
1226 Driver *driver = (Driver*)baton;
1227 driver->GetFromMaster ((const char *)src, src_len);
1228}
1229
1230void
1231Driver::GetFromMaster (const char *src, size_t src_len)
1232{
1233 // Echo the characters back to the Debugger's stdout, that way if you
1234 // type characters while a command is running, you'll see what you've typed.
Greg Clayton66111032010-06-23 01:19:29 +00001235 FILE *out_fh = m_debugger.GetOutputFileHandle();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001236 if (out_fh)
1237 ::fwrite (src, 1, src_len, out_fh);
1238}
1239
1240size_t
1241Driver::EditLineInputReaderCallback
1242(
1243 void *baton,
1244 SBInputReader *reader,
1245 InputReaderAction notification,
1246 const char *bytes,
1247 size_t bytes_len
1248)
1249{
1250 Driver *driver = (Driver *)baton;
1251
1252 switch (notification)
1253 {
1254 case eInputReaderActivate:
1255 break;
1256
1257 case eInputReaderReactivate:
Greg Claytoneea37ee2013-05-14 17:36:51 +00001258 if (driver->m_executing_user_command == false)
1259 driver->ReadyForCommand();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001260 break;
1261
1262 case eInputReaderDeactivate:
1263 break;
Caroline Tice969ed3d2011-05-02 20:41:46 +00001264
1265 case eInputReaderAsynchronousOutputWritten:
1266 if (driver->m_io_channel_ap.get() != NULL)
1267 driver->m_io_channel_ap->RefreshPrompt();
1268 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269
Caroline Ticeefed6132010-11-19 20:47:54 +00001270 case eInputReaderInterrupt:
1271 if (driver->m_io_channel_ap.get() != NULL)
1272 {
Jim Inghamcfc09352012-07-27 23:57:19 +00001273 SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess());
Jim Inghamd242f1c2012-06-01 01:07:02 +00001274 if (!driver->m_io_channel_ap->EditLineHasCharacters()
Jim Inghamcfc09352012-07-27 23:57:19 +00001275 && process.IsValid()
1276 && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching))
Jim Inghamd242f1c2012-06-01 01:07:02 +00001277 {
Jim Inghamcfc09352012-07-27 23:57:19 +00001278 process.SendAsyncInterrupt ();
Jim Inghamd242f1c2012-06-01 01:07:02 +00001279 }
1280 else
1281 {
1282 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
1283 // I wish I could erase the entire input line, but there's no public API for that.
1284 driver->m_io_channel_ap->EraseCharsBeforeCursor();
1285 driver->m_io_channel_ap->RefreshPrompt();
1286 }
Caroline Ticeefed6132010-11-19 20:47:54 +00001287 }
1288 break;
1289
1290 case eInputReaderEndOfFile:
1291 if (driver->m_io_channel_ap.get() != NULL)
1292 {
Caroline Tice969ed3d2011-05-02 20:41:46 +00001293 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
Caroline Ticeefed6132010-11-19 20:47:54 +00001294 driver->m_io_channel_ap->RefreshPrompt ();
1295 }
1296 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
1297 break;
1298
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299 case eInputReaderGotToken:
1300 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
1301 break;
1302
1303 case eInputReaderDone:
1304 break;
1305 }
1306 return bytes_len;
1307}
1308
1309void
1310Driver::MainLoop ()
1311{
Deepak Panickal429222c2013-10-15 15:46:40 +00001312#if defined(_MSC_VER)
1313 m_editline_slave_fh = stdin;
1314 FILE *editline_output_slave_fh = stdout;
1315 lldb_utility::PseudoTerminal editline_output_pty;
1316#else
1317
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001318 char error_str[1024];
1319 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
1320 {
1321 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
1322 exit(1);
1323 }
1324 else
1325 {
1326 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1327 if (driver_slave_name == NULL)
1328 {
1329 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1330 exit(2);
1331 }
1332 else
1333 {
1334 m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1335 if (m_editline_slave_fh == NULL)
1336 {
1337 SBError error;
1338 error.SetErrorToErrno();
1339 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1340 error.GetCString());
1341 exit(3);
1342 }
1343
1344 ::setbuf (m_editline_slave_fh, NULL);
1345 }
1346 }
1347
Caroline Tice969ed3d2011-05-02 20:41:46 +00001348 lldb_utility::PseudoTerminal editline_output_pty;
1349 FILE *editline_output_slave_fh = NULL;
1350
1351 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
1352 {
1353 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
1354 exit(1);
1355 }
1356 else
1357 {
1358 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
1359 if (output_slave_name == NULL)
1360 {
1361 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
1362 exit(2);
1363 }
1364 else
1365 {
1366 editline_output_slave_fh = ::fopen (output_slave_name, "r+");
1367 if (editline_output_slave_fh == NULL)
1368 {
1369 SBError error;
1370 error.SetErrorToErrno();
1371 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
1372 error.GetCString());
1373 exit(3);
1374 }
1375 ::setbuf (editline_output_slave_fh, NULL);
1376 }
1377 }
Deepak Panickal429222c2013-10-15 15:46:40 +00001378#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001379
1380 // struct termios stdin_termios;
1381
1382 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
Greg Claytonf571b892012-02-02 19:28:31 +00001383 {
1384 g_old_stdin_termios_is_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001385 atexit (reset_stdin_termios);
Greg Claytonf571b892012-02-02 19:28:31 +00001386 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001387
1388 ::setbuf (stdin, NULL);
1389 ::setbuf (stdout, NULL);
1390
Greg Clayton66111032010-06-23 01:19:29 +00001391 m_debugger.SetErrorFileHandle (stderr, false);
1392 m_debugger.SetOutputFileHandle (stdout, false);
1393 m_debugger.SetInputFileHandle (stdin, true);
Jim Inghame40e4212010-08-30 19:44:40 +00001394
1395 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396
1397 // You have to drain anything that comes to the master side of the PTY. master_out_comm is
1398 // for that purpose. The reason you need to do this is a curious reason... editline will echo
1399 // characters to the PTY when it gets characters while el_gets is not running, and then when
1400 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1401 // if there are unconsumed characters in the out buffer.
1402 // However, you don't need to do anything with the characters, since editline will dump these
1403 // unconsumed characters after printing the prompt again in el_gets.
1404
Greg Claytond46c87a2010-12-04 02:39:47 +00001405 SBCommunication master_out_comm("driver.editline");
1406 master_out_comm.SetCloseOnEOF (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001407 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1408 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1409
1410 if (master_out_comm.ReadThreadStart () == false)
1411 {
1412 ::fprintf (stderr, "error: failed to start master out read thread");
1413 exit(5);
1414 }
1415
Greg Clayton66111032010-06-23 01:19:29 +00001416 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417
Caroline Tice969ed3d2011-05-02 20:41:46 +00001418 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
1419
Deepak Panickal429222c2013-10-15 15:46:40 +00001420#if !defined (_MSC_VER)
Caroline Tice969ed3d2011-05-02 20:41:46 +00001421 SBCommunication out_comm_2("driver.editline_output");
1422 out_comm_2.SetCloseOnEOF (false);
1423 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
1424 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
1425
1426 if (out_comm_2.ReadThreadStart () == false)
1427 {
1428 ::fprintf (stderr, "error: failed to start libedit output read thread");
1429 exit (5);
1430 }
Deepak Panickal429222c2013-10-15 15:46:40 +00001431#endif
Caroline Tice969ed3d2011-05-02 20:41:46 +00001432
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001433
1434 struct winsize window_size;
1435 if (isatty (STDIN_FILENO)
1436 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1437 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001438 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +00001439 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001440 }
1441
1442 // Since input can be redirected by the debugger, we must insert our editline
1443 // input reader in the queue so we know when our reader should be active
1444 // and so we can receive bytes only when we are supposed to.
Greg Clayton66111032010-06-23 01:19:29 +00001445 SBError err (m_editline_reader.Initialize (m_debugger,
1446 Driver::EditLineInputReaderCallback, // callback
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001447 this, // baton
1448 eInputReaderGranularityByte, // token_size
1449 NULL, // end token - NULL means never done
1450 NULL, // prompt - taken care of elsewhere
1451 false)); // echo input - don't need Debugger
1452 // to do this, we handle it elsewhere
1453
1454 if (err.Fail())
1455 {
1456 ::fprintf (stderr, "error: %s", err.GetCString());
1457 exit (6);
1458 }
1459
Greg Clayton66111032010-06-23 01:19:29 +00001460 m_debugger.PushInputReader (m_editline_reader);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001461
Greg Clayton66111032010-06-23 01:19:29 +00001462 SBListener listener(m_debugger.GetListener());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001463 if (listener.IsValid())
1464 {
1465
Jim Ingham4f465cf2012-10-10 18:32:14 +00001466 listener.StartListeningForEventClass(m_debugger,
1467 SBTarget::GetBroadcasterClassName(),
1468 SBTarget::eBroadcastBitBreakpointChanged);
1469 listener.StartListeningForEventClass(m_debugger,
1470 SBThread::GetBroadcasterClassName(),
Jim Inghamc3faa192012-12-11 02:31:48 +00001471 SBThread::eBroadcastBitStackChanged |
1472 SBThread::eBroadcastBitThreadSelected);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001473 listener.StartListeningForEvents (*m_io_channel_ap,
1474 IOChannel::eBroadcastBitHasUserInput |
1475 IOChannel::eBroadcastBitUserInterrupt |
1476 IOChannel::eBroadcastBitThreadShouldExit |
1477 IOChannel::eBroadcastBitThreadDidStart |
1478 IOChannel::eBroadcastBitThreadDidExit);
1479
1480 if (m_io_channel_ap->Start ())
1481 {
1482 bool iochannel_thread_exited = false;
1483
1484 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
Caroline Tice86a73f92011-05-03 20:53:11 +00001485 SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1486 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1487 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001488
1489 // Before we handle any options from the command line, we parse the
1490 // .lldbinit file in the user's home directory.
1491 SBCommandReturnObject result;
1492 sb_interpreter.SourceInitFileInHomeDirectory(result);
1493 if (GetDebugMode())
1494 {
Greg Clayton66111032010-06-23 01:19:29 +00001495 result.PutError (m_debugger.GetErrorFileHandle());
1496 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001497 }
1498
1499 // Now we handle options we got from the command line
Jim Inghamed3252f2013-09-14 00:20:24 +00001500 // First source in the commands specified to be run before the file arguments are processed.
1501 ExecuteInitialCommands(true);
1502
Johnny Cheneb46f782012-08-15 22:10:42 +00001503 // Was there a core file specified?
1504 std::string core_file_spec("");
1505 if (!m_option_data.m_core_file.empty())
1506 core_file_spec.append("--core ").append(m_option_data.m_core_file);
1507
Jim Inghamed3252f2013-09-14 00:20:24 +00001508 char command_string[PATH_MAX * 2];
Greg Clayton8d846da2010-12-08 22:23:24 +00001509 const size_t num_args = m_option_data.m_args.size();
1510 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001511 {
1512 char arch_name[64];
Greg Clayton66111032010-06-23 01:19:29 +00001513 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Greg Clayton8d846da2010-12-08 22:23:24 +00001514 ::snprintf (command_string,
1515 sizeof (command_string),
Johnny Cheneb46f782012-08-15 22:10:42 +00001516 "target create --arch=%s %s \"%s\"",
Greg Clayton8d846da2010-12-08 22:23:24 +00001517 arch_name,
Johnny Cheneb46f782012-08-15 22:10:42 +00001518 core_file_spec.c_str(),
Greg Clayton8d846da2010-12-08 22:23:24 +00001519 m_option_data.m_args[0].c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001520 else
Greg Clayton8d846da2010-12-08 22:23:24 +00001521 ::snprintf (command_string,
1522 sizeof(command_string),
Johnny Cheneb46f782012-08-15 22:10:42 +00001523 "target create %s \"%s\"",
1524 core_file_spec.c_str(),
Greg Clayton8d846da2010-12-08 22:23:24 +00001525 m_option_data.m_args[0].c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001526
Greg Clayton66111032010-06-23 01:19:29 +00001527 m_debugger.HandleCommand (command_string);
Greg Clayton8d846da2010-12-08 22:23:24 +00001528
1529 if (num_args > 1)
1530 {
Greg Clayton1d885962011-11-08 02:43:13 +00001531 m_debugger.HandleCommand ("settings clear target.run-args");
Greg Clayton8d846da2010-12-08 22:23:24 +00001532 char arg_cstr[1024];
1533 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1534 {
Jim Inghame64f0dc2011-09-13 23:25:31 +00001535 ::snprintf (arg_cstr,
1536 sizeof(arg_cstr),
Greg Clayton1d885962011-11-08 02:43:13 +00001537 "settings append target.run-args \"%s\"",
Jim Inghame64f0dc2011-09-13 23:25:31 +00001538 m_option_data.m_args[arg_idx].c_str());
Greg Clayton8d846da2010-12-08 22:23:24 +00001539 m_debugger.HandleCommand (arg_cstr);
1540 }
1541 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001542 }
Johnny Cheneb46f782012-08-15 22:10:42 +00001543 else if (!core_file_spec.empty())
1544 {
1545 ::snprintf (command_string,
1546 sizeof(command_string),
1547 "target create %s",
1548 core_file_spec.c_str());
1549 m_debugger.HandleCommand (command_string);;
1550 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001551
1552 // Now that all option parsing is done, we try and parse the .lldbinit
1553 // file in the current working directory
1554 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1555 if (GetDebugMode())
1556 {
Greg Clayton66111032010-06-23 01:19:29 +00001557 result.PutError(m_debugger.GetErrorFileHandle());
1558 result.PutOutput(m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001559 }
Jim Inghamed3252f2013-09-14 00:20:24 +00001560
1561 // Now execute the commands specified for after the file arguments are processed.
1562 ExecuteInitialCommands(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001563
1564 SBEvent event;
1565
1566 // Make sure the IO channel is started up before we try to tell it we
1567 // are ready for input
1568 listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1569 *m_io_channel_ap,
1570 IOChannel::eBroadcastBitThreadDidStart,
1571 event);
Jim Inghame64f0dc2011-09-13 23:25:31 +00001572 // If we were asked to attach, then do that here:
1573 // I'm going to use the command string rather than directly
1574 // calling the API's because then I don't have to recode the
1575 // event handling here.
1576 if (!m_option_data.m_process_name.empty()
1577 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1578 {
1579 std::string command_str("process attach ");
1580 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1581 {
1582 command_str.append("-p ");
1583 char pid_buffer[32];
Daniel Malead01b2952012-11-29 21:49:15 +00001584 ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid);
Jim Inghame64f0dc2011-09-13 23:25:31 +00001585 command_str.append(pid_buffer);
1586 }
1587 else
1588 {
1589 command_str.append("-n \"");
1590 command_str.append(m_option_data.m_process_name);
1591 command_str.push_back('\"');
1592 if (m_option_data.m_wait_for)
1593 command_str.append(" -w");
1594 }
1595
1596 if (m_debugger.GetOutputFileHandle())
1597 ::fprintf (m_debugger.GetOutputFileHandle(),
1598 "Attaching to process with:\n %s\n",
1599 command_str.c_str());
1600
1601 // Force the attach to be synchronous:
1602 bool orig_async = m_debugger.GetAsync();
1603 m_debugger.SetAsync(true);
1604 m_debugger.HandleCommand(command_str.c_str());
1605 m_debugger.SetAsync(orig_async);
1606 }
1607
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 ReadyForCommand ();
1609
Greg Claytona9f7b792012-02-29 04:21:24 +00001610 while (!GetIsDone())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001611 {
1612 listener.WaitForEvent (UINT32_MAX, event);
1613 if (event.IsValid())
1614 {
1615 if (event.GetBroadcaster().IsValid())
1616 {
1617 uint32_t event_type = event.GetType();
1618 if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1619 {
1620 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1621 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1622 {
Greg Claytona9f7b792012-02-29 04:21:24 +00001623 SetIsDone();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001624 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1625 iochannel_thread_exited = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001626 }
1627 else
Greg Claytona9f7b792012-02-29 04:21:24 +00001628 {
1629 if (HandleIOEvent (event))
1630 SetIsDone();
1631 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001632 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +00001633 else if (SBProcess::EventIsProcessEvent (event))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001634 {
1635 HandleProcessEvent (event);
1636 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +00001637 else if (SBBreakpoint::EventIsBreakpointEvent (event))
1638 {
1639 HandleBreakpointEvent (event);
1640 }
Jim Ingham4f465cf2012-10-10 18:32:14 +00001641 else if (SBThread::EventIsThreadEvent (event))
1642 {
1643 HandleThreadEvent (event);
1644 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001645 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1646 {
Greg Claytona9f7b792012-02-29 04:21:24 +00001647 // TODO: deprecate the eBroadcastBitQuitCommandReceived event
1648 // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
1649 // that can take over a command
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001650 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
Greg Clayton74d41932012-01-31 04:56:17 +00001651 {
Greg Claytona9f7b792012-02-29 04:21:24 +00001652 SetIsDone();
Greg Clayton74d41932012-01-31 04:56:17 +00001653 }
Caroline Tice86a73f92011-05-03 20:53:11 +00001654 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1655 {
1656 const char *data = SBEvent::GetCStringFromEvent (event);
1657 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1658 }
1659 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1660 {
1661 const char *data = SBEvent::GetCStringFromEvent (event);
1662 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1663 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001664 }
1665 }
1666 }
1667 }
1668
Michael Sartain816cf1d2013-05-22 23:31:28 +00001669 master_out_comm.SetReadThreadBytesReceivedCallback(NULL, NULL);
Greg Claytonf571b892012-02-02 19:28:31 +00001670 master_out_comm.Disconnect();
Michael Sartain816cf1d2013-05-22 23:31:28 +00001671 master_out_comm.ReadThreadStop();
1672
Deepak Panickal429222c2013-10-15 15:46:40 +00001673#if !defined(_MSC_VER)
Michael Sartain816cf1d2013-05-22 23:31:28 +00001674 out_comm_2.SetReadThreadBytesReceivedCallback(NULL, NULL);
Greg Claytonf571b892012-02-02 19:28:31 +00001675 out_comm_2.Disconnect();
Michael Sartain816cf1d2013-05-22 23:31:28 +00001676 out_comm_2.ReadThreadStop();
Deepak Panickal429222c2013-10-15 15:46:40 +00001677#endif
Michael Sartain816cf1d2013-05-22 23:31:28 +00001678
1679 editline_output_pty.CloseMasterFileDescriptor();
Greg Claytonf571b892012-02-02 19:28:31 +00001680 reset_stdin_termios();
1681 fclose (stdin);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001682
1683 CloseIOChannelFile ();
1684
1685 if (!iochannel_thread_exited)
1686 {
Greg Claytonb1320972010-07-14 00:18:15 +00001687 event.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001688 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1689 IOChannel::eBroadcastBitThreadDidExit,
1690 event);
1691 if (!event.IsValid())
1692 {
1693 // Send end EOF to the driver file descriptor
1694 m_io_channel_ap->Stop();
1695 }
1696 }
1697
Jim Ingham12e9a202011-09-15 21:30:02 +00001698 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001699 }
1700 }
1701}
1702
1703
1704void
1705Driver::ReadyForCommand ()
1706{
1707 if (m_waiting_for_command == false)
1708 {
1709 m_waiting_for_command = true;
1710 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1711 }
1712}
1713
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001714void
1715Driver::ResizeWindow (unsigned short col)
1716{
1717 GetDebugger().SetTerminalWidth (col);
1718 if (m_io_channel_ap.get() != NULL)
1719 {
1720 m_io_channel_ap->ElResize();
1721 }
1722}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001723
Caroline Ticedd759852010-09-09 17:45:09 +00001724void
1725sigwinch_handler (int signo)
1726{
1727 struct winsize window_size;
1728 if (isatty (STDIN_FILENO)
1729 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1730 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001731 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +00001732 {
Jim Inghamc46fe7c2013-02-22 22:56:55 +00001733 g_driver->ResizeWindow (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +00001734 }
1735 }
1736}
1737
Caroline Ticeefed6132010-11-19 20:47:54 +00001738void
1739sigint_handler (int signo)
1740{
1741 static bool g_interrupt_sent = false;
1742 if (g_driver)
1743 {
1744 if (!g_interrupt_sent)
1745 {
1746 g_interrupt_sent = true;
1747 g_driver->GetDebugger().DispatchInputInterrupt();
1748 g_interrupt_sent = false;
1749 return;
1750 }
1751 }
1752
1753 exit (signo);
1754}
1755
Jim Inghamc5917d92012-11-30 20:23:19 +00001756void
1757sigtstp_handler (int signo)
1758{
1759 g_driver->GetDebugger().SaveInputTerminalState();
1760 signal (signo, SIG_DFL);
1761 kill (getpid(), signo);
1762 signal (signo, sigtstp_handler);
1763}
1764
1765void
1766sigcont_handler (int signo)
1767{
1768 g_driver->GetDebugger().RestoreInputTerminalState();
1769 signal (signo, SIG_DFL);
1770 kill (getpid(), signo);
1771 signal (signo, sigcont_handler);
1772}
1773
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001774int
Jim Inghama462f5c2011-01-27 20:15:39 +00001775main (int argc, char const *argv[], const char *envp[])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001776{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001777 SBDebugger::Initialize();
1778
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001779 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001780
Greg Clayton3fcbed62010-10-19 03:25:40 +00001781 signal (SIGPIPE, SIG_IGN);
Caroline Ticedd759852010-09-09 17:45:09 +00001782 signal (SIGWINCH, sigwinch_handler);
Caroline Ticeefed6132010-11-19 20:47:54 +00001783 signal (SIGINT, sigint_handler);
Jim Inghamc5917d92012-11-30 20:23:19 +00001784 signal (SIGTSTP, sigtstp_handler);
1785 signal (SIGCONT, sigcont_handler);
Caroline Ticedd759852010-09-09 17:45:09 +00001786
Greg Clayton66111032010-06-23 01:19:29 +00001787 // Create a scope for driver so that the driver object will destroy itself
1788 // before SBDebugger::Terminate() is called.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001789 {
Greg Clayton66111032010-06-23 01:19:29 +00001790 Driver driver;
1791
Deepak Panickal429222c2013-10-15 15:46:40 +00001792 bool exiting = false;
1793 SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
Greg Clayton66111032010-06-23 01:19:29 +00001794 if (error.Fail())
1795 {
1796 const char *error_cstr = error.GetCString ();
1797 if (error_cstr)
1798 ::fprintf (stderr, "error: %s\n", error_cstr);
1799 }
Deepak Panickal429222c2013-10-15 15:46:40 +00001800 else if (!exiting)
Greg Clayton66111032010-06-23 01:19:29 +00001801 {
1802 driver.MainLoop ();
1803 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001804 }
1805
1806 SBDebugger::Terminate();
1807 return 0;
1808}