Skip to content

Conversation

charles-zablit
Copy link
Contributor

This patch makes LLDB use the Event Viewer on Windows (equivalent of system logging on Darwin) rather than piping to the standard output (which was deactivated in ca0a524.

@llvmbot
Copy link
Member

llvmbot commented Jul 23, 2025

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

Changes

This patch makes LLDB use the Event Viewer on Windows (equivalent of system logging on Darwin) rather than piping to the standard output (which was deactivated in ca0a524.


Full diff: https://github.com/llvm/llvm-project/pull/150213.diff

3 Files Affected:

  • (modified) lldb/include/lldb/Host/Host.h (+4)
  • (modified) lldb/source/Host/common/Host.cpp (+17-4)
  • (modified) lldb/source/Host/windows/Host.cpp (+63)
diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index 4e19d15b06743..fcabb4fc28315 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -109,6 +109,10 @@ class Host {
   /// Emit the given message to the operating system log.
   static void SystemLog(lldb::Severity severity, llvm::StringRef message);
 
+  /// Emit the given message to the stdout or stderr depending on severity.
+  static void SystemLogFallback(lldb::Severity severity,
+                                llvm::StringRef message);
+
   /// Get the process ID for the calling process.
   ///
   /// \return
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index 5992b54318f73..d2737c23313a4 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -82,14 +82,27 @@ int __pthread_fchdir(int fildes);
 using namespace lldb;
 using namespace lldb_private;
 
-#if !defined(__APPLE__)
-// The system log is currently only meaningful on Darwin, where this means
-// os_log. The meaning of a "system log" isn't as clear on other platforms, and
-// therefore we don't providate a default implementation. Vendors are free to
+#if !defined(__APPLE__) && !defined(_WIN32)
+// The system log is currently only meaningful on Darwin and Windows.
+// On Darwin, this means os_log. On Windows this means Events Viewer.
+// The meaning of a "system log" isn't as clear on other platforms, and
+// therefore we don't providate a default implementation. Vendors are free
 // to implement this function if they have a use for it.
 void Host::SystemLog(Severity severity, llvm::StringRef message) {}
 #endif
 
+void Host::SystemLogFallback(Severity severity, llvm::StringRef message) {
+  switch (severity) {
+  case lldb::eSeverityInfo:
+  case lldb::eSeverityWarning:
+    llvm::outs() << message;
+    return;
+  case lldb::eSeverityError:
+    llvm::errs() << message;
+    return;
+  }
+}
+
 static constexpr Log::Category g_categories[] = {
     {{"system"}, {"system log"}, SystemLog::System}};
 
diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp
index a7369e7eade3b..38c862e968302 100644
--- a/lldb/source/Host/windows/Host.cpp
+++ b/lldb/source/Host/windows/Host.cpp
@@ -22,7 +22,9 @@
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StructuredData.h"
 
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ManagedStatic.h"
 
 // Windows includes
 #include <tlhelp32.h>
@@ -302,3 +304,64 @@ Environment Host::GetEnvironment() {
   }
   return env;
 }
+
+/// Manages the lifecycle of a Windows Event's Source.
+/// The destructor will call DeregisterEventSource.
+/// This class is meant to be used with \ref llvm::ManagedStatic.
+class WindowsEventLog {
+public:
+  WindowsEventLog() : handle(RegisterEventSource(nullptr, L"lldb")) {}
+
+  ~WindowsEventLog() {
+    if (handle)
+      DeregisterEventSource(handle);
+  }
+
+  HANDLE GetHandle() const { return handle; }
+
+private:
+  HANDLE handle;
+};
+
+static llvm::ManagedStatic<WindowsEventLog> event_log;
+
+static LPCWSTR AnsiToUtf16(const std::string &ansi) {
+  if (ansi.empty())
+    return nullptr;
+  const int unicode_length =
+      MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, nullptr, 0);
+  WCHAR *unicode = new WCHAR[unicode_length];
+  MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, unicode, unicode_length);
+  return unicode;
+}
+
+void Host::SystemLog(Severity severity, llvm::StringRef message) {
+  HANDLE h = event_log->GetHandle();
+  if (!h) {
+    SystemLogFallback(severity, message);
+    return;
+  }
+
+  LPCWSTR wide_message = AnsiToUtf16(message.str());
+  if (!wide_message) {
+    SystemLogFallback(severity, message);
+    return;
+  }
+
+  WORD event_type;
+  switch (severity) {
+  case lldb::eSeverityWarning:
+    event_type = EVENTLOG_WARNING_TYPE;
+    break;
+  case lldb::eSeverityError:
+    event_type = EVENTLOG_ERROR_TYPE;
+    break;
+  case lldb::eSeverityInfo:
+  default:
+    event_type = EVENTLOG_INFORMATION_TYPE;
+  }
+
+  ReportEventW(h, event_type, 0, 0, nullptr, 1, 0, &wide_message, nullptr);
+
+  delete[] wide_message;
+}
\ No newline at end of file

@charles-zablit
Copy link
Contributor Author

This is what it looks like for Swift:

467487049-3e330366-06a0-4dc1-8725-0912ecc7dfdc

