blob: ebd4c62d995b857ca19b72b2d00d22370ba298b0 [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
12#include <getopt.h>
13#include <libgen.h>
14#include <sys/ioctl.h>
15#include <termios.h>
16#include <unistd.h>
Eli Friedmana382d472010-06-09 09:50:17 +000017#include <string.h>
18#include <stdlib.h>
19#include <limits.h>
Eli Friedman07b16272010-06-09 19:11:30 +000020#include <fcntl.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021
22#include <string>
23
24#include "IOChannel.h"
Jim Inghame6bc6cb2012-02-08 05:23:15 +000025#include "lldb/API/SBBreakpoint.h"
Eli Friedmana382d472010-06-09 09:50:17 +000026#include "lldb/API/SBCommandInterpreter.h"
27#include "lldb/API/SBCommandReturnObject.h"
28#include "lldb/API/SBCommunication.h"
29#include "lldb/API/SBDebugger.h"
30#include "lldb/API/SBEvent.h"
31#include "lldb/API/SBHostOS.h"
32#include "lldb/API/SBListener.h"
Jim Ingham85e8b812011-02-19 02:53:09 +000033#include "lldb/API/SBStream.h"
Eli Friedmana382d472010-06-09 09:50:17 +000034#include "lldb/API/SBTarget.h"
35#include "lldb/API/SBThread.h"
36#include "lldb/API/SBProcess.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037
38using namespace lldb;
39
40static void reset_stdin_termios ();
Greg Claytonf571b892012-02-02 19:28:31 +000041static bool g_old_stdin_termios_is_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042static struct termios g_old_stdin_termios;
43
Caroline Ticedd759852010-09-09 17:45:09 +000044static char *g_debugger_name = (char *) "";
Caroline Ticeefed6132010-11-19 20:47:54 +000045static Driver *g_driver = NULL;
Caroline Ticedd759852010-09-09 17:45:09 +000046
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047// In the Driver::MainLoop, we change the terminal settings. This function is
48// added as an atexit handler to make sure we clean them up.
49static void
50reset_stdin_termios ()
51{
Greg Claytonf571b892012-02-02 19:28:31 +000052 if (g_old_stdin_termios_is_valid)
53 {
54 g_old_stdin_termios_is_valid = false;
55 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
56 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057}
58
Greg Claytone0d378b2011-03-24 21:19:54 +000059typedef struct
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060{
Greg Claytone0d378b2011-03-24 21:19:54 +000061 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
62 // then this option belongs to option set n.
63 bool required; // This option is required (in the current usage level)
64 const char * long_option; // Full name for this option.
65 char short_option; // Single character for this option.
66 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Claytonab65b342011-04-13 22:47:15 +000067 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytone0d378b2011-03-24 21:19:54 +000068 lldb::CommandArgumentType argument_type; // Type of argument this option takes
69 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
70 // pass it.
71} OptionDefinition;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072
Jim Inghame64f0dc2011-09-13 23:25:31 +000073#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
74#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
75
Greg Claytone0d378b2011-03-24 21:19:54 +000076static OptionDefinition g_options[] =
77{
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000078 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000079 "Prints out the usage information for the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000080 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000081 "Prints out the current version number of the LLDB debugger." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000082 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
Jim Ingham12e9a202011-09-15 21:30:02 +000083 "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
84 "be one of the architectures for which the program was compiled." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000085 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +000086 "Tells the debugger to use the file <filename> as the program to be debugged." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000087 { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypePath,
Johnny Cheneb46f782012-08-15 22:10:42 +000088 "Tells the debugger to use the fullpath to <path> as the core file." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000089 { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
Jim Ingham12e9a202011-09-15 21:30:02 +000090 "Tells the debugger to attach to a process with the given name." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000091 { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +000092 "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 +000093 { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
Jim Ingham12e9a202011-09-15 21:30:02 +000094 "Tells the debugger to attach to a process with the given pid." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000095 { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
Jim Ingham12e9a202011-09-15 21:30:02 +000096 "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
97 "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
98 "extensions have been implemented." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +000099 { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000100 "Tells the debugger to print out extra information for debugging itself." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000101 { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
Jim Ingham12e9a202011-09-15 21:30:02 +0000102 "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000103 { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000104 "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000105 { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
Jim Ingham12e9a202011-09-15 21:30:02 +0000106 "Do not automatically parse any '.lldbinit' files." },
Filipe Cabecinhasd0b87d82012-09-11 18:11:16 +0000107 { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108};
109
Jim Inghame64f0dc2011-09-13 23:25:31 +0000110static const uint32_t last_option_set_with_args = 2;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111
112Driver::Driver () :
113 SBBroadcaster ("Driver"),
Jim Ingham06942692011-08-13 00:22:20 +0000114 m_debugger (SBDebugger::Create(false)),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115 m_editline_pty (),
116 m_editline_slave_fh (NULL),
117 m_editline_reader (),
118 m_io_channel_ap (),
119 m_option_data (),
120 m_waiting_for_command (false)
121{
Greg Claytonfc3f0272011-05-29 04:06:55 +0000122 // We want to be able to handle CTRL+D in the terminal to have it terminate
123 // certain input
124 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticedd759852010-09-09 17:45:09 +0000125 g_debugger_name = (char *) m_debugger.GetInstanceName();
126 if (g_debugger_name == NULL)
127 g_debugger_name = (char *) "";
Caroline Ticeefed6132010-11-19 20:47:54 +0000128 g_driver = this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129}
130
131Driver::~Driver ()
132{
Caroline Ticeefed6132010-11-19 20:47:54 +0000133 g_driver = NULL;
134 g_debugger_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135}
136
137void
138Driver::CloseIOChannelFile ()
139{
Johnny Chene26c7212012-05-16 22:01:10 +0000140 // Write an End of File sequence to the file descriptor to ensure any
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 // read functions can exit.
142 char eof_str[] = "\x04";
143 ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
144
145 m_editline_pty.CloseMasterFileDescriptor();
146
147 if (m_editline_slave_fh)
148 {
149 ::fclose (m_editline_slave_fh);
150 m_editline_slave_fh = NULL;
151 }
152}
153
Greg Claytonc982c762010-07-09 20:39:50 +0000154// This function takes INDENT, which tells how many spaces to output at the front
155// of each line; TEXT, which is the text that is to be output. It outputs the
156// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
157// front of each line. It breaks lines on spaces, tabs or newlines, shortening
158// the line if necessary to not break in the middle of a word. It assumes that
159// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160
161void
Greg Claytonc982c762010-07-09 20:39:50 +0000162OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163{
164 int len = strlen (text);
165 std::string text_string (text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166
167 // Force indentation to be reasonable.
168 if (indent >= output_max_columns)
169 indent = 0;
170
171 // Will it all fit on one line?
172
173 if (len + indent < output_max_columns)
174 // Output as a single line
Greg Claytonc982c762010-07-09 20:39:50 +0000175 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 else
177 {
178 // We need to break it up into multiple lines.
179 int text_width = output_max_columns - indent - 1;
180 int start = 0;
181 int end = start;
182 int final_end = len;
183 int sub_len;
184
185 while (end < final_end)
186 {
187 // Dont start the 'text' on a space, since we're already outputting the indentation.
188 while ((start < final_end) && (text[start] == ' '))
189 start++;
190
191 end = start + text_width;
192 if (end > final_end)
193 end = final_end;
194 else
195 {
196 // If we're not at the end of the text, make sure we break the line on white space.
197 while (end > start
198 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
199 end--;
200 }
201 sub_len = end - start;
202 std::string substring = text_string.substr (start, sub_len);
Greg Claytonc982c762010-07-09 20:39:50 +0000203 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 start = end + 1;
205 }
206 }
207}
208
209void
Greg Claytone0d378b2011-03-24 21:19:54 +0000210ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211{
212 uint32_t screen_width = 80;
213 uint32_t indent_level = 0;
214 const char *name = "lldb";
Jim Ingham86511212010-06-15 18:47:14 +0000215
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216 fprintf (out, "\nUsage:\n\n");
217
218 indent_level += 2;
219
220
221 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
222 // <cmd> [options-for-level-1]
223 // etc.
224
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 uint32_t num_options;
Jim Ingham86511212010-06-15 18:47:14 +0000226 uint32_t num_option_sets = 0;
227
228 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 {
Jim Ingham86511212010-06-15 18:47:14 +0000230 uint32_t this_usage_mask = option_table[num_options].usage_mask;
231 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 {
Jim Ingham86511212010-06-15 18:47:14 +0000233 if (num_option_sets == 0)
234 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 }
236 else
237 {
Greg Claytonc982c762010-07-09 20:39:50 +0000238 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham86511212010-06-15 18:47:14 +0000239 {
240 if (this_usage_mask & 1 << j)
241 {
242 if (num_option_sets <= j)
243 num_option_sets = j + 1;
244 }
245 }
246 }
247 }
248
249 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
250 {
251 uint32_t opt_set_mask;
252
253 opt_set_mask = 1 << opt_set;
254
255 if (opt_set > 0)
256 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000257 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham556e6532011-08-16 23:15:02 +0000258 bool is_help_line = false;
Jim Ingham86511212010-06-15 18:47:14 +0000259
260 for (uint32_t i = 0; i < num_options; ++i)
261 {
262 if (option_table[i].usage_mask & opt_set_mask)
263 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000264 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000265 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham556e6532011-08-16 23:15:02 +0000266 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
267 // so we do it by hand here.
268 if (option_table[i].short_option == 'h')
269 is_help_line = true;
270
Jim Ingham86511212010-06-15 18:47:14 +0000271 if (option_table[i].required)
272 {
273 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000274 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000275 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000276 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000277 else
278 fprintf (out, " -%c", option_table[i].short_option);
279 }
280 else
281 {
282 if (option_table[i].option_has_arg == required_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000283 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000284 else if (option_table[i].option_has_arg == optional_argument)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000285 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham86511212010-06-15 18:47:14 +0000286 else
287 fprintf (out, " [-%c]", option_table[i].short_option);
288 }
289 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000291 if (!is_help_line && (opt_set <= last_option_set_with_args))
Jim Ingham556e6532011-08-16 23:15:02 +0000292 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 }
294
295 fprintf (out, "\n\n");
296
297 // Now print out all the detailed information about the various options: long form, short form and help text:
298 // -- long_name <argument>
299 // - short <argument>
300 // help text
301
302 // This variable is used to keep track of which options' info we've printed out, because some options can be in
303 // more than one usage level, but we only want to print the long form of its information once.
304
305 Driver::OptionData::OptionSet options_seen;
306 Driver::OptionData::OptionSet::iterator pos;
307
308 indent_level += 5;
309
Jim Ingham86511212010-06-15 18:47:14 +0000310 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 {
312 // Only print this option if we haven't already seen it.
313 pos = options_seen.find (option_table[i].short_option);
314 if (pos == options_seen.end())
315 {
Caroline Ticedeaab222010-10-01 19:59:14 +0000316 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Clayton9d0402b2011-02-20 02:15:07 +0000317 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Ticedeaab222010-10-01 19:59:14 +0000318
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 options_seen.insert (option_table[i].short_option);
Greg Claytonc982c762010-07-09 20:39:50 +0000320 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000321 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000322 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323 fprintf (out, "\n");
Greg Claytonc982c762010-07-09 20:39:50 +0000324 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Ticedeaab222010-10-01 19:59:14 +0000325 if (arg_type != eArgTypeNone)
Greg Clayton9d0402b2011-02-20 02:15:07 +0000326 fprintf (out, "<%s>", arg_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 fprintf (out, "\n");
328 indent_level += 5;
Greg Claytonc982c762010-07-09 20:39:50 +0000329 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 indent_level -= 5;
331 fprintf (out, "\n");
332 }
333 }
334
335 indent_level -= 5;
336
Jim Inghama9deaf92011-08-16 23:57:58 +0000337 fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
338 "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
339 "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
340 indent_level, "",
341 indent_level, "",
342 name,
343 indent_level, "");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344}
345
346void
Greg Claytone0d378b2011-03-24 21:19:54 +0000347BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Tice4ab31c92010-10-12 21:57:09 +0000348 uint32_t num_options)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349{
350 if (num_options == 0)
351 return;
352
353 uint32_t i;
354 uint32_t j;
355 std::bitset<256> option_seen;
356
Caroline Tice4ab31c92010-10-12 21:57:09 +0000357 getopt_table.resize (num_options + 1);
358
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 for (i = 0, j = 0; i < num_options; ++i)
Greg Claytonc982c762010-07-09 20:39:50 +0000360 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 char short_opt = expanded_option_table[i].short_option;
Greg Claytonc982c762010-07-09 20:39:50 +0000362
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363 if (option_seen.test(short_opt) == false)
Greg Claytonc982c762010-07-09 20:39:50 +0000364 {
Caroline Tice4ab31c92010-10-12 21:57:09 +0000365 getopt_table[j].name = expanded_option_table[i].long_option;
366 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
367 getopt_table[j].flag = NULL;
368 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 option_seen.set(short_opt);
370 ++j;
Greg Claytonc982c762010-07-09 20:39:50 +0000371 }
372 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373
Caroline Tice4ab31c92010-10-12 21:57:09 +0000374 getopt_table[j].name = NULL;
375 getopt_table[j].has_arg = 0;
376 getopt_table[j].flag = NULL;
377 getopt_table[j].val = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378
379}
380
Greg Clayton66111032010-06-23 01:19:29 +0000381Driver::OptionData::OptionData () :
Greg Clayton8d846da2010-12-08 22:23:24 +0000382 m_args(),
Greg Clayton66111032010-06-23 01:19:29 +0000383 m_script_lang (lldb::eScriptLanguageDefault),
Johnny Cheneb46f782012-08-15 22:10:42 +0000384 m_core_file (),
Greg Claytonc982c762010-07-09 20:39:50 +0000385 m_crash_log (),
Greg Clayton66111032010-06-23 01:19:29 +0000386 m_source_command_files (),
387 m_debug_mode (false),
Greg Claytonc982c762010-07-09 20:39:50 +0000388 m_print_version (false),
Greg Clayton66111032010-06-23 01:19:29 +0000389 m_print_help (false),
Jim Inghame64f0dc2011-09-13 23:25:31 +0000390 m_wait_for(false),
391 m_process_name(),
392 m_process_pid(LLDB_INVALID_PROCESS_ID),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000393 m_use_external_editor(false),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000394 m_seen_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395{
Greg Clayton66111032010-06-23 01:19:29 +0000396}
397
398Driver::OptionData::~OptionData ()
399{
400}
401
402void
403Driver::OptionData::Clear ()
404{
Greg Clayton8d846da2010-12-08 22:23:24 +0000405 m_args.clear ();
Greg Clayton66111032010-06-23 01:19:29 +0000406 m_script_lang = lldb::eScriptLanguageDefault;
407 m_source_command_files.clear ();
408 m_debug_mode = false;
409 m_print_help = false;
410 m_print_version = false;
Jim Inghame40e4212010-08-30 19:44:40 +0000411 m_use_external_editor = false;
Jim Inghame64f0dc2011-09-13 23:25:31 +0000412 m_wait_for = false;
413 m_process_name.erase();
414 m_process_pid = LLDB_INVALID_PROCESS_ID;
Greg Clayton66111032010-06-23 01:19:29 +0000415}
416
417void
418Driver::ResetOptionValues ()
419{
420 m_option_data.Clear ();
421}
422
423const char *
424Driver::GetFilename() const
425{
Greg Clayton8d846da2010-12-08 22:23:24 +0000426 if (m_option_data.m_args.empty())
Greg Clayton66111032010-06-23 01:19:29 +0000427 return NULL;
Greg Clayton8d846da2010-12-08 22:23:24 +0000428 return m_option_data.m_args.front().c_str();
Greg Clayton66111032010-06-23 01:19:29 +0000429}
430
431const char *
432Driver::GetCrashLogFilename() const
433{
434 if (m_option_data.m_crash_log.empty())
435 return NULL;
436 return m_option_data.m_crash_log.c_str();
437}
438
439lldb::ScriptLanguage
440Driver::GetScriptLanguage() const
441{
442 return m_option_data.m_script_lang;
443}
444
445size_t
446Driver::GetNumSourceCommandFiles () const
447{
448 return m_option_data.m_source_command_files.size();
449}
450
451const char *
452Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
453{
454 if (idx < m_option_data.m_source_command_files.size())
455 return m_option_data.m_source_command_files[idx].c_str();
456 return NULL;
457}
458
459bool
460Driver::GetDebugMode() const
461{
462 return m_option_data.m_debug_mode;
463}
464
465
466// Check the arguments that were passed to this program to make sure they are valid and to get their
467// argument values (if any). Return a boolean value indicating whether or not to start up the full
468// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
469// if the user only wanted help or version information.
470
471SBError
472Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
473{
474 ResetOptionValues ();
475
476 SBCommandReturnObject result;
477
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 SBError error;
479 std::string option_string;
480 struct option *long_options = NULL;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000481 std::vector<struct option> long_options_vector;
Greg Claytonc982c762010-07-09 20:39:50 +0000482 uint32_t num_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483
Greg Claytonc982c762010-07-09 20:39:50 +0000484 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
485 /* Do Nothing. */;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486
487 if (num_options == 0)
488 {
489 if (argc > 1)
490 error.SetErrorStringWithFormat ("invalid number of options");
491 return error;
492 }
493
Caroline Tice4ab31c92010-10-12 21:57:09 +0000494 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495
Caroline Tice4ab31c92010-10-12 21:57:09 +0000496 if (long_options_vector.empty())
497 long_options = NULL;
498 else
499 long_options = &long_options_vector.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500
501 if (long_options == NULL)
502 {
503 error.SetErrorStringWithFormat ("invalid long options");
504 return error;
505 }
506
507 // Build the option_string argument for call to getopt_long.
508
509 for (int i = 0; long_options[i].name != NULL; ++i)
510 {
511 if (long_options[i].flag == NULL)
512 {
513 option_string.push_back ((char) long_options[i].val);
514 switch (long_options[i].has_arg)
515 {
516 default:
517 case no_argument:
518 break;
519 case required_argument:
520 option_string.push_back (':');
521 break;
522 case optional_argument:
523 option_string.append ("::");
524 break;
525 }
526 }
527 }
528
Jim Ingham06942692011-08-13 00:22:20 +0000529 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
530 // know at that point whether we should read in init files yet. So we don't read them in in the
531 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
532 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
533 // main loop.
534
535 m_debugger.SkipLLDBInitFiles (false);
536 m_debugger.SkipAppInitFiles (false);
537
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 // Prepare for & make calls to getopt_long.
Eli Friedmanadb35022010-06-13 19:18:49 +0000539#if __GLIBC__
540 optind = 0;
541#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542 optreset = 1;
543 optind = 1;
Eli Friedmanadb35022010-06-13 19:18:49 +0000544#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000545 int val;
546 while (1)
547 {
548 int long_options_index = -1;
Greg Claytonc982c762010-07-09 20:39:50 +0000549 val = ::getopt_long (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550
551 if (val == -1)
552 break;
553 else if (val == '?')
554 {
Greg Clayton66111032010-06-23 01:19:29 +0000555 m_option_data.m_print_help = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 error.SetErrorStringWithFormat ("unknown or ambiguous option");
557 break;
558 }
559 else if (val == 0)
560 continue;
561 else
562 {
Greg Clayton66111032010-06-23 01:19:29 +0000563 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 if (long_options_index == -1)
565 {
566 for (int i = 0;
567 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
568 ++i)
569 {
570 if (long_options[i].val == val)
571 {
572 long_options_index = i;
573 break;
574 }
575 }
576 }
577
578 if (long_options_index >= 0)
579 {
Greg Clayton66111032010-06-23 01:19:29 +0000580 const char short_option = (char) g_options[long_options_index].short_option;
581
582 switch (short_option)
583 {
584 case 'h':
585 m_option_data.m_print_help = true;
586 break;
587
588 case 'v':
589 m_option_data.m_print_version = true;
590 break;
591
592 case 'c':
Johnny Cheneb46f782012-08-15 22:10:42 +0000593 {
594 SBFileSpec file(optarg);
595 if (file.Exists())
596 {
597 m_option_data.m_core_file = optarg;
598 }
599 else
600 error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
601 }
Greg Clayton66111032010-06-23 01:19:29 +0000602 break;
Johnny Cheneb46f782012-08-15 22:10:42 +0000603
Jim Inghame40e4212010-08-30 19:44:40 +0000604 case 'e':
605 m_option_data.m_use_external_editor = true;
606 break;
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000607
Jim Inghame64f0dc2011-09-13 23:25:31 +0000608 case 'x':
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000609 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham06942692011-08-13 00:22:20 +0000610 m_debugger.SkipAppInitFiles (true);
Greg Clayton6eee5aa2010-10-11 01:05:37 +0000611 break;
612
Greg Clayton66111032010-06-23 01:19:29 +0000613 case 'f':
614 {
615 SBFileSpec file(optarg);
616 if (file.Exists())
Greg Clayton8d846da2010-12-08 22:23:24 +0000617 {
618 m_option_data.m_args.push_back (optarg);
619 }
Caroline Tice428a9a52010-09-10 04:48:55 +0000620 else if (file.ResolveExecutableLocation())
621 {
622 char path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000623 file.GetPath (path, sizeof(path));
Greg Clayton8d846da2010-12-08 22:23:24 +0000624 m_option_data.m_args.push_back (path);
Caroline Tice428a9a52010-09-10 04:48:55 +0000625 }
Greg Clayton66111032010-06-23 01:19:29 +0000626 else
627 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
628 }
629 break;
630
631 case 'a':
632 if (!m_debugger.SetDefaultArchitecture (optarg))
633 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
634 break;
635
636 case 'l':
637 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
638 break;
639
640 case 'd':
641 m_option_data.m_debug_mode = true;
642 break;
643
Jim Inghame64f0dc2011-09-13 23:25:31 +0000644 case 'n':
645 m_option_data.m_process_name = optarg;
646 break;
647
648 case 'w':
649 m_option_data.m_wait_for = true;
650 break;
651
652 case 'p':
653 {
654 char *remainder;
655 m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
656 if (remainder == optarg || *remainder != '\0')
657 error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
658 optarg);
659 }
660 break;
Greg Clayton66111032010-06-23 01:19:29 +0000661 case 's':
662 {
663 SBFileSpec file(optarg);
664 if (file.Exists())
665 m_option_data.m_source_command_files.push_back (optarg);
Caroline Tice428a9a52010-09-10 04:48:55 +0000666 else if (file.ResolveExecutableLocation())
667 {
668 char final_path[PATH_MAX];
Johnny Chen25f3a3c2011-08-10 22:06:24 +0000669 file.GetPath (final_path, sizeof(final_path));
Caroline Tice428a9a52010-09-10 04:48:55 +0000670 std::string path_str (final_path);
671 m_option_data.m_source_command_files.push_back (path_str);
672 }
Greg Clayton66111032010-06-23 01:19:29 +0000673 else
674 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
675 }
676 break;
677
678 default:
679 m_option_data.m_print_help = true;
680 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
681 break;
682 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000683 }
684 else
685 {
686 error.SetErrorStringWithFormat ("invalid option with value %i", val);
687 }
688 if (error.Fail())
Caroline Tice4ab31c92010-10-12 21:57:09 +0000689 {
Greg Clayton66111032010-06-23 01:19:29 +0000690 return error;
Caroline Tice4ab31c92010-10-12 21:57:09 +0000691 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692 }
693 }
Jim Ingham86511212010-06-15 18:47:14 +0000694
Greg Clayton66111032010-06-23 01:19:29 +0000695 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 {
697 ShowUsage (out_fh, g_options, m_option_data);
Greg Claytone46dd322010-10-11 01:13:37 +0000698 exit = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699 }
700 else if (m_option_data.m_print_version)
701 {
Greg Clayton66111032010-06-23 01:19:29 +0000702 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
703 exit = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000705 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 +0000706 {
Greg Clayton8d846da2010-12-08 22:23:24 +0000707 // Any arguments that are left over after option parsing are for
708 // the program. If a file was specified with -f then the filename
709 // is already in the m_option_data.m_args array, and any remaining args
710 // are arguments for the inferior program. If no file was specified with
711 // -f, then what is left is the program name followed by any arguments.
712
713 // Skip any options we consumed with getopt_long
714 argc -= optind;
715 argv += optind;
716
717 if (argc > 0)
718 {
719 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
720 {
721 const char *arg = argv[arg_idx];
722 if (arg)
723 m_option_data.m_args.push_back (arg);
724 }
725 }
726
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727 }
Jim Inghame64f0dc2011-09-13 23:25:31 +0000728 else
729 {
730 // Skip any options we consumed with getopt_long
731 argc -= optind;
Greg Clayton23f59502012-07-17 03:23:13 +0000732 //argv += optind; // Commented out to keep static analyzer happy
Jim Inghame64f0dc2011-09-13 23:25:31 +0000733
734 if (argc > 0)
735 ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
736 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737
Greg Clayton66111032010-06-23 01:19:29 +0000738 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739}
740
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000741size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742Driver::GetProcessSTDOUT ()
743{
744 // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
745 char stdio_buffer[1024];
746 size_t len;
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000747 size_t total_bytes = 0;
Jim Ingham2976d002010-08-26 21:32:51 +0000748 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000749 {
Caroline Tice969ed3d2011-05-02 20:41:46 +0000750 m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC);
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000751 total_bytes += len;
752 }
753 return total_bytes;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754}
755
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000756size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757Driver::GetProcessSTDERR ()
758{
759 // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
760 char stdio_buffer[1024];
761 size_t len;
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000762 size_t total_bytes = 0;
Jim Ingham2976d002010-08-26 21:32:51 +0000763 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000764 {
Caroline Tice969ed3d2011-05-02 20:41:46 +0000765 m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC);
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000766 total_bytes += len;
767 }
768 return total_bytes;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000769}
770
771void
Jim Ingham2976d002010-08-26 21:32:51 +0000772Driver::UpdateSelectedThread ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773{
774 using namespace lldb;
Jim Ingham2976d002010-08-26 21:32:51 +0000775 SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 if (process.IsValid())
777 {
Jim Ingham2976d002010-08-26 21:32:51 +0000778 SBThread curr_thread (process.GetSelectedThread());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779 SBThread thread;
780 StopReason curr_thread_stop_reason = eStopReasonInvalid;
781 curr_thread_stop_reason = curr_thread.GetStopReason();
782
783 if (!curr_thread.IsValid() ||
784 curr_thread_stop_reason == eStopReasonInvalid ||
785 curr_thread_stop_reason == eStopReasonNone)
786 {
787 // Prefer a thread that has just completed its plan over another thread as current thread.
788 SBThread plan_thread;
789 SBThread other_thread;
790 const size_t num_threads = process.GetNumThreads();
791 size_t i;
792 for (i = 0; i < num_threads; ++i)
793 {
794 thread = process.GetThreadAtIndex(i);
795 StopReason thread_stop_reason = thread.GetStopReason();
796 switch (thread_stop_reason)
797 {
798 default:
799 case eStopReasonInvalid:
800 case eStopReasonNone:
801 break;
802
803 case eStopReasonTrace:
804 case eStopReasonBreakpoint:
805 case eStopReasonWatchpoint:
806 case eStopReasonSignal:
807 case eStopReasonException:
808 if (!other_thread.IsValid())
809 other_thread = thread;
810 break;
811 case eStopReasonPlanComplete:
812 if (!plan_thread.IsValid())
813 plan_thread = thread;
814 break;
815 }
816 }
817 if (plan_thread.IsValid())
Jim Ingham2976d002010-08-26 21:32:51 +0000818 process.SetSelectedThread (plan_thread);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819 else if (other_thread.IsValid())
Jim Ingham2976d002010-08-26 21:32:51 +0000820 process.SetSelectedThread (other_thread);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821 else
822 {
823 if (curr_thread.IsValid())
824 thread = curr_thread;
825 else
826 thread = process.GetThreadAtIndex(0);
827
828 if (thread.IsValid())
Jim Ingham2976d002010-08-26 21:32:51 +0000829 process.SetSelectedThread (thread);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000830 }
831 }
832 }
833}
834
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000835// This function handles events that were broadcast by the process.
836void
837Driver::HandleBreakpointEvent (const SBEvent &event)
838{
839 using namespace lldb;
840 const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
841
842 if (event_type & eBreakpointEventTypeAdded
843 || event_type & eBreakpointEventTypeRemoved
844 || event_type & eBreakpointEventTypeEnabled
845 || event_type & eBreakpointEventTypeDisabled
846 || event_type & eBreakpointEventTypeCommandChanged
847 || event_type & eBreakpointEventTypeConditionChanged
848 || event_type & eBreakpointEventTypeIgnoreChanged
849 || event_type & eBreakpointEventTypeLocationsResolved)
850 {
851 // Don't do anything about these events, since the breakpoint commands already echo these actions.
852 }
853 else if (event_type & eBreakpointEventTypeLocationsAdded)
854 {
855 char message[256];
856 uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
857 if (num_new_locations > 0)
858 {
859 SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
Jim Inghamfab10e82012-03-06 00:37:27 +0000860 int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n",
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000861 num_new_locations,
Jason Molenda65c28cb2012-09-28 01:50:47 +0000862 num_new_locations == 1 ? "" : "s",
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000863 breakpoint.GetID());
864 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
865 }
866 }
867 else if (event_type & eBreakpointEventTypeLocationsRemoved)
868 {
869 // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
870 }
871 else if (event_type & eBreakpointEventTypeLocationsResolved)
872 {
873 // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
874 }
875}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000876
877// This function handles events that were broadcast by the process.
878void
879Driver::HandleProcessEvent (const SBEvent &event)
880{
881 using namespace lldb;
882 const uint32_t event_type = event.GetType();
883
884 if (event_type & SBProcess::eBroadcastBitSTDOUT)
885 {
886 // The process has stdout available, get it and write it out to the
887 // appropriate place.
Caroline Tice969ed3d2011-05-02 20:41:46 +0000888 GetProcessSTDOUT ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000889 }
890 else if (event_type & SBProcess::eBroadcastBitSTDERR)
891 {
892 // The process has stderr available, get it and write it out to the
893 // appropriate place.
Caroline Tice969ed3d2011-05-02 20:41:46 +0000894 GetProcessSTDERR ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000895 }
896 else if (event_type & SBProcess::eBroadcastBitStateChanged)
897 {
898 // Drain all stout and stderr so we don't see any output come after
899 // we print our prompts
Caroline Tice969ed3d2011-05-02 20:41:46 +0000900 GetProcessSTDOUT ();
901 GetProcessSTDERR ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000902 // Something changed in the process; get the event and report the process's current status and location to
903 // the user.
904 StateType event_state = SBProcess::GetStateFromEvent (event);
905 if (event_state == eStateInvalid)
906 return;
907
908 SBProcess process (SBProcess::GetProcessFromEvent (event));
909 assert (process.IsValid());
910
911 switch (event_state)
912 {
913 case eStateInvalid:
914 case eStateUnloaded:
Greg Claytonb766a732011-02-04 01:58:07 +0000915 case eStateConnected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 case eStateAttaching:
917 case eStateLaunching:
918 case eStateStepping:
919 case eStateDetached:
920 {
921 char message[1024];
Greg Clayton61e7a582011-12-01 23:28:38 +0000922 int message_len = ::snprintf (message, sizeof(message), "Process %llu %s\n", process.GetProcessID(),
Greg Clayton66111032010-06-23 01:19:29 +0000923 m_debugger.StateAsCString (event_state));
Caroline Tice969ed3d2011-05-02 20:41:46 +0000924 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925 }
926 break;
927
928 case eStateRunning:
929 // Don't be chatty when we run...
930 break;
931
932 case eStateExited:
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000933 {
934 SBCommandReturnObject result;
935 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
Caroline Tice969ed3d2011-05-02 20:41:46 +0000936 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
937 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
Caroline Ticebd13b8d2010-09-29 18:35:42 +0000938 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939 break;
940
941 case eStateStopped:
942 case eStateCrashed:
943 case eStateSuspended:
944 // Make sure the program hasn't been auto-restarted:
945 if (SBProcess::GetRestartedFromEvent (event))
946 {
947 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
948 char message[1024];
Greg Clayton61e7a582011-12-01 23:28:38 +0000949 int message_len = ::snprintf (message, sizeof(message), "Process %llu stopped and was programmatically restarted.\n",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950 process.GetProcessID());
Caroline Tice969ed3d2011-05-02 20:41:46 +0000951 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000952 }
953 else
954 {
Jim Ingham8499e1a2012-05-08 23:06:07 +0000955 if (GetDebugger().GetSelectedTarget() == process.GetTarget())
956 {
957 SBCommandReturnObject result;
958 UpdateSelectedThread ();
959 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
960 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
961 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
962 }
963 else
964 {
965 SBStream out_stream;
966 uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget());
967 if (target_idx != UINT32_MAX)
968 out_stream.Printf ("Target %d: (", target_idx);
969 else
970 out_stream.Printf ("Target <unknown index>: (");
971 process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief);
972 out_stream.Printf (") stopped.\n");
973 m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC);
974 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975 }
976 break;
977 }
978 }
979}
980
Jim Ingham4f465cf2012-10-10 18:32:14 +0000981void
982Driver::HandleThreadEvent (const SBEvent &event)
983{
984 // At present the only thread event we handle is the Frame Changed event, and all we do for that is just
985 // reprint the thread status for that thread.
986 using namespace lldb;
987 const uint32_t event_type = event.GetType();
988 if (event_type == SBThread::eBroadcastBitStackChanged)
989 {
990 SBThread thread = SBThread::GetThreadFromEvent (event);
991 if (thread.IsValid())
992 {
993 SBStream out_stream;
994 thread.GetStatus(out_stream);
995 m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
996 }
997 }
998}
999
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
1001
1002bool
1003Driver::HandleIOEvent (const SBEvent &event)
1004{
1005 bool quit = false;
1006
1007 const uint32_t event_type = event.GetType();
1008
1009 if (event_type & IOChannel::eBroadcastBitHasUserInput)
1010 {
1011 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
1012 // handling.
1013
1014 const char *command_string = SBEvent::GetCStringFromEvent(event);
1015 if (command_string == NULL)
Greg Claytonc982c762010-07-09 20:39:50 +00001016 command_string = "";
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 SBCommandReturnObject result;
Jim Ingham85e8b812011-02-19 02:53:09 +00001018
Caroline Ticeb5059ac2011-05-16 19:20:50 +00001019 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
1020 // output orderings and problems with the prompt.
Jim Ingham85e8b812011-02-19 02:53:09 +00001021 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
1022
Enrico Granatacd4d24d2012-10-16 20:57:12 +00001023 const bool only_if_no_immediate = true;
1024
Enrico Granata430e5402012-10-16 21:11:14 +00001025 const size_t output_size = result.GetOutputSize();
Enrico Granatacd4d24d2012-10-16 20:57:12 +00001026
1027 if (output_size > 0)
1028 m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC);
1029
Enrico Granata430e5402012-10-16 21:11:14 +00001030 const size_t error_size = result.GetErrorSize();
Enrico Granatacd4d24d2012-10-16 20:57:12 +00001031
1032 if (error_size > 0)
1033 m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC);
Caroline Ticeb5059ac2011-05-16 19:20:50 +00001034
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035 // We are done getting and running our command, we can now clear the
1036 // m_waiting_for_command so we can get another one.
1037 m_waiting_for_command = false;
1038
1039 // If our editline input reader is active, it means another input reader
1040 // got pushed onto the input reader and caused us to become deactivated.
1041 // When the input reader above us gets popped, we will get re-activated
1042 // and our prompt will refresh in our callback
1043 if (m_editline_reader.IsActive())
1044 {
1045 ReadyForCommand ();
1046 }
1047 }
1048 else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
1049 {
1050 // This is here to handle control-c interrupts from the user. It has not yet really been implemented.
1051 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER
1052 //m_io_channel_ap->CancelInput();
1053 // Anything else? Send Interrupt to process?
1054 }
1055 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1056 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1057 {
1058 // If the IOChannel thread is trying to go away, then it is definitely
1059 // time to end the debugging session.
1060 quit = true;
1061 }
1062
1063 return quit;
1064}
1065
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066void
1067Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
1068{
1069 Driver *driver = (Driver*)baton;
1070 driver->GetFromMaster ((const char *)src, src_len);
1071}
1072
1073void
1074Driver::GetFromMaster (const char *src, size_t src_len)
1075{
1076 // Echo the characters back to the Debugger's stdout, that way if you
1077 // type characters while a command is running, you'll see what you've typed.
Greg Clayton66111032010-06-23 01:19:29 +00001078 FILE *out_fh = m_debugger.GetOutputFileHandle();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079 if (out_fh)
1080 ::fwrite (src, 1, src_len, out_fh);
1081}
1082
1083size_t
1084Driver::EditLineInputReaderCallback
1085(
1086 void *baton,
1087 SBInputReader *reader,
1088 InputReaderAction notification,
1089 const char *bytes,
1090 size_t bytes_len
1091)
1092{
1093 Driver *driver = (Driver *)baton;
1094
1095 switch (notification)
1096 {
1097 case eInputReaderActivate:
1098 break;
1099
1100 case eInputReaderReactivate:
1101 driver->ReadyForCommand();
1102 break;
1103
1104 case eInputReaderDeactivate:
1105 break;
Caroline Tice969ed3d2011-05-02 20:41:46 +00001106
1107 case eInputReaderAsynchronousOutputWritten:
1108 if (driver->m_io_channel_ap.get() != NULL)
1109 driver->m_io_channel_ap->RefreshPrompt();
1110 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111
Caroline Ticeefed6132010-11-19 20:47:54 +00001112 case eInputReaderInterrupt:
1113 if (driver->m_io_channel_ap.get() != NULL)
1114 {
Jim Inghamcfc09352012-07-27 23:57:19 +00001115 SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess());
Jim Inghamd242f1c2012-06-01 01:07:02 +00001116 if (!driver->m_io_channel_ap->EditLineHasCharacters()
Jim Inghamcfc09352012-07-27 23:57:19 +00001117 && process.IsValid()
1118 && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching))
Jim Inghamd242f1c2012-06-01 01:07:02 +00001119 {
Jim Inghamcfc09352012-07-27 23:57:19 +00001120 process.SendAsyncInterrupt ();
Jim Inghamd242f1c2012-06-01 01:07:02 +00001121 }
1122 else
1123 {
1124 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
1125 // I wish I could erase the entire input line, but there's no public API for that.
1126 driver->m_io_channel_ap->EraseCharsBeforeCursor();
1127 driver->m_io_channel_ap->RefreshPrompt();
1128 }
Caroline Ticeefed6132010-11-19 20:47:54 +00001129 }
1130 break;
1131
1132 case eInputReaderEndOfFile:
1133 if (driver->m_io_channel_ap.get() != NULL)
1134 {
Caroline Tice969ed3d2011-05-02 20:41:46 +00001135 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
Caroline Ticeefed6132010-11-19 20:47:54 +00001136 driver->m_io_channel_ap->RefreshPrompt ();
1137 }
1138 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
1139 break;
1140
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001141 case eInputReaderGotToken:
1142 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
1143 break;
1144
1145 case eInputReaderDone:
1146 break;
1147 }
1148 return bytes_len;
1149}
1150
1151void
1152Driver::MainLoop ()
1153{
1154 char error_str[1024];
1155 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
1156 {
1157 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
1158 exit(1);
1159 }
1160 else
1161 {
1162 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1163 if (driver_slave_name == NULL)
1164 {
1165 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1166 exit(2);
1167 }
1168 else
1169 {
1170 m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1171 if (m_editline_slave_fh == NULL)
1172 {
1173 SBError error;
1174 error.SetErrorToErrno();
1175 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1176 error.GetCString());
1177 exit(3);
1178 }
1179
1180 ::setbuf (m_editline_slave_fh, NULL);
1181 }
1182 }
1183
Caroline Tice969ed3d2011-05-02 20:41:46 +00001184 lldb_utility::PseudoTerminal editline_output_pty;
1185 FILE *editline_output_slave_fh = NULL;
1186
1187 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
1188 {
1189 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
1190 exit(1);
1191 }
1192 else
1193 {
1194 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
1195 if (output_slave_name == NULL)
1196 {
1197 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
1198 exit(2);
1199 }
1200 else
1201 {
1202 editline_output_slave_fh = ::fopen (output_slave_name, "r+");
1203 if (editline_output_slave_fh == NULL)
1204 {
1205 SBError error;
1206 error.SetErrorToErrno();
1207 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
1208 error.GetCString());
1209 exit(3);
1210 }
1211 ::setbuf (editline_output_slave_fh, NULL);
1212 }
1213 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214
1215 // struct termios stdin_termios;
1216
1217 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
Greg Claytonf571b892012-02-02 19:28:31 +00001218 {
1219 g_old_stdin_termios_is_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001220 atexit (reset_stdin_termios);
Greg Claytonf571b892012-02-02 19:28:31 +00001221 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222
1223 ::setbuf (stdin, NULL);
1224 ::setbuf (stdout, NULL);
1225
Greg Clayton66111032010-06-23 01:19:29 +00001226 m_debugger.SetErrorFileHandle (stderr, false);
1227 m_debugger.SetOutputFileHandle (stdout, false);
1228 m_debugger.SetInputFileHandle (stdin, true);
Jim Inghame40e4212010-08-30 19:44:40 +00001229
1230 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231
1232 // You have to drain anything that comes to the master side of the PTY. master_out_comm is
1233 // for that purpose. The reason you need to do this is a curious reason... editline will echo
1234 // characters to the PTY when it gets characters while el_gets is not running, and then when
1235 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1236 // if there are unconsumed characters in the out buffer.
1237 // However, you don't need to do anything with the characters, since editline will dump these
1238 // unconsumed characters after printing the prompt again in el_gets.
1239
Greg Claytond46c87a2010-12-04 02:39:47 +00001240 SBCommunication master_out_comm("driver.editline");
1241 master_out_comm.SetCloseOnEOF (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001242 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1243 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1244
1245 if (master_out_comm.ReadThreadStart () == false)
1246 {
1247 ::fprintf (stderr, "error: failed to start master out read thread");
1248 exit(5);
1249 }
1250
Greg Clayton66111032010-06-23 01:19:29 +00001251 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001252
Caroline Tice969ed3d2011-05-02 20:41:46 +00001253 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
1254
1255 SBCommunication out_comm_2("driver.editline_output");
1256 out_comm_2.SetCloseOnEOF (false);
1257 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
1258 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
1259
1260 if (out_comm_2.ReadThreadStart () == false)
1261 {
1262 ::fprintf (stderr, "error: failed to start libedit output read thread");
1263 exit (5);
1264 }
1265
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266
1267 struct winsize window_size;
1268 if (isatty (STDIN_FILENO)
1269 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1270 {
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001271 if (window_size.ws_col > 0)
Greg Claytona7015092010-09-18 01:14:36 +00001272 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001273 }
1274
1275 // Since input can be redirected by the debugger, we must insert our editline
1276 // input reader in the queue so we know when our reader should be active
1277 // and so we can receive bytes only when we are supposed to.
Greg Clayton66111032010-06-23 01:19:29 +00001278 SBError err (m_editline_reader.Initialize (m_debugger,
1279 Driver::EditLineInputReaderCallback, // callback
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001280 this, // baton
1281 eInputReaderGranularityByte, // token_size
1282 NULL, // end token - NULL means never done
1283 NULL, // prompt - taken care of elsewhere
1284 false)); // echo input - don't need Debugger
1285 // to do this, we handle it elsewhere
1286
1287 if (err.Fail())
1288 {
1289 ::fprintf (stderr, "error: %s", err.GetCString());
1290 exit (6);
1291 }
1292
Greg Clayton66111032010-06-23 01:19:29 +00001293 m_debugger.PushInputReader (m_editline_reader);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294
Greg Clayton66111032010-06-23 01:19:29 +00001295 SBListener listener(m_debugger.GetListener());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296 if (listener.IsValid())
1297 {
1298
Jim Ingham4f465cf2012-10-10 18:32:14 +00001299 listener.StartListeningForEventClass(m_debugger,
1300 SBTarget::GetBroadcasterClassName(),
1301 SBTarget::eBroadcastBitBreakpointChanged);
1302 listener.StartListeningForEventClass(m_debugger,
1303 SBThread::GetBroadcasterClassName(),
1304 SBThread::eBroadcastBitStackChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001305 listener.StartListeningForEvents (*m_io_channel_ap,
1306 IOChannel::eBroadcastBitHasUserInput |
1307 IOChannel::eBroadcastBitUserInterrupt |
1308 IOChannel::eBroadcastBitThreadShouldExit |
1309 IOChannel::eBroadcastBitThreadDidStart |
1310 IOChannel::eBroadcastBitThreadDidExit);
1311
1312 if (m_io_channel_ap->Start ())
1313 {
1314 bool iochannel_thread_exited = false;
1315
1316 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
Caroline Tice86a73f92011-05-03 20:53:11 +00001317 SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1318 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1319 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001320
1321 // Before we handle any options from the command line, we parse the
1322 // .lldbinit file in the user's home directory.
1323 SBCommandReturnObject result;
1324 sb_interpreter.SourceInitFileInHomeDirectory(result);
1325 if (GetDebugMode())
1326 {
Greg Clayton66111032010-06-23 01:19:29 +00001327 result.PutError (m_debugger.GetErrorFileHandle());
1328 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001329 }
1330
1331 // Now we handle options we got from the command line
1332 char command_string[PATH_MAX * 2];
1333 const size_t num_source_command_files = GetNumSourceCommandFiles();
1334 if (num_source_command_files > 0)
1335 {
1336 for (size_t i=0; i < num_source_command_files; ++i)
1337 {
1338 const char *command_file = GetSourceCommandFileAtIndex(i);
Johnny Chen85ffddc2010-07-28 21:16:11 +00001339 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
Greg Clayton66111032010-06-23 01:19:29 +00001340 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001341 if (GetDebugMode())
1342 {
Greg Clayton66111032010-06-23 01:19:29 +00001343 result.PutError (m_debugger.GetErrorFileHandle());
1344 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001345 }
1346 }
1347 }
1348
Johnny Cheneb46f782012-08-15 22:10:42 +00001349 // Was there a core file specified?
1350 std::string core_file_spec("");
1351 if (!m_option_data.m_core_file.empty())
1352 core_file_spec.append("--core ").append(m_option_data.m_core_file);
1353
Greg Clayton8d846da2010-12-08 22:23:24 +00001354 const size_t num_args = m_option_data.m_args.size();
1355 if (num_args > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356 {
1357 char arch_name[64];
Greg Clayton66111032010-06-23 01:19:29 +00001358 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Greg Clayton8d846da2010-12-08 22:23:24 +00001359 ::snprintf (command_string,
1360 sizeof (command_string),
Johnny Cheneb46f782012-08-15 22:10:42 +00001361 "target create --arch=%s %s \"%s\"",
Greg Clayton8d846da2010-12-08 22:23:24 +00001362 arch_name,
Johnny Cheneb46f782012-08-15 22:10:42 +00001363 core_file_spec.c_str(),
Greg Clayton8d846da2010-12-08 22:23:24 +00001364 m_option_data.m_args[0].c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001365 else
Greg Clayton8d846da2010-12-08 22:23:24 +00001366 ::snprintf (command_string,
1367 sizeof(command_string),
Johnny Cheneb46f782012-08-15 22:10:42 +00001368 "target create %s \"%s\"",
1369 core_file_spec.c_str(),
Greg Clayton8d846da2010-12-08 22:23:24 +00001370 m_option_data.m_args[0].c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371
Greg Clayton66111032010-06-23 01:19:29 +00001372 m_debugger.HandleCommand (command_string);
Greg Clayton8d846da2010-12-08 22:23:24 +00001373
1374 if (num_args > 1)
1375 {
Greg Clayton1d885962011-11-08 02:43:13 +00001376 m_debugger.HandleCommand ("settings clear target.run-args");
Greg Clayton8d846da2010-12-08 22:23:24 +00001377 char arg_cstr[1024];
1378 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1379 {
Jim Inghame64f0dc2011-09-13 23:25:31 +00001380 ::snprintf (arg_cstr,
1381 sizeof(arg_cstr),
Greg Clayton1d885962011-11-08 02:43:13 +00001382 "settings append target.run-args \"%s\"",
Jim Inghame64f0dc2011-09-13 23:25:31 +00001383 m_option_data.m_args[arg_idx].c_str());
Greg Clayton8d846da2010-12-08 22:23:24 +00001384 m_debugger.HandleCommand (arg_cstr);
1385 }
1386 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001387 }
Johnny Cheneb46f782012-08-15 22:10:42 +00001388 else if (!core_file_spec.empty())
1389 {
1390 ::snprintf (command_string,
1391 sizeof(command_string),
1392 "target create %s",
1393 core_file_spec.c_str());
1394 m_debugger.HandleCommand (command_string);;
1395 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396
1397 // Now that all option parsing is done, we try and parse the .lldbinit
1398 // file in the current working directory
1399 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1400 if (GetDebugMode())
1401 {
Greg Clayton66111032010-06-23 01:19:29 +00001402 result.PutError(m_debugger.GetErrorFileHandle());
1403 result.PutOutput(m_debugger.GetOutputFileHandle());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404 }
1405
1406 SBEvent event;
1407
1408 // Make sure the IO channel is started up before we try to tell it we
1409 // are ready for input
1410 listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1411 *m_io_channel_ap,
1412 IOChannel::eBroadcastBitThreadDidStart,
1413 event);
Jim Inghame64f0dc2011-09-13 23:25:31 +00001414 // If we were asked to attach, then do that here:
1415 // I'm going to use the command string rather than directly
1416 // calling the API's because then I don't have to recode the
1417 // event handling here.
1418 if (!m_option_data.m_process_name.empty()
1419 || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1420 {
1421 std::string command_str("process attach ");
1422 if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
1423 {
1424 command_str.append("-p ");
1425 char pid_buffer[32];
Greg Clayton61e7a582011-12-01 23:28:38 +00001426 ::snprintf (pid_buffer, sizeof(pid_buffer), "%llu", m_option_data.m_process_pid);
Jim Inghame64f0dc2011-09-13 23:25:31 +00001427 command_str.append(pid_buffer);
1428 }
1429 else
1430 {
1431 command_str.append("-n \"");
1432 command_str.append(m_option_data.m_process_name);
1433 command_str.push_back('\"');
1434 if (m_option_data.m_wait_for)
1435 command_str.append(" -w");
1436 }
1437
1438 if (m_debugger.GetOutputFileHandle())
1439 ::fprintf (m_debugger.GetOutputFileHandle(),
1440 "Attaching to process with:\n %s\n",
1441 command_str.c_str());
1442
1443 // Force the attach to be synchronous:
1444 bool orig_async = m_debugger.GetAsync();
1445 m_debugger.SetAsync(true);
1446 m_debugger.HandleCommand(command_str.c_str());
1447 m_debugger.SetAsync(orig_async);
1448 }
1449
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001450 ReadyForCommand ();
1451
Greg Claytona9f7b792012-02-29 04:21:24 +00001452 while (!GetIsDone())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001453 {
1454 listener.WaitForEvent (UINT32_MAX, event);
1455 if (event.IsValid())
1456 {
1457 if (event.GetBroadcaster().IsValid())
1458 {
1459 uint32_t event_type = event.GetType();
1460 if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1461 {
1462 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1463 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1464 {
Greg Claytona9f7b792012-02-29 04:21:24 +00001465 SetIsDone();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001466 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1467 iochannel_thread_exited = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001468 }
1469 else
Greg Claytona9f7b792012-02-29 04:21:24 +00001470 {
1471 if (HandleIOEvent (event))
1472 SetIsDone();
1473 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001474 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +00001475 else if (SBProcess::EventIsProcessEvent (event))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001476 {
1477 HandleProcessEvent (event);
1478 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +00001479 else if (SBBreakpoint::EventIsBreakpointEvent (event))
1480 {
1481 HandleBreakpointEvent (event);
1482 }
Jim Ingham4f465cf2012-10-10 18:32:14 +00001483 else if (SBThread::EventIsThreadEvent (event))
1484 {
1485 HandleThreadEvent (event);
1486 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001487 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1488 {
Greg Claytona9f7b792012-02-29 04:21:24 +00001489 // TODO: deprecate the eBroadcastBitQuitCommandReceived event
1490 // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
1491 // that can take over a command
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001492 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
Greg Clayton74d41932012-01-31 04:56:17 +00001493 {
Greg Claytona9f7b792012-02-29 04:21:24 +00001494 SetIsDone();
Greg Clayton74d41932012-01-31 04:56:17 +00001495 }
Caroline Tice86a73f92011-05-03 20:53:11 +00001496 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1497 {
1498 const char *data = SBEvent::GetCStringFromEvent (event);
1499 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1500 }
1501 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1502 {
1503 const char *data = SBEvent::GetCStringFromEvent (event);
1504 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1505 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001506 }
1507 }
1508 }
1509 }
1510
Greg Claytonf571b892012-02-02 19:28:31 +00001511 editline_output_pty.CloseMasterFileDescriptor();
1512 master_out_comm.Disconnect();
1513 out_comm_2.Disconnect();
1514 reset_stdin_termios();
1515 fclose (stdin);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001516
1517 CloseIOChannelFile ();
1518
1519 if (!iochannel_thread_exited)
1520 {
Greg Claytonb1320972010-07-14 00:18:15 +00001521 event.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001522 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1523 IOChannel::eBroadcastBitThreadDidExit,
1524 event);
1525 if (!event.IsValid())
1526 {
1527 // Send end EOF to the driver file descriptor
1528 m_io_channel_ap->Stop();
1529 }
1530 }
1531
Jim Ingham12e9a202011-09-15 21:30:02 +00001532 SBDebugger::Destroy (m_debugger);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001533 }
1534 }
1535}
1536
1537
1538void
1539Driver::ReadyForCommand ()
1540{
1541 if (m_waiting_for_command == false)
1542 {
1543 m_waiting_for_command = true;
1544 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1545 }
1546}
1547
1548
Caroline Ticedd759852010-09-09 17:45:09 +00001549void
1550sigwinch_handler (int signo)
1551{
1552 struct winsize window_size;
1553 if (isatty (STDIN_FILENO)
1554 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1555 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001556 if ((window_size.ws_col > 0) && g_driver != NULL)
Caroline Ticedd759852010-09-09 17:45:09 +00001557 {
Jim Ingham57190ba2012-04-26 21:39:32 +00001558 g_driver->GetDebugger().SetTerminalWidth (window_size.ws_col);
Caroline Ticedd759852010-09-09 17:45:09 +00001559 }
1560 }
1561}
1562
Caroline Ticeefed6132010-11-19 20:47:54 +00001563void
1564sigint_handler (int signo)
1565{
1566 static bool g_interrupt_sent = false;
1567 if (g_driver)
1568 {
1569 if (!g_interrupt_sent)
1570 {
1571 g_interrupt_sent = true;
1572 g_driver->GetDebugger().DispatchInputInterrupt();
1573 g_interrupt_sent = false;
1574 return;
1575 }
1576 }
1577
1578 exit (signo);
1579}
1580
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001581int
Jim Inghama462f5c2011-01-27 20:15:39 +00001582main (int argc, char const *argv[], const char *envp[])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001583{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001584 SBDebugger::Initialize();
1585
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00001586 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001587
Greg Clayton3fcbed62010-10-19 03:25:40 +00001588 signal (SIGPIPE, SIG_IGN);
Caroline Ticedd759852010-09-09 17:45:09 +00001589 signal (SIGWINCH, sigwinch_handler);
Caroline Ticeefed6132010-11-19 20:47:54 +00001590 signal (SIGINT, sigint_handler);
Caroline Ticedd759852010-09-09 17:45:09 +00001591
Greg Clayton66111032010-06-23 01:19:29 +00001592 // Create a scope for driver so that the driver object will destroy itself
1593 // before SBDebugger::Terminate() is called.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001594 {
Greg Clayton66111032010-06-23 01:19:29 +00001595 Driver driver;
1596
1597 bool exit = false;
1598 SBError error (driver.ParseArgs (argc, argv, stdout, exit));
1599 if (error.Fail())
1600 {
1601 const char *error_cstr = error.GetCString ();
1602 if (error_cstr)
1603 ::fprintf (stderr, "error: %s\n", error_cstr);
1604 }
1605 else if (!exit)
1606 {
1607 driver.MainLoop ();
1608 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001609 }
1610
1611 SBDebugger::Terminate();
1612 return 0;
1613}