-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[windows][lldb] implement system logging on Windows #150213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[windows][lldb] implement system logging on Windows #150213
Conversation
@llvm/pr-subscribers-lldb Author: Charles Zablit (charles-zablit) ChangesThis 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:
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/include/lldb/Host/Host.h
Outdated
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, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 👍
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.
…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" />
…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" />
… 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" />
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.
…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" />
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.
…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" />
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.