https://github.com/charles-zablit created https://github.com/llvm/llvm-project/pull/150213
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 ca0a5247004b6d692978d10bdbf86e338133e60c. >From 7a96f44bd01d5a66f18af43d98f4b1ab8776a203 Mon Sep 17 00:00:00 2001 From: Charles Zablit <c_zab...@apple.com> Date: Wed, 23 Jul 2025 12:43:38 +0100 Subject: [PATCH] [windows][lldb] implement system logging on Windows --- lldb/include/lldb/Host/Host.h | 4 ++ lldb/source/Host/common/Host.cpp | 21 +++++++++-- lldb/source/Host/windows/Host.cpp | 63 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 4 deletions(-) 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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits