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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits