From 0cac4ca3916ac24ab6139d03cbfd18db9e715bfe Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 25 Nov 2014 21:00:58 +0000 Subject: Import LLDB as of upstream SVN r216948 (git 50f7fe44) This corresponds with the branchpoint for the 3.5 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL --- tools/driver/Driver.cpp | 242 +++++++++++++++++++++++++++------------------- tools/driver/Driver.h | 5 +- tools/driver/Platform.cpp | 25 ++--- tools/driver/Platform.h | 56 ++++++----- 4 files changed, 184 insertions(+), 144 deletions(-) (limited to 'tools/driver') diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp index 78d3a7e1c037..854310031c37 100644 --- a/tools/driver/Driver.cpp +++ b/tools/driver/Driver.cpp @@ -15,6 +15,14 @@ #include #include +// Includes for pipe() +#if defined(_WIN32) +#include +#include +#else +#include +#endif + #include #include @@ -477,63 +485,19 @@ Driver::GetScriptLanguage() const } void -Driver::ExecuteInitialCommands (bool before_file) +Driver::WriteInitialCommands (bool before_file, SBStream &strm) { - size_t num_commands; - std::vector > *command_set; - if (before_file) - command_set = &(m_option_data.m_initial_commands); - else - command_set = &(m_option_data.m_after_file_commands); + std::vector > &command_set = before_file ? m_option_data.m_initial_commands : + m_option_data.m_after_file_commands; - num_commands = command_set->size(); - SBCommandReturnObject result; - bool old_async = GetDebugger().GetAsync(); - GetDebugger().SetAsync(false); - for (size_t idx = 0; idx < num_commands; idx++) + for (const auto &command_pair : command_set) { - bool is_file = (*command_set)[idx].first; - const char *command = (*command_set)[idx].second.c_str(); - char command_string[PATH_MAX * 2]; - const bool dump_stream_only_if_no_immediate = true; - const char *executed_command = command; - if (is_file) - { - ::snprintf (command_string, sizeof(command_string), "command source -s %i '%s'", m_option_data.m_source_quietly, command); - executed_command = command_string; - } - - m_debugger.GetCommandInterpreter().HandleCommand (executed_command, result, false); - if (!m_option_data.m_source_quietly || result.Succeeded() == false) - { - const size_t output_size = result.GetOutputSize(); - if (output_size > 0) - { - const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate); - if (cstr) - printf ("%s", cstr); - } - const size_t error_size = result.GetErrorSize(); - if (error_size > 0) - { - const char *cstr = result.GetError(dump_stream_only_if_no_immediate); - if (cstr) - printf ("%s", cstr); - } - } - - if (result.Succeeded() == false) - { - const char *type = before_file ? "before file" : "after_file"; - if (is_file) - ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command); - else - ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command); - break; - } - result.Clear(); + const char *command = command_pair.second.c_str(); + if (command_pair.first) + strm.Printf("command source -s %i '%s'\n", m_option_data.m_source_quietly, command); + else + strm.Printf("%s\n", command); } - GetDebugger().SetAsync(old_async); } bool @@ -857,8 +821,8 @@ Driver::MainLoop () m_debugger.SetErrorFileHandle (stderr, false); m_debugger.SetOutputFileHandle (stdout, false); - m_debugger.SetInputFileHandle (stdin, true); - + m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet... + m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor); struct winsize window_size; @@ -882,77 +846,61 @@ Driver::MainLoop () } // Now we handle options we got from the command line - // First source in the commands specified to be run before the file arguments are processed. - ExecuteInitialCommands(true); - - // Was there a core file specified? - std::string core_file_spec(""); - if (!m_option_data.m_core_file.empty()) - core_file_spec.append("--core ").append(m_option_data.m_core_file); + SBStream commands_stream; - char command_string[PATH_MAX * 2]; + // First source in the commands specified to be run before the file arguments are processed. + WriteInitialCommands(true, commands_stream); + const size_t num_args = m_option_data.m_args.size(); if (num_args > 0) { char arch_name[64]; if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) - ::snprintf (command_string, - sizeof (command_string), - "target create --arch=%s %s \"%s\"", - arch_name, - core_file_spec.c_str(), - m_option_data.m_args[0].c_str()); + commands_stream.Printf("target create --arch=%s \"%s\"", arch_name, m_option_data.m_args[0].c_str()); else - ::snprintf (command_string, - sizeof(command_string), - "target create %s \"%s\"", - core_file_spec.c_str(), - m_option_data.m_args[0].c_str()); - - m_debugger.HandleCommand (command_string); + commands_stream.Printf("target create \"%s\"", m_option_data.m_args[0].c_str()); + + if (!m_option_data.m_core_file.empty()) + { + commands_stream.Printf(" --core \"%s\"", m_option_data.m_core_file.c_str()); + } + commands_stream.Printf("\n"); if (num_args > 1) { - m_debugger.HandleCommand ("settings clear target.run-args"); - char arg_cstr[1024]; + commands_stream.Printf ("settings set -- target.run-args "); for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) { - ::snprintf (arg_cstr, - sizeof(arg_cstr), - "settings append target.run-args \"%s\"", - m_option_data.m_args[arg_idx].c_str()); - m_debugger.HandleCommand (arg_cstr); + const char *arg_cstr = m_option_data.m_args[arg_idx].c_str(); + if (strchr(arg_cstr, '"') == NULL) + commands_stream.Printf(" \"%s\"", arg_cstr); + else + commands_stream.Printf(" '%s'", arg_cstr); } + commands_stream.Printf("\n"); } } - else if (!core_file_spec.empty()) + else if (!m_option_data.m_core_file.empty()) { - ::snprintf (command_string, - sizeof(command_string), - "target create %s", - core_file_spec.c_str()); - m_debugger.HandleCommand (command_string);; + commands_stream.Printf("target create --core \"%s\"\n", m_option_data.m_core_file.c_str()); } else if (!m_option_data.m_process_name.empty()) { - ::snprintf (command_string, - sizeof(command_string), - "process attach --name '%s'%s", - m_option_data.m_process_name.c_str(), - m_option_data.m_wait_for ? " --waitfor" : ""); - m_debugger.HandleCommand (command_string); + commands_stream.Printf ("process attach --name \"%s\"", m_option_data.m_process_name.c_str()); + + if (m_option_data.m_wait_for) + commands_stream.Printf(" --waitfor"); + + commands_stream.Printf("\n"); + } else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid) { - ::snprintf (command_string, - sizeof(command_string), - "process attach --pid %" PRIu64, - m_option_data.m_process_pid); - m_debugger.HandleCommand (command_string); + commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid); } - ExecuteInitialCommands(false); - + WriteInitialCommands(false, commands_stream); + // Now that all option parsing is done, we try and parse the .lldbinit // file in the current working directory sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result); @@ -964,6 +912,90 @@ Driver::MainLoop () bool handle_events = true; bool spawn_thread = false; + + // Check if we have any data in the commands stream, and if so, save it to a temp file + // so we can then run the command interpreter using the file contents. + const char *commands_data = commands_stream.GetData(); + const size_t commands_size = commands_stream.GetSize(); + if (commands_data && commands_size) + { + enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE + + bool success = true; + int fds[2] = { -1, -1 }; + int err = 0; +#ifdef _WIN32 + err = _pipe(fds, commands_size, O_BINARY); +#else + err = pipe(fds); +#endif + if (err == 0) + { + if (write (fds[WRITE], commands_data, commands_size) == commands_size) + { + // Close the write end of the pipe so when we give the read end to + // the debugger/command interpreter it will exit when it consumes all + // of the data +#ifdef _WIN32 + _close(fds[WRITE]); fds[WRITE] = -1; +#else + close(fds[WRITE]); fds[WRITE] = -1; +#endif + // Now open the read file descriptor in a FILE * that we can give to + // the debugger as an input handle + FILE *commands_file = fdopen(fds[READ], "r"); + if (commands_file) + { + fds[READ] = -1; // The FILE * 'commands_file' now owns the read descriptor + // Hand ownership if the FILE * over to the debugger for "commands_file". + m_debugger.SetInputFileHandle (commands_file, true); + m_debugger.RunCommandInterpreter(handle_events, spawn_thread); + } + else + { + fprintf(stderr, "error: fdopen(%i, \"r\") failed (errno = %i) when trying to open LLDB commands pipe\n", fds[READ], errno); + success = false; + } + } + } + else + { + fprintf(stderr, "error: can't create pipe file descriptors for LLDB commands\n"); + success = false; + } + + // Close any pipes that we still have ownership of + if ( fds[WRITE] != -1) + { +#ifdef _WIN32 + _close(fds[WRITE]); fds[WRITE] = -1; +#else + close(fds[WRITE]); fds[WRITE] = -1; +#endif + + } + + if ( fds[READ] != -1) + { +#ifdef _WIN32 + _close(fds[READ]); fds[READ] = -1; +#else + close(fds[READ]); fds[READ] = -1; +#endif + } + + // Something went wrong with command pipe + if (!success) + { + exit(1); + } + + } + + // Now set the input file handle to STDIN and run the command + // interpreter again in interactive mode and let the debugger + // take ownership of stdin + m_debugger.SetInputFileHandle (stdin, true); m_debugger.RunCommandInterpreter(handle_events, spawn_thread); reset_stdin_termios(); @@ -1032,6 +1064,12 @@ sigcont_handler (int signo) int main (int argc, char const *argv[], const char *envp[]) { +#ifdef _MSC_VER + // disable buffering on windows + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdin , NULL, _IONBF, 0); +#endif + SBDebugger::Initialize(); SBHostOS::ThreadCreated (""); diff --git a/tools/driver/Driver.h b/tools/driver/Driver.h index 699244685d06..8b6c6eebdd56 100644 --- a/tools/driver/Driver.h +++ b/tools/driver/Driver.h @@ -23,9 +23,6 @@ #include "lldb/API/SBDebugger.h" #include "lldb/API/SBError.h" -#define ASYNC true -#define NO_ASYNC false - class IOChannel; class Driver : public lldb::SBBroadcaster @@ -55,7 +52,7 @@ public: GetScriptLanguage() const; void - ExecuteInitialCommands (bool before_file); + WriteInitialCommands (bool before_file, lldb::SBStream &strm); bool GetDebugMode() const; diff --git a/tools/driver/Platform.cpp b/tools/driver/Platform.cpp index 5b5286e68114..a49161540872 100644 --- a/tools/driver/Platform.cpp +++ b/tools/driver/Platform.cpp @@ -8,17 +8,14 @@ //===----------------------------------------------------------------------===// // this file is only relevant for Visual C++ -#if defined( _MSC_VER ) +#if defined( _WIN32 ) #include #include +#include #include "Platform.h" -// index one of the variable arguments -// presuming "(EditLine *el, ..." is first in the argument list -#define GETARG( Y, X ) ( (void* ) *( ( (int**) &(Y) ) + (X) ) ) - // the control handler or SIGINT handler static sighandler_t _ctrlHandler = NULL; @@ -42,14 +39,16 @@ ioctl (int d, int request, ...) // request the console windows size case ( TIOCGWINSZ ): { - // locate the window size structure on stack - winsize *ws = (winsize*) GETARG( d, 2 ); + va_list vl; + va_start(vl,request); + // locate the window size structure on stack + winsize *ws = va_arg(vl, winsize*); // get screen buffer information CONSOLE_SCREEN_BUFFER_INFO info; - GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info ); - // fill in the columns - ws->ws_col = info.dwMaximumWindowSize.X; - // + if ( GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info ) == TRUE ) + // fill in the columns + ws->ws_col = info.dwMaximumWindowSize.X; + va_end(vl); return 0; } break; @@ -85,6 +84,7 @@ tcgetattr (int fildes, struct termios *termios_p) return -1; } +#ifdef _MSC_VER sighandler_t signal (int sig, sighandler_t sigFunc) { @@ -107,5 +107,6 @@ signal (int sig, sighandler_t sigFunc) } return 0; } +#endif -#endif \ No newline at end of file +#endif diff --git a/tools/driver/Platform.h b/tools/driver/Platform.h index faa2991bf6f3..e26610711aca 100644 --- a/tools/driver/Platform.h +++ b/tools/driver/Platform.h @@ -10,22 +10,18 @@ #ifndef lldb_Platform_h_ #define lldb_Platform_h_ -#if defined( _MSC_VER ) +#include "lldb/Host/HostGetOpt.h" + +#if defined( _WIN32 ) // this will stop signal.h being included #define _INC_SIGNAL - #include +#if defined( _MSC_VER ) #include +#endif #include - #include "lldb/Host/windows/Windows.h" - #include "lldb/Host/HostGetOpt.h" - - struct timeval - { - long tv_sec; - long tv_usec; - }; + #include "lldb/Host/windows/windows.h" struct winsize { @@ -42,6 +38,17 @@ // ioctls.h #define TIOCGWINSZ 0x5413 + + // signal handler function pointer type + typedef void(*sighandler_t)(int); + + // signal.h + #define SIGINT 2 + // default handler + #define SIG_DFL ( (sighandler_t) -1 ) + // ignored + #define SIG_IGN ( (sighandler_t) -2 ) + // signal.h #define SIGPIPE 13 #define SIGCONT 18 @@ -64,34 +71,31 @@ speed_t c_ospeed; // output speed }; - typedef long pid_t; - #define STDIN_FILENO 0 - #define PATH_MAX MAX_PATH +#ifdef _MSC_VER + struct timeval + { + long tv_sec; + long tv_usec; + }; + typedef long pid_t; #define snprintf _snprintf + extern sighandler_t signal( int sig, sighandler_t ); + #define PATH_MAX MAX_PATH +#endif + + #define STDIN_FILENO 0 extern int ioctl( int d, int request, ... ); extern int kill ( pid_t pid, int sig ); extern int tcsetattr( int fd, int optional_actions, const struct termios *termios_p ); extern int tcgetattr( int fildes, struct termios *termios_p ); - // signal handler function pointer type - typedef void (*sighandler_t)(int); - - // signal.h - #define SIGINT 2 - // default handler - #define SIG_DFL ( (sighandler_t) -1 ) - // ignored - #define SIG_IGN ( (sighandler_t) -2 ) - extern sighandler_t signal( int sig, sighandler_t ); - #else #include - #include #include #include #include @@ -101,7 +105,7 @@ #include #include - #if defined(__FreeBSD__) + #if defined(__FreeBSD__) || defined(__NetBSD__) #include #else #include -- cgit v1.2.3