blob: 313870b1a3be54dba3f3d485fd09ce70b898c2f4 [file] [log] [blame]
Chris Lattner24943d22010-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 Friedmanf2f321d2010-06-09 09:50:17 +000017#include <string.h>
18#include <stdlib.h>
19#include <limits.h>
Eli Friedmand6e167d2010-06-09 19:11:30 +000020#include <fcntl.h>
Chris Lattner24943d22010-06-08 16:52:24 +000021
22#include <string>
23
24#include "IOChannel.h"
Eli Friedmanf2f321d2010-06-09 09:50:17 +000025#include "lldb/API/SBCommandInterpreter.h"
26#include "lldb/API/SBCommandReturnObject.h"
27#include "lldb/API/SBCommunication.h"
28#include "lldb/API/SBDebugger.h"
29#include "lldb/API/SBEvent.h"
30#include "lldb/API/SBHostOS.h"
31#include "lldb/API/SBListener.h"
32#include "lldb/API/SBSourceManager.h"
Jim Ingham2e8cb8a2011-02-19 02:53:09 +000033#include "lldb/API/SBStream.h"
Eli Friedmanf2f321d2010-06-09 09:50:17 +000034#include "lldb/API/SBTarget.h"
35#include "lldb/API/SBThread.h"
36#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
38using namespace lldb;
39
40static void reset_stdin_termios ();
41static struct termios g_old_stdin_termios;
42
Caroline Ticeb8314fe2010-09-09 17:45:09 +000043static char *g_debugger_name = (char *) "";
Caroline Ticec4f55fe2010-11-19 20:47:54 +000044static Driver *g_driver = NULL;
Caroline Ticeb8314fe2010-09-09 17:45:09 +000045
Chris Lattner24943d22010-06-08 16:52:24 +000046// In the Driver::MainLoop, we change the terminal settings. This function is
47// added as an atexit handler to make sure we clean them up.
48static void
49reset_stdin_termios ()
50{
51 ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
52}
53
Greg Claytonb3448432011-03-24 21:19:54 +000054typedef struct
Chris Lattner24943d22010-06-08 16:52:24 +000055{
Greg Claytonb3448432011-03-24 21:19:54 +000056 uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
57 // then this option belongs to option set n.
58 bool required; // This option is required (in the current usage level)
59 const char * long_option; // Full name for this option.
60 char short_option; // Single character for this option.
61 int option_has_arg; // no_argument, required_argument or optional_argument
Greg Clayton5e342f52011-04-13 22:47:15 +000062 uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Greg Claytonb3448432011-03-24 21:19:54 +000063 lldb::CommandArgumentType argument_type; // Type of argument this option takes
64 const char * usage_text; // Full text explaining what this options does and what (if any) argument to
65 // pass it.
66} OptionDefinition;
Chris Lattner24943d22010-06-08 16:52:24 +000067
Jim Ingham6ae25442011-08-16 23:15:02 +000068#define LLDB_2_TO_4 LLDB_OPT_SET_2|LLDB_OPT_SET_3|LLDB_OPT_SET_4
Greg Claytonb3448432011-03-24 21:19:54 +000069static OptionDefinition g_options[] =
70{
71 { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , NULL, eArgTypeNone, "Prints out the usage information for the LLDB debugger." },
72 { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , NULL, eArgTypeNone, "Prints out the current version number of the LLDB debugger." },
73 { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, NULL, eArgTypeArchitecture,"Tells the debugger to use the specified architecture when starting and running the program. <architecture> must be one of the architectures for which the program was compiled." },
74 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "script-language", 'l', required_argument, NULL, eArgTypeScriptLang,"Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python extensions have been implemented." },
75 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "debug" , 'd', no_argument , NULL, eArgTypeNone,"Tells the debugger to print out extra information for debugging itself." },
76 { LLDB_OPT_SET_3 | LLDB_OPT_SET_4, false, "source" , 's', required_argument, NULL, eArgTypeFilename, "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
77 { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, NULL, eArgTypeFilename, "Tells the debugger to use the file <filename> as the program to be debugged." },
Jim Ingham6ae25442011-08-16 23:15:02 +000078 { LLDB_2_TO_4, false, "editor" , 'e', no_argument , NULL, eArgTypeNone, "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
79 { LLDB_2_TO_4, false, "no-lldbinit" , 'n', no_argument , NULL, eArgTypeNone, "Do not automatically parse any '.lldbinit' files." },
Greg Claytonb3448432011-03-24 21:19:54 +000080 { 0, false, NULL , 0 , 0 , NULL, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +000081};
82
83
84Driver::Driver () :
85 SBBroadcaster ("Driver"),
Jim Ingham558dd5b2011-08-13 00:22:20 +000086 m_debugger (SBDebugger::Create(false)),
Chris Lattner24943d22010-06-08 16:52:24 +000087 m_editline_pty (),
88 m_editline_slave_fh (NULL),
89 m_editline_reader (),
90 m_io_channel_ap (),
91 m_option_data (),
92 m_waiting_for_command (false)
93{
Greg Clayton421ca502011-05-29 04:06:55 +000094 // We want to be able to handle CTRL+D in the terminal to have it terminate
95 // certain input
96 m_debugger.SetCloseInputOnEOF (false);
Caroline Ticeb8314fe2010-09-09 17:45:09 +000097 g_debugger_name = (char *) m_debugger.GetInstanceName();
98 if (g_debugger_name == NULL)
99 g_debugger_name = (char *) "";
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000100 g_driver = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000101}
102
103Driver::~Driver ()
104{
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000105 g_driver = NULL;
106 g_debugger_name = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000107}
108
109void
110Driver::CloseIOChannelFile ()
111{
112 // Write and End of File sequence to the file descriptor to ensure any
113 // read functions can exit.
114 char eof_str[] = "\x04";
115 ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
116
117 m_editline_pty.CloseMasterFileDescriptor();
118
119 if (m_editline_slave_fh)
120 {
121 ::fclose (m_editline_slave_fh);
122 m_editline_slave_fh = NULL;
123 }
124}
125
Greg Clayton54e7afa2010-07-09 20:39:50 +0000126// This function takes INDENT, which tells how many spaces to output at the front
127// of each line; TEXT, which is the text that is to be output. It outputs the
128// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
129// front of each line. It breaks lines on spaces, tabs or newlines, shortening
130// the line if necessary to not break in the middle of a word. It assumes that
131// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner24943d22010-06-08 16:52:24 +0000132
133void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000134OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
Chris Lattner24943d22010-06-08 16:52:24 +0000135{
136 int len = strlen (text);
137 std::string text_string (text);
Chris Lattner24943d22010-06-08 16:52:24 +0000138
139 // Force indentation to be reasonable.
140 if (indent >= output_max_columns)
141 indent = 0;
142
143 // Will it all fit on one line?
144
145 if (len + indent < output_max_columns)
146 // Output as a single line
Greg Clayton54e7afa2010-07-09 20:39:50 +0000147 fprintf (out, "%*s%s\n", indent, "", text);
Chris Lattner24943d22010-06-08 16:52:24 +0000148 else
149 {
150 // We need to break it up into multiple lines.
151 int text_width = output_max_columns - indent - 1;
152 int start = 0;
153 int end = start;
154 int final_end = len;
155 int sub_len;
156
157 while (end < final_end)
158 {
159 // Dont start the 'text' on a space, since we're already outputting the indentation.
160 while ((start < final_end) && (text[start] == ' '))
161 start++;
162
163 end = start + text_width;
164 if (end > final_end)
165 end = final_end;
166 else
167 {
168 // If we're not at the end of the text, make sure we break the line on white space.
169 while (end > start
170 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
171 end--;
172 }
173 sub_len = end - start;
174 std::string substring = text_string.substr (start, sub_len);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000175 fprintf (out, "%*s%s\n", indent, "", substring.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000176 start = end + 1;
177 }
178 }
179}
180
181void
Greg Claytonb3448432011-03-24 21:19:54 +0000182ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
Chris Lattner24943d22010-06-08 16:52:24 +0000183{
184 uint32_t screen_width = 80;
185 uint32_t indent_level = 0;
186 const char *name = "lldb";
Jim Ingham34e9a982010-06-15 18:47:14 +0000187
Chris Lattner24943d22010-06-08 16:52:24 +0000188 fprintf (out, "\nUsage:\n\n");
189
190 indent_level += 2;
191
192
193 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
194 // <cmd> [options-for-level-1]
195 // etc.
196
Chris Lattner24943d22010-06-08 16:52:24 +0000197 uint32_t num_options;
Jim Ingham34e9a982010-06-15 18:47:14 +0000198 uint32_t num_option_sets = 0;
199
200 for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
Chris Lattner24943d22010-06-08 16:52:24 +0000201 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000202 uint32_t this_usage_mask = option_table[num_options].usage_mask;
203 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner24943d22010-06-08 16:52:24 +0000204 {
Jim Ingham34e9a982010-06-15 18:47:14 +0000205 if (num_option_sets == 0)
206 num_option_sets = 1;
Chris Lattner24943d22010-06-08 16:52:24 +0000207 }
208 else
209 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000210 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
Jim Ingham34e9a982010-06-15 18:47:14 +0000211 {
212 if (this_usage_mask & 1 << j)
213 {
214 if (num_option_sets <= j)
215 num_option_sets = j + 1;
216 }
217 }
218 }
219 }
220
221 for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
222 {
223 uint32_t opt_set_mask;
224
225 opt_set_mask = 1 << opt_set;
226
227 if (opt_set > 0)
228 fprintf (out, "\n");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000229 fprintf (out, "%*s%s", indent_level, "", name);
Jim Ingham6ae25442011-08-16 23:15:02 +0000230 bool is_help_line = false;
Jim Ingham34e9a982010-06-15 18:47:14 +0000231
232 for (uint32_t i = 0; i < num_options; ++i)
233 {
234 if (option_table[i].usage_mask & opt_set_mask)
235 {
Caroline Tice4d6675c2010-10-01 19:59:14 +0000236 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Claytonaa378b12011-02-20 02:15:07 +0000237 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Jim Ingham6ae25442011-08-16 23:15:02 +0000238 // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
239 // so we do it by hand here.
240 if (option_table[i].short_option == 'h')
241 is_help_line = true;
242
Jim Ingham34e9a982010-06-15 18:47:14 +0000243 if (option_table[i].required)
244 {
245 if (option_table[i].option_has_arg == required_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000246 fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000247 else if (option_table[i].option_has_arg == optional_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000248 fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000249 else
250 fprintf (out, " -%c", option_table[i].short_option);
251 }
252 else
253 {
254 if (option_table[i].option_has_arg == required_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000255 fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000256 else if (option_table[i].option_has_arg == optional_argument)
Greg Claytonaa378b12011-02-20 02:15:07 +0000257 fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
Jim Ingham34e9a982010-06-15 18:47:14 +0000258 else
259 fprintf (out, " [-%c]", option_table[i].short_option);
260 }
261 }
Chris Lattner24943d22010-06-08 16:52:24 +0000262 }
Jim Ingham6ae25442011-08-16 23:15:02 +0000263 if (!is_help_line)
264 fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
Chris Lattner24943d22010-06-08 16:52:24 +0000265 }
266
267 fprintf (out, "\n\n");
268
269 // Now print out all the detailed information about the various options: long form, short form and help text:
270 // -- long_name <argument>
271 // - short <argument>
272 // help text
273
274 // This variable is used to keep track of which options' info we've printed out, because some options can be in
275 // more than one usage level, but we only want to print the long form of its information once.
276
277 Driver::OptionData::OptionSet options_seen;
278 Driver::OptionData::OptionSet::iterator pos;
279
280 indent_level += 5;
281
Jim Ingham34e9a982010-06-15 18:47:14 +0000282 for (uint32_t i = 0; i < num_options; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +0000283 {
284 // Only print this option if we haven't already seen it.
285 pos = options_seen.find (option_table[i].short_option);
286 if (pos == options_seen.end())
287 {
Caroline Tice4d6675c2010-10-01 19:59:14 +0000288 CommandArgumentType arg_type = option_table[i].argument_type;
Greg Claytonaa378b12011-02-20 02:15:07 +0000289 const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
Caroline Tice4d6675c2010-10-01 19:59:14 +0000290
Chris Lattner24943d22010-06-08 16:52:24 +0000291 options_seen.insert (option_table[i].short_option);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000292 fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
Caroline Tice4d6675c2010-10-01 19:59:14 +0000293 if (arg_type != eArgTypeNone)
Greg Claytonaa378b12011-02-20 02:15:07 +0000294 fprintf (out, "<%s>", arg_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000295 fprintf (out, "\n");
Greg Clayton54e7afa2010-07-09 20:39:50 +0000296 fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
Caroline Tice4d6675c2010-10-01 19:59:14 +0000297 if (arg_type != eArgTypeNone)
Greg Claytonaa378b12011-02-20 02:15:07 +0000298 fprintf (out, "<%s>", arg_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000299 fprintf (out, "\n");
300 indent_level += 5;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000301 OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
Chris Lattner24943d22010-06-08 16:52:24 +0000302 indent_level -= 5;
303 fprintf (out, "\n");
304 }
305 }
306
307 indent_level -= 5;
308
Greg Clayton54e7afa2010-07-09 20:39:50 +0000309 fprintf (out, "\n%*s('%s <filename>' also works, to specify the file to be debugged.)\n\n",
310 indent_level, "", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000311}
312
313void
Greg Claytonb3448432011-03-24 21:19:54 +0000314BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000315 uint32_t num_options)
Chris Lattner24943d22010-06-08 16:52:24 +0000316{
317 if (num_options == 0)
318 return;
319
320 uint32_t i;
321 uint32_t j;
322 std::bitset<256> option_seen;
323
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000324 getopt_table.resize (num_options + 1);
325
Chris Lattner24943d22010-06-08 16:52:24 +0000326 for (i = 0, j = 0; i < num_options; ++i)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000327 {
Chris Lattner24943d22010-06-08 16:52:24 +0000328 char short_opt = expanded_option_table[i].short_option;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000329
Chris Lattner24943d22010-06-08 16:52:24 +0000330 if (option_seen.test(short_opt) == false)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000331 {
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000332 getopt_table[j].name = expanded_option_table[i].long_option;
333 getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
334 getopt_table[j].flag = NULL;
335 getopt_table[j].val = expanded_option_table[i].short_option;
Chris Lattner24943d22010-06-08 16:52:24 +0000336 option_seen.set(short_opt);
337 ++j;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000338 }
339 }
Chris Lattner24943d22010-06-08 16:52:24 +0000340
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000341 getopt_table[j].name = NULL;
342 getopt_table[j].has_arg = 0;
343 getopt_table[j].flag = NULL;
344 getopt_table[j].val = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000345
346}
347
Greg Clayton63094e02010-06-23 01:19:29 +0000348Driver::OptionData::OptionData () :
Greg Clayton4dc18922010-12-08 22:23:24 +0000349 m_args(),
Greg Clayton63094e02010-06-23 01:19:29 +0000350 m_script_lang (lldb::eScriptLanguageDefault),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000351 m_crash_log (),
Greg Clayton63094e02010-06-23 01:19:29 +0000352 m_source_command_files (),
353 m_debug_mode (false),
Greg Clayton54e7afa2010-07-09 20:39:50 +0000354 m_print_version (false),
Greg Clayton63094e02010-06-23 01:19:29 +0000355 m_print_help (false),
Stephen Wilsondbeb3e12011-04-11 19:41:40 +0000356 m_use_external_editor(false),
357 m_seen_options()
Chris Lattner24943d22010-06-08 16:52:24 +0000358{
Greg Clayton63094e02010-06-23 01:19:29 +0000359}
360
361Driver::OptionData::~OptionData ()
362{
363}
364
365void
366Driver::OptionData::Clear ()
367{
Greg Clayton4dc18922010-12-08 22:23:24 +0000368 m_args.clear ();
Greg Clayton63094e02010-06-23 01:19:29 +0000369 m_script_lang = lldb::eScriptLanguageDefault;
370 m_source_command_files.clear ();
371 m_debug_mode = false;
372 m_print_help = false;
373 m_print_version = false;
Jim Ingham74989e82010-08-30 19:44:40 +0000374 m_use_external_editor = false;
Greg Clayton63094e02010-06-23 01:19:29 +0000375}
376
377void
378Driver::ResetOptionValues ()
379{
380 m_option_data.Clear ();
381}
382
383const char *
384Driver::GetFilename() const
385{
Greg Clayton4dc18922010-12-08 22:23:24 +0000386 if (m_option_data.m_args.empty())
Greg Clayton63094e02010-06-23 01:19:29 +0000387 return NULL;
Greg Clayton4dc18922010-12-08 22:23:24 +0000388 return m_option_data.m_args.front().c_str();
Greg Clayton63094e02010-06-23 01:19:29 +0000389}
390
391const char *
392Driver::GetCrashLogFilename() const
393{
394 if (m_option_data.m_crash_log.empty())
395 return NULL;
396 return m_option_data.m_crash_log.c_str();
397}
398
399lldb::ScriptLanguage
400Driver::GetScriptLanguage() const
401{
402 return m_option_data.m_script_lang;
403}
404
405size_t
406Driver::GetNumSourceCommandFiles () const
407{
408 return m_option_data.m_source_command_files.size();
409}
410
411const char *
412Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
413{
414 if (idx < m_option_data.m_source_command_files.size())
415 return m_option_data.m_source_command_files[idx].c_str();
416 return NULL;
417}
418
419bool
420Driver::GetDebugMode() const
421{
422 return m_option_data.m_debug_mode;
423}
424
425
426// Check the arguments that were passed to this program to make sure they are valid and to get their
427// argument values (if any). Return a boolean value indicating whether or not to start up the full
428// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
429// if the user only wanted help or version information.
430
431SBError
432Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
433{
434 ResetOptionValues ();
435
436 SBCommandReturnObject result;
437
Chris Lattner24943d22010-06-08 16:52:24 +0000438 SBError error;
439 std::string option_string;
440 struct option *long_options = NULL;
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000441 std::vector<struct option> long_options_vector;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000442 uint32_t num_options;
Chris Lattner24943d22010-06-08 16:52:24 +0000443
Greg Clayton54e7afa2010-07-09 20:39:50 +0000444 for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
445 /* Do Nothing. */;
Chris Lattner24943d22010-06-08 16:52:24 +0000446
447 if (num_options == 0)
448 {
449 if (argc > 1)
450 error.SetErrorStringWithFormat ("invalid number of options");
451 return error;
452 }
453
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000454 BuildGetOptTable (g_options, long_options_vector, num_options);
Chris Lattner24943d22010-06-08 16:52:24 +0000455
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000456 if (long_options_vector.empty())
457 long_options = NULL;
458 else
459 long_options = &long_options_vector.front();
Chris Lattner24943d22010-06-08 16:52:24 +0000460
461 if (long_options == NULL)
462 {
463 error.SetErrorStringWithFormat ("invalid long options");
464 return error;
465 }
466
467 // Build the option_string argument for call to getopt_long.
468
469 for (int i = 0; long_options[i].name != NULL; ++i)
470 {
471 if (long_options[i].flag == NULL)
472 {
473 option_string.push_back ((char) long_options[i].val);
474 switch (long_options[i].has_arg)
475 {
476 default:
477 case no_argument:
478 break;
479 case required_argument:
480 option_string.push_back (':');
481 break;
482 case optional_argument:
483 option_string.append ("::");
484 break;
485 }
486 }
487 }
488
Jim Ingham558dd5b2011-08-13 00:22:20 +0000489 // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
490 // know at that point whether we should read in init files yet. So we don't read them in in the
491 // Driver constructor, then set the flags back to "read them in" here, and then if we see the
492 // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
493 // main loop.
494
495 m_debugger.SkipLLDBInitFiles (false);
496 m_debugger.SkipAppInitFiles (false);
497
Chris Lattner24943d22010-06-08 16:52:24 +0000498 // Prepare for & make calls to getopt_long.
Eli Friedmanef2bc872010-06-13 19:18:49 +0000499#if __GLIBC__
500 optind = 0;
501#else
Chris Lattner24943d22010-06-08 16:52:24 +0000502 optreset = 1;
503 optind = 1;
Eli Friedmanef2bc872010-06-13 19:18:49 +0000504#endif
Chris Lattner24943d22010-06-08 16:52:24 +0000505 int val;
506 while (1)
507 {
508 int long_options_index = -1;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000509 val = ::getopt_long (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
Chris Lattner24943d22010-06-08 16:52:24 +0000510
511 if (val == -1)
512 break;
513 else if (val == '?')
514 {
Greg Clayton63094e02010-06-23 01:19:29 +0000515 m_option_data.m_print_help = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000516 error.SetErrorStringWithFormat ("unknown or ambiguous option");
517 break;
518 }
519 else if (val == 0)
520 continue;
521 else
522 {
Greg Clayton63094e02010-06-23 01:19:29 +0000523 m_option_data.m_seen_options.insert ((char) val);
Chris Lattner24943d22010-06-08 16:52:24 +0000524 if (long_options_index == -1)
525 {
526 for (int i = 0;
527 long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
528 ++i)
529 {
530 if (long_options[i].val == val)
531 {
532 long_options_index = i;
533 break;
534 }
535 }
536 }
537
538 if (long_options_index >= 0)
539 {
Greg Clayton63094e02010-06-23 01:19:29 +0000540 const char short_option = (char) g_options[long_options_index].short_option;
541
542 switch (short_option)
543 {
544 case 'h':
545 m_option_data.m_print_help = true;
546 break;
547
548 case 'v':
549 m_option_data.m_print_version = true;
550 break;
551
552 case 'c':
553 m_option_data.m_crash_log = optarg;
554 break;
Greg Clayton887aa282010-10-11 01:05:37 +0000555
Jim Ingham74989e82010-08-30 19:44:40 +0000556 case 'e':
557 m_option_data.m_use_external_editor = true;
558 break;
Greg Clayton887aa282010-10-11 01:05:37 +0000559
560 case 'n':
561 m_debugger.SkipLLDBInitFiles (true);
Jim Ingham558dd5b2011-08-13 00:22:20 +0000562 m_debugger.SkipAppInitFiles (true);
Greg Clayton887aa282010-10-11 01:05:37 +0000563 break;
564
Greg Clayton63094e02010-06-23 01:19:29 +0000565 case 'f':
566 {
567 SBFileSpec file(optarg);
568 if (file.Exists())
Greg Clayton4dc18922010-12-08 22:23:24 +0000569 {
570 m_option_data.m_args.push_back (optarg);
571 }
Caroline Ticeeddffe92010-09-10 04:48:55 +0000572 else if (file.ResolveExecutableLocation())
573 {
574 char path[PATH_MAX];
Johnny Chenee6e7902011-08-10 22:06:24 +0000575 file.GetPath (path, sizeof(path));
Greg Clayton4dc18922010-12-08 22:23:24 +0000576 m_option_data.m_args.push_back (path);
Caroline Ticeeddffe92010-09-10 04:48:55 +0000577 }
Greg Clayton63094e02010-06-23 01:19:29 +0000578 else
579 error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
580 }
581 break;
582
583 case 'a':
584 if (!m_debugger.SetDefaultArchitecture (optarg))
585 error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
586 break;
587
588 case 'l':
589 m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
590 break;
591
592 case 'd':
593 m_option_data.m_debug_mode = true;
594 break;
595
596 case 's':
597 {
598 SBFileSpec file(optarg);
599 if (file.Exists())
600 m_option_data.m_source_command_files.push_back (optarg);
Caroline Ticeeddffe92010-09-10 04:48:55 +0000601 else if (file.ResolveExecutableLocation())
602 {
603 char final_path[PATH_MAX];
Johnny Chenee6e7902011-08-10 22:06:24 +0000604 file.GetPath (final_path, sizeof(final_path));
Caroline Ticeeddffe92010-09-10 04:48:55 +0000605 std::string path_str (final_path);
606 m_option_data.m_source_command_files.push_back (path_str);
607 }
Greg Clayton63094e02010-06-23 01:19:29 +0000608 else
609 error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
610 }
611 break;
612
613 default:
614 m_option_data.m_print_help = true;
615 error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
616 break;
617 }
Chris Lattner24943d22010-06-08 16:52:24 +0000618 }
619 else
620 {
621 error.SetErrorStringWithFormat ("invalid option with value %i", val);
622 }
623 if (error.Fail())
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000624 {
Greg Clayton63094e02010-06-23 01:19:29 +0000625 return error;
Caroline Ticebd5c63e2010-10-12 21:57:09 +0000626 }
Chris Lattner24943d22010-06-08 16:52:24 +0000627 }
628 }
Jim Ingham34e9a982010-06-15 18:47:14 +0000629
Greg Clayton63094e02010-06-23 01:19:29 +0000630 if (error.Fail() || m_option_data.m_print_help)
Chris Lattner24943d22010-06-08 16:52:24 +0000631 {
632 ShowUsage (out_fh, g_options, m_option_data);
Greg Clayton9caa9462010-10-11 01:13:37 +0000633 exit = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000634 }
635 else if (m_option_data.m_print_version)
636 {
Greg Clayton63094e02010-06-23 01:19:29 +0000637 ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
638 exit = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000639 }
640 else if (! m_option_data.m_crash_log.empty())
641 {
642 // Handle crash log stuff here.
643 }
644 else
645 {
Greg Clayton4dc18922010-12-08 22:23:24 +0000646 // Any arguments that are left over after option parsing are for
647 // the program. If a file was specified with -f then the filename
648 // is already in the m_option_data.m_args array, and any remaining args
649 // are arguments for the inferior program. If no file was specified with
650 // -f, then what is left is the program name followed by any arguments.
651
652 // Skip any options we consumed with getopt_long
653 argc -= optind;
654 argv += optind;
655
656 if (argc > 0)
657 {
658 for (int arg_idx=0; arg_idx<argc; ++arg_idx)
659 {
660 const char *arg = argv[arg_idx];
661 if (arg)
662 m_option_data.m_args.push_back (arg);
663 }
664 }
665
Chris Lattner24943d22010-06-08 16:52:24 +0000666 }
667
Greg Clayton63094e02010-06-23 01:19:29 +0000668 return error;
Chris Lattner24943d22010-06-08 16:52:24 +0000669}
670
Caroline Tice757500e2010-09-29 18:35:42 +0000671size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000672Driver::GetProcessSTDOUT ()
673{
674 // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
675 char stdio_buffer[1024];
676 size_t len;
Caroline Tice757500e2010-09-29 18:35:42 +0000677 size_t total_bytes = 0;
Jim Inghamc8332952010-08-26 21:32:51 +0000678 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Tice757500e2010-09-29 18:35:42 +0000679 {
Caroline Tice4a348082011-05-02 20:41:46 +0000680 m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC);
Caroline Tice757500e2010-09-29 18:35:42 +0000681 total_bytes += len;
682 }
683 return total_bytes;
Chris Lattner24943d22010-06-08 16:52:24 +0000684}
685
Caroline Tice757500e2010-09-29 18:35:42 +0000686size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000687Driver::GetProcessSTDERR ()
688{
689 // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
690 char stdio_buffer[1024];
691 size_t len;
Caroline Tice757500e2010-09-29 18:35:42 +0000692 size_t total_bytes = 0;
Jim Inghamc8332952010-08-26 21:32:51 +0000693 while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
Caroline Tice757500e2010-09-29 18:35:42 +0000694 {
Caroline Tice4a348082011-05-02 20:41:46 +0000695 m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC);
Caroline Tice757500e2010-09-29 18:35:42 +0000696 total_bytes += len;
697 }
698 return total_bytes;
Chris Lattner24943d22010-06-08 16:52:24 +0000699}
700
701void
Jim Inghamc8332952010-08-26 21:32:51 +0000702Driver::UpdateSelectedThread ()
Chris Lattner24943d22010-06-08 16:52:24 +0000703{
704 using namespace lldb;
Jim Inghamc8332952010-08-26 21:32:51 +0000705 SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
Chris Lattner24943d22010-06-08 16:52:24 +0000706 if (process.IsValid())
707 {
Jim Inghamc8332952010-08-26 21:32:51 +0000708 SBThread curr_thread (process.GetSelectedThread());
Chris Lattner24943d22010-06-08 16:52:24 +0000709 SBThread thread;
710 StopReason curr_thread_stop_reason = eStopReasonInvalid;
711 curr_thread_stop_reason = curr_thread.GetStopReason();
712
713 if (!curr_thread.IsValid() ||
714 curr_thread_stop_reason == eStopReasonInvalid ||
715 curr_thread_stop_reason == eStopReasonNone)
716 {
717 // Prefer a thread that has just completed its plan over another thread as current thread.
718 SBThread plan_thread;
719 SBThread other_thread;
720 const size_t num_threads = process.GetNumThreads();
721 size_t i;
722 for (i = 0; i < num_threads; ++i)
723 {
724 thread = process.GetThreadAtIndex(i);
725 StopReason thread_stop_reason = thread.GetStopReason();
726 switch (thread_stop_reason)
727 {
728 default:
729 case eStopReasonInvalid:
730 case eStopReasonNone:
731 break;
732
733 case eStopReasonTrace:
734 case eStopReasonBreakpoint:
735 case eStopReasonWatchpoint:
736 case eStopReasonSignal:
737 case eStopReasonException:
738 if (!other_thread.IsValid())
739 other_thread = thread;
740 break;
741 case eStopReasonPlanComplete:
742 if (!plan_thread.IsValid())
743 plan_thread = thread;
744 break;
745 }
746 }
747 if (plan_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000748 process.SetSelectedThread (plan_thread);
Chris Lattner24943d22010-06-08 16:52:24 +0000749 else if (other_thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000750 process.SetSelectedThread (other_thread);
Chris Lattner24943d22010-06-08 16:52:24 +0000751 else
752 {
753 if (curr_thread.IsValid())
754 thread = curr_thread;
755 else
756 thread = process.GetThreadAtIndex(0);
757
758 if (thread.IsValid())
Jim Inghamc8332952010-08-26 21:32:51 +0000759 process.SetSelectedThread (thread);
Chris Lattner24943d22010-06-08 16:52:24 +0000760 }
761 }
762 }
763}
764
765
766// This function handles events that were broadcast by the process.
767void
768Driver::HandleProcessEvent (const SBEvent &event)
769{
770 using namespace lldb;
771 const uint32_t event_type = event.GetType();
772
773 if (event_type & SBProcess::eBroadcastBitSTDOUT)
774 {
775 // The process has stdout available, get it and write it out to the
776 // appropriate place.
Caroline Tice4a348082011-05-02 20:41:46 +0000777 GetProcessSTDOUT ();
Chris Lattner24943d22010-06-08 16:52:24 +0000778 }
779 else if (event_type & SBProcess::eBroadcastBitSTDERR)
780 {
781 // The process has stderr available, get it and write it out to the
782 // appropriate place.
Caroline Tice4a348082011-05-02 20:41:46 +0000783 GetProcessSTDERR ();
Chris Lattner24943d22010-06-08 16:52:24 +0000784 }
785 else if (event_type & SBProcess::eBroadcastBitStateChanged)
786 {
787 // Drain all stout and stderr so we don't see any output come after
788 // we print our prompts
Caroline Tice4a348082011-05-02 20:41:46 +0000789 GetProcessSTDOUT ();
790 GetProcessSTDERR ();
Chris Lattner24943d22010-06-08 16:52:24 +0000791 // Something changed in the process; get the event and report the process's current status and location to
792 // the user.
793 StateType event_state = SBProcess::GetStateFromEvent (event);
794 if (event_state == eStateInvalid)
795 return;
796
797 SBProcess process (SBProcess::GetProcessFromEvent (event));
798 assert (process.IsValid());
799
800 switch (event_state)
801 {
802 case eStateInvalid:
803 case eStateUnloaded:
Greg Claytone71e2582011-02-04 01:58:07 +0000804 case eStateConnected:
Chris Lattner24943d22010-06-08 16:52:24 +0000805 case eStateAttaching:
806 case eStateLaunching:
807 case eStateStepping:
808 case eStateDetached:
809 {
810 char message[1024];
811 int message_len = ::snprintf (message, sizeof(message), "Process %d %s\n", process.GetProcessID(),
Greg Clayton63094e02010-06-23 01:19:29 +0000812 m_debugger.StateAsCString (event_state));
Caroline Tice4a348082011-05-02 20:41:46 +0000813 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner24943d22010-06-08 16:52:24 +0000814 }
815 break;
816
817 case eStateRunning:
818 // Don't be chatty when we run...
819 break;
820
821 case eStateExited:
Caroline Tice757500e2010-09-29 18:35:42 +0000822 {
823 SBCommandReturnObject result;
824 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
Caroline Tice4a348082011-05-02 20:41:46 +0000825 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
826 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
Caroline Tice757500e2010-09-29 18:35:42 +0000827 }
Chris Lattner24943d22010-06-08 16:52:24 +0000828 break;
829
830 case eStateStopped:
831 case eStateCrashed:
832 case eStateSuspended:
833 // Make sure the program hasn't been auto-restarted:
834 if (SBProcess::GetRestartedFromEvent (event))
835 {
836 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
837 char message[1024];
838 int message_len = ::snprintf (message, sizeof(message), "Process %d stopped and was programmatically restarted.\n",
839 process.GetProcessID());
Caroline Tice4a348082011-05-02 20:41:46 +0000840 m_io_channel_ap->OutWrite(message, message_len, ASYNC);
Chris Lattner24943d22010-06-08 16:52:24 +0000841 }
842 else
843 {
Caroline Tice757500e2010-09-29 18:35:42 +0000844 SBCommandReturnObject result;
Jim Inghamc8332952010-08-26 21:32:51 +0000845 UpdateSelectedThread ();
Caroline Tice757500e2010-09-29 18:35:42 +0000846 m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
Caroline Tice4a348082011-05-02 20:41:46 +0000847 m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
848 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
Chris Lattner24943d22010-06-08 16:52:24 +0000849 }
850 break;
851 }
852 }
853}
854
855// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
856
857bool
858Driver::HandleIOEvent (const SBEvent &event)
859{
860 bool quit = false;
861
862 const uint32_t event_type = event.GetType();
863
864 if (event_type & IOChannel::eBroadcastBitHasUserInput)
865 {
866 // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
867 // handling.
868
869 const char *command_string = SBEvent::GetCStringFromEvent(event);
870 if (command_string == NULL)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000871 command_string = "";
Chris Lattner24943d22010-06-08 16:52:24 +0000872 SBCommandReturnObject result;
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000873
Caroline Tice845d6da2011-05-16 19:20:50 +0000874 // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
875 // output orderings and problems with the prompt.
Jim Ingham2e8cb8a2011-02-19 02:53:09 +0000876 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
877
Caroline Tice845d6da2011-05-16 19:20:50 +0000878 if (result.GetOutputSize() > 0)
879 m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC);
880
881 if (result.GetErrorSize() > 0)
882 m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC);
883
Chris Lattner24943d22010-06-08 16:52:24 +0000884 // We are done getting and running our command, we can now clear the
885 // m_waiting_for_command so we can get another one.
886 m_waiting_for_command = false;
887
888 // If our editline input reader is active, it means another input reader
889 // got pushed onto the input reader and caused us to become deactivated.
890 // When the input reader above us gets popped, we will get re-activated
891 // and our prompt will refresh in our callback
892 if (m_editline_reader.IsActive())
893 {
894 ReadyForCommand ();
895 }
896 }
897 else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
898 {
899 // This is here to handle control-c interrupts from the user. It has not yet really been implemented.
900 // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER
901 //m_io_channel_ap->CancelInput();
902 // Anything else? Send Interrupt to process?
903 }
904 else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
905 (event_type & IOChannel::eBroadcastBitThreadDidExit))
906 {
907 // If the IOChannel thread is trying to go away, then it is definitely
908 // time to end the debugging session.
909 quit = true;
910 }
911
912 return quit;
913}
914
Chris Lattner24943d22010-06-08 16:52:24 +0000915void
916Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
917{
918 Driver *driver = (Driver*)baton;
919 driver->GetFromMaster ((const char *)src, src_len);
920}
921
922void
923Driver::GetFromMaster (const char *src, size_t src_len)
924{
925 // Echo the characters back to the Debugger's stdout, that way if you
926 // type characters while a command is running, you'll see what you've typed.
Greg Clayton63094e02010-06-23 01:19:29 +0000927 FILE *out_fh = m_debugger.GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000928 if (out_fh)
929 ::fwrite (src, 1, src_len, out_fh);
930}
931
932size_t
933Driver::EditLineInputReaderCallback
934(
935 void *baton,
936 SBInputReader *reader,
937 InputReaderAction notification,
938 const char *bytes,
939 size_t bytes_len
940)
941{
942 Driver *driver = (Driver *)baton;
943
944 switch (notification)
945 {
946 case eInputReaderActivate:
947 break;
948
949 case eInputReaderReactivate:
950 driver->ReadyForCommand();
951 break;
952
953 case eInputReaderDeactivate:
954 break;
Caroline Tice4a348082011-05-02 20:41:46 +0000955
956 case eInputReaderAsynchronousOutputWritten:
957 if (driver->m_io_channel_ap.get() != NULL)
958 driver->m_io_channel_ap->RefreshPrompt();
959 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000960
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000961 case eInputReaderInterrupt:
962 if (driver->m_io_channel_ap.get() != NULL)
963 {
Caroline Tice4a348082011-05-02 20:41:46 +0000964 driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000965 driver->m_io_channel_ap->RefreshPrompt();
966 }
967 break;
968
969 case eInputReaderEndOfFile:
970 if (driver->m_io_channel_ap.get() != NULL)
971 {
Caroline Tice4a348082011-05-02 20:41:46 +0000972 driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000973 driver->m_io_channel_ap->RefreshPrompt ();
974 }
975 write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
976 break;
977
Chris Lattner24943d22010-06-08 16:52:24 +0000978 case eInputReaderGotToken:
979 write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
980 break;
981
982 case eInputReaderDone:
983 break;
984 }
985 return bytes_len;
986}
987
988void
989Driver::MainLoop ()
990{
991 char error_str[1024];
992 if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
993 {
994 ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
995 exit(1);
996 }
997 else
998 {
999 const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
1000 if (driver_slave_name == NULL)
1001 {
1002 ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
1003 exit(2);
1004 }
1005 else
1006 {
1007 m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
1008 if (m_editline_slave_fh == NULL)
1009 {
1010 SBError error;
1011 error.SetErrorToErrno();
1012 ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
1013 error.GetCString());
1014 exit(3);
1015 }
1016
1017 ::setbuf (m_editline_slave_fh, NULL);
1018 }
1019 }
1020
Caroline Tice4a348082011-05-02 20:41:46 +00001021 lldb_utility::PseudoTerminal editline_output_pty;
1022 FILE *editline_output_slave_fh = NULL;
1023
1024 if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
1025 {
1026 ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
1027 exit(1);
1028 }
1029 else
1030 {
1031 const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
1032 if (output_slave_name == NULL)
1033 {
1034 ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
1035 exit(2);
1036 }
1037 else
1038 {
1039 editline_output_slave_fh = ::fopen (output_slave_name, "r+");
1040 if (editline_output_slave_fh == NULL)
1041 {
1042 SBError error;
1043 error.SetErrorToErrno();
1044 ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
1045 error.GetCString());
1046 exit(3);
1047 }
1048 ::setbuf (editline_output_slave_fh, NULL);
1049 }
1050 }
Chris Lattner24943d22010-06-08 16:52:24 +00001051
1052 // struct termios stdin_termios;
1053
1054 if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
1055 atexit (reset_stdin_termios);
1056
1057 ::setbuf (stdin, NULL);
1058 ::setbuf (stdout, NULL);
1059
Greg Clayton63094e02010-06-23 01:19:29 +00001060 m_debugger.SetErrorFileHandle (stderr, false);
1061 m_debugger.SetOutputFileHandle (stdout, false);
1062 m_debugger.SetInputFileHandle (stdin, true);
Jim Ingham74989e82010-08-30 19:44:40 +00001063
1064 m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
Chris Lattner24943d22010-06-08 16:52:24 +00001065
1066 // You have to drain anything that comes to the master side of the PTY. master_out_comm is
1067 // for that purpose. The reason you need to do this is a curious reason... editline will echo
1068 // characters to the PTY when it gets characters while el_gets is not running, and then when
1069 // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
1070 // if there are unconsumed characters in the out buffer.
1071 // However, you don't need to do anything with the characters, since editline will dump these
1072 // unconsumed characters after printing the prompt again in el_gets.
1073
Greg Claytoneecb0f32010-12-04 02:39:47 +00001074 SBCommunication master_out_comm("driver.editline");
1075 master_out_comm.SetCloseOnEOF (false);
Chris Lattner24943d22010-06-08 16:52:24 +00001076 master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
1077 master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
1078
1079 if (master_out_comm.ReadThreadStart () == false)
1080 {
1081 ::fprintf (stderr, "error: failed to start master out read thread");
1082 exit(5);
1083 }
1084
Greg Clayton63094e02010-06-23 01:19:29 +00001085 SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +00001086
Caroline Tice4a348082011-05-02 20:41:46 +00001087 m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
1088
1089 SBCommunication out_comm_2("driver.editline_output");
1090 out_comm_2.SetCloseOnEOF (false);
1091 out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
1092 out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
1093
1094 if (out_comm_2.ReadThreadStart () == false)
1095 {
1096 ::fprintf (stderr, "error: failed to start libedit output read thread");
1097 exit (5);
1098 }
1099
Chris Lattner24943d22010-06-08 16:52:24 +00001100
1101 struct winsize window_size;
1102 if (isatty (STDIN_FILENO)
1103 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1104 {
Caroline Tice6e4c5ce2010-09-04 00:03:46 +00001105 if (window_size.ws_col > 0)
Greg Clayton238c0a12010-09-18 01:14:36 +00001106 m_debugger.SetTerminalWidth (window_size.ws_col);
Chris Lattner24943d22010-06-08 16:52:24 +00001107 }
1108
1109 // Since input can be redirected by the debugger, we must insert our editline
1110 // input reader in the queue so we know when our reader should be active
1111 // and so we can receive bytes only when we are supposed to.
Greg Clayton63094e02010-06-23 01:19:29 +00001112 SBError err (m_editline_reader.Initialize (m_debugger,
1113 Driver::EditLineInputReaderCallback, // callback
Chris Lattner24943d22010-06-08 16:52:24 +00001114 this, // baton
1115 eInputReaderGranularityByte, // token_size
1116 NULL, // end token - NULL means never done
1117 NULL, // prompt - taken care of elsewhere
1118 false)); // echo input - don't need Debugger
1119 // to do this, we handle it elsewhere
1120
1121 if (err.Fail())
1122 {
1123 ::fprintf (stderr, "error: %s", err.GetCString());
1124 exit (6);
1125 }
1126
Greg Clayton63094e02010-06-23 01:19:29 +00001127 m_debugger.PushInputReader (m_editline_reader);
Chris Lattner24943d22010-06-08 16:52:24 +00001128
Greg Clayton63094e02010-06-23 01:19:29 +00001129 SBListener listener(m_debugger.GetListener());
Chris Lattner24943d22010-06-08 16:52:24 +00001130 if (listener.IsValid())
1131 {
1132
1133 listener.StartListeningForEvents (*m_io_channel_ap,
1134 IOChannel::eBroadcastBitHasUserInput |
1135 IOChannel::eBroadcastBitUserInterrupt |
1136 IOChannel::eBroadcastBitThreadShouldExit |
1137 IOChannel::eBroadcastBitThreadDidStart |
1138 IOChannel::eBroadcastBitThreadDidExit);
1139
1140 if (m_io_channel_ap->Start ())
1141 {
1142 bool iochannel_thread_exited = false;
1143
1144 listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
Caroline Tice388ca8f2011-05-03 20:53:11 +00001145 SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1146 SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1147 SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
Chris Lattner24943d22010-06-08 16:52:24 +00001148
1149 // Before we handle any options from the command line, we parse the
1150 // .lldbinit file in the user's home directory.
1151 SBCommandReturnObject result;
1152 sb_interpreter.SourceInitFileInHomeDirectory(result);
1153 if (GetDebugMode())
1154 {
Greg Clayton63094e02010-06-23 01:19:29 +00001155 result.PutError (m_debugger.GetErrorFileHandle());
1156 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner24943d22010-06-08 16:52:24 +00001157 }
1158
1159 // Now we handle options we got from the command line
1160 char command_string[PATH_MAX * 2];
1161 const size_t num_source_command_files = GetNumSourceCommandFiles();
1162 if (num_source_command_files > 0)
1163 {
1164 for (size_t i=0; i < num_source_command_files; ++i)
1165 {
1166 const char *command_file = GetSourceCommandFileAtIndex(i);
Johnny Chen7c984242010-07-28 21:16:11 +00001167 ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
Greg Clayton63094e02010-06-23 01:19:29 +00001168 m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
Chris Lattner24943d22010-06-08 16:52:24 +00001169 if (GetDebugMode())
1170 {
Greg Clayton63094e02010-06-23 01:19:29 +00001171 result.PutError (m_debugger.GetErrorFileHandle());
1172 result.PutOutput (m_debugger.GetOutputFileHandle());
Chris Lattner24943d22010-06-08 16:52:24 +00001173 }
1174 }
1175 }
1176
Greg Clayton4dc18922010-12-08 22:23:24 +00001177 const size_t num_args = m_option_data.m_args.size();
1178 if (num_args > 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001179 {
1180 char arch_name[64];
Greg Clayton63094e02010-06-23 01:19:29 +00001181 if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
Greg Clayton4dc18922010-12-08 22:23:24 +00001182 ::snprintf (command_string,
1183 sizeof (command_string),
Greg Claytonabe0fed2011-04-18 08:33:37 +00001184 "target create --arch=%s '%s'",
Greg Clayton4dc18922010-12-08 22:23:24 +00001185 arch_name,
1186 m_option_data.m_args[0].c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001187 else
Greg Clayton4dc18922010-12-08 22:23:24 +00001188 ::snprintf (command_string,
1189 sizeof(command_string),
Greg Claytonabe0fed2011-04-18 08:33:37 +00001190 "target create '%s'",
Greg Clayton4dc18922010-12-08 22:23:24 +00001191 m_option_data.m_args[0].c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001192
Greg Clayton63094e02010-06-23 01:19:29 +00001193 m_debugger.HandleCommand (command_string);
Greg Clayton4dc18922010-12-08 22:23:24 +00001194
1195 if (num_args > 1)
1196 {
1197 m_debugger.HandleCommand ("settings clear target.process.run-args");
1198 char arg_cstr[1024];
1199 for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
1200 {
1201 ::snprintf (arg_cstr, sizeof(arg_cstr), "settings append target.process.run-args \"%s\"", m_option_data.m_args[arg_idx].c_str());
1202 m_debugger.HandleCommand (arg_cstr);
1203 }
1204 }
Chris Lattner24943d22010-06-08 16:52:24 +00001205 }
1206
1207 // Now that all option parsing is done, we try and parse the .lldbinit
1208 // file in the current working directory
1209 sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
1210 if (GetDebugMode())
1211 {
Greg Clayton63094e02010-06-23 01:19:29 +00001212 result.PutError(m_debugger.GetErrorFileHandle());
1213 result.PutOutput(m_debugger.GetOutputFileHandle());
Chris Lattner24943d22010-06-08 16:52:24 +00001214 }
1215
1216 SBEvent event;
1217
1218 // Make sure the IO channel is started up before we try to tell it we
1219 // are ready for input
1220 listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
1221 *m_io_channel_ap,
1222 IOChannel::eBroadcastBitThreadDidStart,
1223 event);
1224
1225 ReadyForCommand ();
1226
1227 bool done = false;
1228 while (!done)
1229 {
1230 listener.WaitForEvent (UINT32_MAX, event);
1231 if (event.IsValid())
1232 {
1233 if (event.GetBroadcaster().IsValid())
1234 {
1235 uint32_t event_type = event.GetType();
1236 if (event.BroadcasterMatchesRef (*m_io_channel_ap))
1237 {
1238 if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
1239 (event_type & IOChannel::eBroadcastBitThreadDidExit))
1240 {
1241 done = true;
1242 if (event_type & IOChannel::eBroadcastBitThreadDidExit)
1243 iochannel_thread_exited = true;
Chris Lattner24943d22010-06-08 16:52:24 +00001244 }
1245 else
1246 done = HandleIOEvent (event);
1247 }
Jim Inghamc8332952010-08-26 21:32:51 +00001248 else if (event.BroadcasterMatchesRef (m_debugger.GetSelectedTarget().GetProcess().GetBroadcaster()))
Chris Lattner24943d22010-06-08 16:52:24 +00001249 {
1250 HandleProcessEvent (event);
1251 }
1252 else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
1253 {
1254 if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
1255 done = true;
Caroline Tice388ca8f2011-05-03 20:53:11 +00001256 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1257 {
1258 const char *data = SBEvent::GetCStringFromEvent (event);
1259 m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1260 }
1261 else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1262 {
1263 const char *data = SBEvent::GetCStringFromEvent (event);
1264 m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1265 }
Chris Lattner24943d22010-06-08 16:52:24 +00001266 }
1267 }
1268 }
1269 }
1270
1271 reset_stdin_termios ();
1272
1273 CloseIOChannelFile ();
1274
1275 if (!iochannel_thread_exited)
1276 {
Greg Claytonbef15832010-07-14 00:18:15 +00001277 event.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +00001278 listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
1279 IOChannel::eBroadcastBitThreadDidExit,
1280 event);
1281 if (!event.IsValid())
1282 {
1283 // Send end EOF to the driver file descriptor
1284 m_io_channel_ap->Stop();
1285 }
1286 }
1287
Jim Inghamc8332952010-08-26 21:32:51 +00001288 SBProcess process = m_debugger.GetSelectedTarget().GetProcess();
Chris Lattner24943d22010-06-08 16:52:24 +00001289 if (process.IsValid())
1290 process.Destroy();
1291 }
1292 }
1293}
1294
1295
1296void
1297Driver::ReadyForCommand ()
1298{
1299 if (m_waiting_for_command == false)
1300 {
1301 m_waiting_for_command = true;
1302 BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
1303 }
1304}
1305
1306
Caroline Ticeb8314fe2010-09-09 17:45:09 +00001307void
1308sigwinch_handler (int signo)
1309{
1310 struct winsize window_size;
1311 if (isatty (STDIN_FILENO)
1312 && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1313 {
1314 if ((window_size.ws_col > 0) && (strlen (g_debugger_name) > 0))
1315 {
1316 char width_str_buffer[25];
1317 ::sprintf (width_str_buffer, "%d", window_size.ws_col);
1318 SBDebugger::SetInternalVariable ("term-width", width_str_buffer, g_debugger_name);
1319 }
1320 }
1321}
1322
Caroline Ticec4f55fe2010-11-19 20:47:54 +00001323void
1324sigint_handler (int signo)
1325{
1326 static bool g_interrupt_sent = false;
1327 if (g_driver)
1328 {
1329 if (!g_interrupt_sent)
1330 {
1331 g_interrupt_sent = true;
1332 g_driver->GetDebugger().DispatchInputInterrupt();
1333 g_interrupt_sent = false;
1334 return;
1335 }
1336 }
1337
1338 exit (signo);
1339}
1340
Chris Lattner24943d22010-06-08 16:52:24 +00001341int
Jim Inghamb2b604f2011-01-27 20:15:39 +00001342main (int argc, char const *argv[], const char *envp[])
Chris Lattner24943d22010-06-08 16:52:24 +00001343{
Chris Lattner24943d22010-06-08 16:52:24 +00001344 SBDebugger::Initialize();
1345
Greg Clayton95e33b72010-11-07 21:02:03 +00001346 SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Chris Lattner24943d22010-06-08 16:52:24 +00001347
Greg Clayton36f63a92010-10-19 03:25:40 +00001348 signal (SIGPIPE, SIG_IGN);
Caroline Ticeb8314fe2010-09-09 17:45:09 +00001349 signal (SIGWINCH, sigwinch_handler);
Caroline Ticec4f55fe2010-11-19 20:47:54 +00001350 signal (SIGINT, sigint_handler);
Caroline Ticeb8314fe2010-09-09 17:45:09 +00001351
Greg Clayton63094e02010-06-23 01:19:29 +00001352 // Create a scope for driver so that the driver object will destroy itself
1353 // before SBDebugger::Terminate() is called.
Chris Lattner24943d22010-06-08 16:52:24 +00001354 {
Greg Clayton63094e02010-06-23 01:19:29 +00001355 Driver driver;
1356
1357 bool exit = false;
1358 SBError error (driver.ParseArgs (argc, argv, stdout, exit));
1359 if (error.Fail())
1360 {
1361 const char *error_cstr = error.GetCString ();
1362 if (error_cstr)
1363 ::fprintf (stderr, "error: %s\n", error_cstr);
1364 }
1365 else if (!exit)
1366 {
1367 driver.MainLoop ();
1368 }
Chris Lattner24943d22010-06-08 16:52:24 +00001369 }
1370
1371 SBDebugger::Terminate();
1372 return 0;
1373}