static void SystemLog(lldb::Severity severity, llvm::StringRef message);

/// Emit the given message to the stdout or stderr depending on severity.
static void SystemLogFallback(lldb::Severity severity,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need this fallback? I wonder if spamming stdout/stderr isn't worse than having no logging at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to remove it. It would only be called if the system can't register an EventSource, which either means it's unsupported on this Windows version or that the system is corrupted somehow (in which case stdout will not work either).

I removed it 👍

@charles-zablit charles-zablit merged commit 87023cd into llvm:main Jul 31, 2025
9 checks passed
charles-zablit added a commit to charles-zablit/llvm-project that referenced this pull request Jul 31, 2025
This patch makes LLDB use the Event Viewer on Windows (equivalent of
system logging on Darwin) rather than piping to the standard output
(which was deactivated in ca0a524.
charles-zablit added a commit that referenced this pull request Sep 2, 2025
…56474)

In #150213 we made use of the
Event Viewer on Windows (equivalent of system logging on Darwin) rather
than piping to the standard output. This turned out to be too verbose in
practice, as the Event Viewer is developer oriented and not user
oriented.

This patch swaps the use of `ReportEventW` for `OutputDebugStringA`,
allowing to use tools such as `DebugView` to record logs when we are
interested in receiving them, rather than continuously writing to the
buffer. Please see an example below:
<img width="1253" height="215" alt="Screenshot 2025-09-02 at 16 07 03"
src="https://github.com/user-attachments/assets/4a326e46-d8a4-4c99-8c96-1bee62da8d55"
/>
charles-zablit added a commit to charles-zablit/llvm-project that referenced this pull request Sep 2, 2025
…vm#156474)

In llvm#150213 we made use of the
Event Viewer on Windows (equivalent of system logging on Darwin) rather
than piping to the standard output. This turned out to be too verbose in
practice, as the Event Viewer is developer oriented and not user
oriented.

This patch swaps the use of `ReportEventW` for `OutputDebugStringA`,
allowing to use tools such as `DebugView` to record logs when we are
interested in receiving them, rather than continuously writing to the
buffer. Please see an example below:
<img width="1253" height="215" alt="Screenshot 2025-09-02 at 16 07 03"
src="https://github.com/user-attachments/assets/4a326e46-d8a4-4c99-8c96-1bee62da8d55"
/>
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Sep 2, 2025
… events (#156474)

In llvm/llvm-project#150213 we made use of the
Event Viewer on Windows (equivalent of system logging on Darwin) rather
than piping to the standard output. This turned out to be too verbose in
practice, as the Event Viewer is developer oriented and not user
oriented.

This patch swaps the use of `ReportEventW` for `OutputDebugStringA`,
allowing to use tools such as `DebugView` to record logs when we are
interested in receiving them, rather than continuously writing to the
buffer. Please see an example below:
<img width="1253" height="215" alt="Screenshot 2025-09-02 at 16 07 03"
src="https://github.com/user-attachments/assets/4a326e46-d8a4-4c99-8c96-1bee62da8d55"
/>
charles-zablit added a commit to charles-zablit/llvm-project that referenced this pull request Sep 4, 2025
This patch makes LLDB use the Event Viewer on Windows (equivalent of
system logging on Darwin) rather than piping to the standard output
(which was deactivated in ca0a524.
charles-zablit added a commit to charles-zablit/llvm-project that referenced this pull request Sep 4, 2025
…vm#156474)

In llvm#150213 we made use of the
Event Viewer on Windows (equivalent of system logging on Darwin) rather
than piping to the standard output. This turned out to be too verbose in
practice, as the Event Viewer is developer oriented and not user
oriented.

This patch swaps the use of `ReportEventW` for `OutputDebugStringA`,
allowing to use tools such as `DebugView` to record logs when we are
interested in receiving them, rather than continuously writing to the
buffer. Please see an example below:
<img width="1253" height="215" alt="Screenshot 2025-09-02 at 16 07 03"
src="https://github.com/user-attachments/assets/4a326e46-d8a4-4c99-8c96-1bee62da8d55"
/>
charles-zablit added a commit to charles-zablit/llvm-project that referenced this pull request Sep 15, 2025
This patch makes LLDB use the Event Viewer on Windows (equivalent of
system logging on Darwin) rather than piping to the standard output
(which was deactivated in ca0a524.
charles-zablit added a commit to charles-zablit/llvm-project that referenced this pull request Sep 15, 2025
…vm#156474)

In llvm#150213 we made use of the
Event Viewer on Windows (equivalent of system logging on Darwin) rather
than piping to the standard output. This turned out to be too verbose in
practice, as the Event Viewer is developer oriented and not user
oriented.

This patch swaps the use of `ReportEventW` for `OutputDebugStringA`,
allowing to use tools such as `DebugView` to record logs when we are
interested in receiving them, rather than continuously writing to the
buffer. Please see an example below:
<img width="1253" height="215" alt="Screenshot 2025-09-02 at 16 07 03"
src="https://github.com/user-attachments/assets/4a326e46-d8a4-4c99-8c96-1bee62da8d55"
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants