Bug Summary

File:tools/lldb/tools/driver/Driver.cpp
Location:line 914, column 17
Description:Value stored to 'success' is never read

Annotated Source Code

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