[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