PatriosTheGreat created this revision. PatriosTheGreat added reviewers: teemperor, jarin. PatriosTheGreat requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Right now if the LLDB is compiled under the windows with static vcruntime library, the -o and -k commands will not work. The problem is that the LLDB create FILE* in lldb.exe and pass it to liblldb.dll which is an object from CRT. Since the CRT is statically linked each of these module has its own copy of the CRT with it's own global state and the LLDB should not share CRT objects between them. In this change I moved the logic of creating FILE* out of commands stream from Driver class to SBDebugger. To do this I added new method: SBError SBDebugger::SetInputStream(SBStream &stream) Command to build the LLDB: cmake -G Ninja -DLLVM_ENABLE_PROJECTS="clang;lldb;libcxx" -DLLVM_USE_CRT_RELEASE="MT" -DLLVM_USE_CRT_MINSIZEREL="MT" -DLLVM_USE_CRT_RELWITHDEBINFO="MT" -DP YTHON_HOME:FILEPATH=C:/Python38 -DCMAKE_C_COMPILER:STRING=cl.exe -DCMAKE_CXX_COMPILER:STRING=cl.exe ../llvm Command which will fail: lldb.exe -o help See discord discussion for more details: https://discord.com/channels/636084430946959380/636732809708306432/854629125398724628 This revision is for the further discussion. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D104413 Files: lldb/include/lldb/API/SBDebugger.h lldb/source/API/SBDebugger.cpp lldb/tools/driver/Driver.cpp
Index: lldb/tools/driver/Driver.cpp =================================================================== --- lldb/tools/driver/Driver.cpp +++ lldb/tools/driver/Driver.cpp @@ -23,7 +23,6 @@ #include "llvm/Support/Format.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" -#include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" @@ -42,14 +41,6 @@ #include <cstring> #include <fcntl.h> -// Includes for pipe() -#if defined(_WIN32) -#include <fcntl.h> -#include <io.h> -#else -#include <unistd.h> -#endif - #if !defined(__APPLE__) #include "llvm/Support/DataTypes.h" #endif @@ -400,60 +391,6 @@ return error; } -static inline int OpenPipe(int fds[2], std::size_t size) { -#ifdef _WIN32 - return _pipe(fds, size, O_BINARY); -#else - (void)size; - return pipe(fds); -#endif -} - -static ::FILE *PrepareCommandsForSourcing(const char *commands_data, - size_t commands_size) { - enum PIPES { READ, WRITE }; // Indexes for the read and write fds - int fds[2] = {-1, -1}; - - if (OpenPipe(fds, commands_size) != 0) { - WithColor::error() - << "can't create pipe file descriptors for LLDB commands\n"; - return nullptr; - } - - ssize_t nrwr = write(fds[WRITE], commands_data, commands_size); - if (size_t(nrwr) != commands_size) { - WithColor::error() - << format( - "write(%i, %p, %" PRIu64 - ") failed (errno = %i) when trying to open LLDB commands pipe", - fds[WRITE], static_cast<const void *>(commands_data), - static_cast<uint64_t>(commands_size), errno) - << '\n'; - llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]); - llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); - return nullptr; - } - - // Close the write end of the pipe, so that the command interpreter will exit - // when it consumes all the data. - llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); - - // Open the read file descriptor as a FILE * that we can return as an input - // handle. - ::FILE *commands_file = fdopen(fds[READ], "rb"); - if (commands_file == nullptr) { - WithColor::error() << format("fdopen(%i, \"rb\") failed (errno = %i) " - "when trying to open LLDB commands pipe", - fds[READ], errno) - << '\n'; - llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]); - return nullptr; - } - - // 'commands_file' now owns the read descriptor. - return commands_file; -} - std::string EscapeString(std::string arg) { std::string::size_type pos = 0; while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos) { @@ -583,21 +520,15 @@ // 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(); - bool go_interactive = true; - if ((commands_data != nullptr) && (commands_size != 0u)) { - FILE *commands_file = - PrepareCommandsForSourcing(commands_data, commands_size); - - if (commands_file == nullptr) { - // We should have already printed an error in PrepareCommandsForSourcing. + if ((commands_stream.GetData() != nullptr) && + (commands_stream.GetSize() != 0u)) { + SBError error = m_debugger.SetInputStream(commands_stream); + if (error.Fail()) { + WithColor::error() << error.GetCString() << '\n'; return 1; } - m_debugger.SetInputFileHandle(commands_file, true); - // Set the debugger into Sync mode when running the command file. Otherwise // command files that run the target won't run in a sensible way. bool old_async = m_debugger.GetAsync(); @@ -629,12 +560,8 @@ SBStream crash_commands_stream; WriteCommandsForSourcing(eCommandPlacementAfterCrash, crash_commands_stream); - const char *crash_commands_data = crash_commands_stream.GetData(); - const size_t crash_commands_size = crash_commands_stream.GetSize(); - commands_file = - PrepareCommandsForSourcing(crash_commands_data, crash_commands_size); - if (commands_file != nullptr) { - m_debugger.SetInputFileHandle(commands_file, true); + SBError error = m_debugger.SetInputStream(crash_commands_stream); + if (error.Success()) { SBCommandInterpreterRunResult local_results = m_debugger.RunCommandInterpreter(options); if (local_results.GetResult() == Index: lldb/source/API/SBDebugger.cpp =================================================================== --- lldb/source/API/SBDebugger.cpp +++ lldb/source/API/SBDebugger.cpp @@ -57,6 +57,15 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Process.h" + +// Includes for pipe() +#if defined(_WIN32) +#include <fcntl.h> +#include <io.h> +#else +#include <unistd.h> +#endif using namespace lldb; using namespace lldb_private; @@ -99,6 +108,15 @@ static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime; +static inline int OpenPipe(int fds[2], std::size_t size) { +#ifdef _WIN32 + return _pipe(fds, size, O_BINARY); +#else + (void)size; + return pipe(fds); +#endif +} + SBError SBInputReader::Initialize( lldb::SBDebugger &sb_debugger, unsigned long (*callback)(void *, lldb::SBInputReader *, @@ -330,6 +348,55 @@ SetInputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); } +SBError SBDebugger::SetInputStream(SBStream &stream) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputStream, (SBStream &), stream); + + SBError result; + enum PIPES { READ, WRITE }; // Indexes for the read and write fds + int fds[2] = {-1, -1}; + + if (OpenPipe(fds, stream.GetSize()) != 0) { + result.SetErrorString( + "can't create pipe file descriptors for LLDB commands"); + return result; + } + + ssize_t nrwr = write(fds[WRITE], stream.GetData(), stream.GetSize()); + if (size_t(nrwr) != stream.GetSize()) { + result.SetErrorStringWithFormat( + "write(%i, %p, %" PRIu64 + ") failed (errno = %i) when trying to open LLDB commands pipe", + fds[WRITE], static_cast<const void *>(stream.GetData()), + static_cast<uint64_t>(stream.GetSize()), errno); + + llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]); + llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); + return result; + } + + // Close the write end of the pipe, so that the command interpreter will exit + // when it consumes all the data. + llvm::sys::Process::SafelyCloseFileDescriptor(fds[WRITE]); + + // Open the read file descriptor as a FILE * that we can return as an input + // handle. + FILE *commands_file = fdopen(fds[READ], "rb"); + if (commands_file == nullptr) { + result.SetErrorStringWithFormat("fdopen(%i, \"rb\") failed (errno = %i) " + "when trying to open LLDB commands pipe", + fds[READ], errno); + llvm::sys::Process::SafelyCloseFileDescriptor(fds[READ]); + return result; + } + + if (result.Fail()) { + return result; + } + + return LLDB_RECORD_RESULT( + SetInputFile((FileSP)std::make_shared<NativeFile>(commands_file, true))); +} + SBError SBDebugger::SetInputFile(FileSP file_sp) { LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp); return LLDB_RECORD_RESULT(SetInputFile(SBFile(file_sp))); @@ -1760,6 +1827,7 @@ LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ()); LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool)); LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles, (bool)); + LLDB_REGISTER_METHOD(SBError, SBDebugger, SetInputStream, (SBStream &)); LLDB_REGISTER_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool)); LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ()); LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ()); Index: lldb/include/lldb/API/SBDebugger.h =================================================================== --- lldb/include/lldb/API/SBDebugger.h +++ lldb/include/lldb/API/SBDebugger.h @@ -126,6 +126,8 @@ FILE *GetErrorFileHandle(); + SBError SetInputStream(SBStream &stream); + SBError SetInputFile(SBFile file); SBError SetOutputFile(SBFile file);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits