Skip to content

Commit 7a96f44

Browse files
[windows][lldb] implement system logging on Windows
1 parent 3e24dad commit 7a96f44

File tree

3 files changed

+84
-4
lines changed

3 files changed

+84
-4
lines changed

lldb/include/lldb/Host/Host.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class Host {
109109
/// Emit the given message to the operating system log.
110110
static void SystemLog(lldb::Severity severity, llvm::StringRef message);
111111

112+
/// Emit the given message to the stdout or stderr depending on severity.
113+
static void SystemLogFallback(lldb::Severity severity,
114+
llvm::StringRef message);
115+
112116
/// Get the process ID for the calling process.
113117
///
114118
/// \return

lldb/source/Host/common/Host.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,27 @@ int __pthread_fchdir(int fildes);
8282
using namespace lldb;
8383
using namespace lldb_private;
8484

85-
#if !defined(__APPLE__)
86-
// The system log is currently only meaningful on Darwin, where this means
87-
// os_log. The meaning of a "system log" isn't as clear on other platforms, and
88-
// therefore we don't providate a default implementation. Vendors are free to
85+
#if !defined(__APPLE__) && !defined(_WIN32)
86+
// The system log is currently only meaningful on Darwin and Windows.
87+
// On Darwin, this means os_log. On Windows this means Events Viewer.
88+
// The meaning of a "system log" isn't as clear on other platforms, and
89+
// therefore we don't providate a default implementation. Vendors are free
8990
// to implement this function if they have a use for it.
9091
void Host::SystemLog(Severity severity, llvm::StringRef message) {}
9192
#endif
9293

94+
void Host::SystemLogFallback(Severity severity, llvm::StringRef message) {
95+
switch (severity) {
96+
case lldb::eSeverityInfo:
97+
case lldb::eSeverityWarning:
98+
llvm::outs() << message;
99+
return;
100+
case lldb::eSeverityError:
101+
llvm::errs() << message;
102+
return;
103+
}
104+
}
105+
93106
static constexpr Log::Category g_categories[] = {
94107
{{"system"}, {"system log"}, SystemLog::System}};
95108

lldb/source/Host/windows/Host.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#include "lldb/Utility/StreamString.h"
2323
#include "lldb/Utility/StructuredData.h"
2424

25+
#include "llvm/ADT/StringRef.h"
2526
#include "llvm/Support/ConvertUTF.h"
27+
#include "llvm/Support/ManagedStatic.h"
2628

2729
// Windows includes
2830
#include <tlhelp32.h>
@@ -302,3 +304,64 @@ Environment Host::GetEnvironment() {
302304
}
303305
return env;
304306
}
307+
308+
/// Manages the lifecycle of a Windows Event's Source.
309+
/// The destructor will call DeregisterEventSource.
310+
/// This class is meant to be used with \ref llvm::ManagedStatic.
311+
class WindowsEventLog {
312+
public:
313+
WindowsEventLog() : handle(RegisterEventSource(nullptr, L"lldb")) {}
314+
315+
~WindowsEventLog() {
316+
if (handle)
317+
DeregisterEventSource(handle);
318+
}
319+
320+
HANDLE GetHandle() const { return handle; }
321+
322+
private:
323+
HANDLE handle;
324+
};
325+
326+
static llvm::ManagedStatic<WindowsEventLog> event_log;
327+
328+
static LPCWSTR AnsiToUtf16(const std::string &ansi) {
329+
if (ansi.empty())
330+
return nullptr;
331+
const int unicode_length =
332+
MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, nullptr, 0);
333+
WCHAR *unicode = new WCHAR[unicode_length];
334+
MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, unicode, unicode_length);
335+
return unicode;
336+
}
337+
338+
void Host::SystemLog(Severity severity, llvm::StringRef message) {
339+
HANDLE h = event_log->GetHandle();
340+
if (!h) {
341+
SystemLogFallback(severity, message);
342+
return;
343+
}
344+
345+
LPCWSTR wide_message = AnsiToUtf16(message.str());
346+
if (!wide_message) {
347+
SystemLogFallback(severity, message);
348+
return;
349+
}
350+
351+
WORD event_type;
352+
switch (severity) {
353+
case lldb::eSeverityWarning:
354+
event_type = EVENTLOG_WARNING_TYPE;
355+
break;
356+
case lldb::eSeverityError:
357+
event_type = EVENTLOG_ERROR_TYPE;
358+
break;
359+
case lldb::eSeverityInfo:
360+
default:
361+
event_type = EVENTLOG_INFORMATION_TYPE;
362+
}
363+
364+
ReportEventW(h, event_type, 0, 0, nullptr, 1, 0, &wide_message, nullptr);
365+
366+
delete[] wide_message;
367+
}

0 commit comments

Comments
 (0)