aadsm updated this revision to Diff 276894. aadsm added a comment. This update still doesn't add windows support but I just want to get a feel that I'm going on the right direction. It addresses the following:
- redirect stdout/err as early as possible to avoid something writing to it, and only starts or ends redirection it once it's safe. - adds a mutex to OutputStream::write_full to make sure multiple threads don't try to write to the output fd at the same time. > We should also think about testing all of this. Do we have a reliable > mechanism to produce stdout/err output from lldb? this turned out to be harder than I thought it would be, my plan was to print to stdout in python from a thread but I never see that print anywhere (not sure why though). A sure way to test this (what I did manually) is to put a `script print('foo')` command in lldninit. Unfortunately I can't use a local lldbinit since that's a concept of the lldb binary and not of liblldb (unless we want to add that option to lldb-vscode as well), so not really sure about this as well. I also tried to use a `breakpoint command add -o 'script print("foo")'` but same behaviour, I never saw that print. Still don't know how to tackle this, need to think more about it. > Or, if this output is going to the same place as the SBDebuggers notion of > stdout/err, There no guarantee of this, people can just use sys.stdout.write in python. > given that Richard has found some vscode code which already tries to send > stderr to the console window I would still prefer to wrap liblldb's stderr into a console message so people can see it in the client(e.g.: VSCode) console rather than outputting it through the lldb-vscode stderr which will then be up to the client to decide what to do with it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D80659/new/ https://reviews.llvm.org/D80659 Files: lldb/tools/lldb-vscode/IOStream.cpp lldb/tools/lldb-vscode/IOStream.h lldb/tools/lldb-vscode/lldb-vscode.cpp
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp =================================================================== --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -486,6 +486,43 @@ } } +class FileDescriptorToConsoleOutputRedirector { + private: + int m_captured_fd[2]; + std::thread m_thread; + + public: + FileDescriptorToConsoleOutputRedirector(int fd) { + pipe(m_captured_fd); + dup2(m_captured_fd[1], fd); + }; + ~FileDescriptorToConsoleOutputRedirector() { + StopRedirecting(); + } + // Only call this once. + void StartRedirecting() { + int read_fd = m_captured_fd[0]; + + m_thread = std::thread([read_fd] { + char buffer[4096]; + while (true) { + ssize_t bytes_count = read(read_fd, &buffer, sizeof(buffer)); + if (bytes_count == 0) + return; + g_vsc.SendOutput(OutputType::Console, buffer); + } + }); + m_thread.detach(); + } + + void StopRedirecting() { + if (!m_thread.joinable()) + return; + close(m_captured_fd[1]); + m_thread.join(); + } +}; + // "AttachRequest": { // "allOf": [ { "$ref": "#/definitions/Request" }, { // "type": "object", @@ -2781,7 +2818,9 @@ } int main(int argc, char *argv[]) { - + int stdout_fd = dup(fileno(stdout)); + FileDescriptorToConsoleOutputRedirector stdout_redirector(fileno(stdout)); + FileDescriptorToConsoleOutputRedirector stderr_redirector(fileno(stderr)); // Initialize LLDB first before we do anything. lldb::SBDebugger::Initialize(); @@ -2824,9 +2863,11 @@ } } else { g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false); - g_vsc.output.descriptor = - StreamDescriptor::from_file(fileno(stdout), false); + g_vsc.output.descriptor = StreamDescriptor::from_file(stdout_fd, false); } + // Can start redirecting now that the output description has been properly set. + stdout_redirector.StartRedirecting(); + stderr_redirector.StartRedirecting(); auto request_handlers = GetRequestHandlers(); uint32_t packet_idx = 0; while (!g_vsc.sent_terminated_event) { @@ -2875,5 +2916,9 @@ // We must terminate the debugger in a thread before the C++ destructor // chain messes everything up. lldb::SBDebugger::Terminate(); + // Can now safely stop redirecting since lldb will no longer emit stdout + // or stderr messages. + stdout_redirector.StopRedirecting(); + stderr_redirector.StopRedirecting(); return 0; } Index: lldb/tools/lldb-vscode/IOStream.h =================================================================== --- lldb/tools/lldb-vscode/IOStream.h +++ lldb/tools/lldb-vscode/IOStream.h @@ -63,6 +63,9 @@ StreamDescriptor descriptor; bool write_full(llvm::StringRef str); + + private: + std::mutex m_mutex; }; } // namespace lldb_vscode Index: lldb/tools/lldb-vscode/IOStream.cpp =================================================================== --- lldb/tools/lldb-vscode/IOStream.cpp +++ lldb/tools/lldb-vscode/IOStream.cpp @@ -70,6 +70,7 @@ } bool OutputStream::write_full(llvm::StringRef str) { + std::lock_guard<std::mutex> lock(m_mutex); while (!str.empty()) { int bytes_written = 0; if (descriptor.m_is_socket)
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits