[Lldb-commits] [lldb] 9bcaf6d - [lldb-vscode] Implement stderr/stdout on win32 and redirect lldb log to VSCode
Walter Erquinigo via lldb-commits
lldb-commits at lists.llvm.org
Tue Apr 5 11:54:11 PDT 2022
Author: Walter Erquinigo
Date: 2022-04-05T11:54:03-07:00
New Revision: 9bcaf6ddfe34943e6ae6a319097524c117908913
URL: https://github.com/llvm/llvm-project/commit/9bcaf6ddfe34943e6ae6a319097524c117908913
DIFF: https://github.com/llvm/llvm-project/commit/9bcaf6ddfe34943e6ae6a319097524c117908913.diff
LOG: [lldb-vscode] Implement stderr/stdout on win32 and redirect lldb log to VSCode
This patch implements stderr/stdout forwarding on windows.
This was previously not implemented in D99974.
I added separate callbacks so the output can be sent to the different channels VSCode provides (OutputType::Stdout, OutputType::Stderr, OutputType::Console).
This patch also passes a log callback handler to SBDebugger::Create to be able to see logging output when it is enabled.
Since the output is now redirect on early startup I removed the calls to SetOutputFileHandle/SetErrorFileHandle, which set them to /dev/null.
I send the output of stderr/stdout/lldb log to OutputType::Console
Reviewed By: wallace
Differential Revision: https://reviews.llvm.org/D123025
Added:
Modified:
lldb/tools/lldb-vscode/OutputRedirector.cpp
lldb/tools/lldb-vscode/lldb-vscode.cpp
Removed:
################################################################################
diff --git a/lldb/tools/lldb-vscode/OutputRedirector.cpp b/lldb/tools/lldb-vscode/OutputRedirector.cpp
index 7432a828d045b..9243915f7d787 100644
--- a/lldb/tools/lldb-vscode/OutputRedirector.cpp
+++ b/lldb/tools/lldb-vscode/OutputRedirector.cpp
@@ -6,20 +6,27 @@
//
//===----------------------------------------------------------------------===/
-#if !defined(_WIN32)
+#if defined(_WIN32)
+#include <fcntl.h>
+#include <io.h>
+#else
#include <unistd.h>
#endif
#include "OutputRedirector.h"
+#include "llvm/ADT/StringRef.h"
using namespace llvm;
namespace lldb_vscode {
Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) {
-#if !defined(_WIN32)
int new_fd[2];
+#if defined(_WIN32)
+ if (_pipe(new_fd, 4096, O_TEXT) == -1) {
+#else
if (pipe(new_fd) == -1) {
+#endif
int error = errno;
return createStringError(inconvertibleErrorCode(),
"Couldn't create new pipe for fd %d. %s", fd,
@@ -45,11 +52,10 @@ Error RedirectFd(int fd, std::function<void(llvm::StringRef)> callback) {
continue;
break;
}
- callback(StringRef(buffer, bytes_count).str());
+ callback(StringRef(buffer, bytes_count));
}
});
t.detach();
-#endif
return Error::success();
}
diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp
index 83a9762df6040..869c125ec0340 100644
--- a/lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -65,11 +65,6 @@
#define PATH_MAX MAX_PATH
#endif
typedef int socklen_t;
-constexpr const char *dev_null_path = "nul";
-
-#else
-constexpr const char *dev_null_path = "/dev/null";
-
#endif
using namespace lldb_vscode;
@@ -1446,23 +1441,13 @@ void request_modules(const llvm::json::Object &request) {
// }]
// }
void request_initialize(const llvm::json::Object &request) {
- g_vsc.debugger = lldb::SBDebugger::Create(true /*source_init_files*/);
+ auto log_cb = [](const char *buf, void *baton) -> void {
+ g_vsc.SendOutput(OutputType::Console, llvm::StringRef{buf});
+ };
+ g_vsc.debugger =
+ lldb::SBDebugger::Create(true /*source_init_files*/, log_cb, nullptr);
g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
- // Create an empty target right away since we might get breakpoint requests
- // before we are given an executable to launch in a "launch" request, or a
- // executable when attaching to a process by process ID in a "attach"
- // request.
- FILE *out = llvm::sys::RetryAfterSignal(nullptr, fopen, dev_null_path, "w");
- if (out) {
- // Set the output and error file handles to redirect into nothing otherwise
- // if any code in LLDB prints to the debugger file handles, the output and
- // error file handles are initialized to STDOUT and STDERR and any output
- // will kill our debug session.
- g_vsc.debugger.SetOutputFileHandle(out, true);
- g_vsc.debugger.SetErrorFileHandle(out, false);
- }
-
// Start our event thread so we can receive events from the debugger, target,
// process and more.
g_vsc.event_thread = std::thread(EventThreadFunction);
@@ -3147,18 +3132,25 @@ void redirection_test() {
/// \return
/// A fd pointing to the original stdout.
int SetupStdoutStderrRedirection() {
- int new_stdout_fd = dup(fileno(stdout));
- auto stdout_err_redirector_callback = [&](llvm::StringRef data) {
- g_vsc.SendOutput(OutputType::Console, data);
+ int stdoutfd = fileno(stdout);
+ int new_stdout_fd = dup(stdoutfd);
+ auto output_callback_stderr = [](llvm::StringRef data) {
+ g_vsc.SendOutput(OutputType::Stderr, data);
};
-
- for (int fd : {fileno(stdout), fileno(stderr)}) {
- if (llvm::Error err = RedirectFd(fd, stdout_err_redirector_callback)) {
- std::string error_message = llvm::toString(std::move(err));
- if (g_vsc.log)
- *g_vsc.log << error_message << std::endl;
- stdout_err_redirector_callback(error_message);
- }
+ auto output_callback_stdout = [](llvm::StringRef data) {
+ g_vsc.SendOutput(OutputType::Stdout, data);
+ };
+ if (llvm::Error err = RedirectFd(stdoutfd, output_callback_stdout)) {
+ std::string error_message = llvm::toString(std::move(err));
+ if (g_vsc.log)
+ *g_vsc.log << error_message << std::endl;
+ output_callback_stderr(error_message);
+ }
+ if (llvm::Error err = RedirectFd(fileno(stderr), output_callback_stderr)) {
+ std::string error_message = llvm::toString(std::move(err));
+ if (g_vsc.log)
+ *g_vsc.log << error_message << std::endl;
+ output_callback_stderr(error_message);
}
/// used only by TestVSCode_redirection_to_console.py
More information about the lldb-commits
mailing list