Skip to content

Commit 87023cd

Browse files
[windows][lldb] implement system logging on Windows (#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 ca0a524.
1 parent 8bacfb2 commit 87023cd

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

lldb/source/Host/common/Host.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ 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

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 std::wstring AnsiToUtf16(const std::string &ansi) {
329+
if (ansi.empty())
330+
return {};
331+
332+
const int unicode_length =
333+
MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, nullptr, 0);
334+
if (unicode_length == 0)
335+
return {};
336+
337+
std::wstring unicode(unicode_length, L'\0');
338+
MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, &unicode[0], unicode_length);
339+
return unicode;
340+
}
341+
342+
void Host::SystemLog(Severity severity, llvm::StringRef message) {
343+
HANDLE h = event_log->GetHandle();
344+
if (!h)
345+
return;
346+
347+
std::wstring wide_message = AnsiToUtf16(message.str());
348+
if (wide_message.empty())
349+
return;
350+
351+
LPCWSTR msg_ptr = wide_message.c_str();
352+
353+
WORD event_type;
354+
switch (severity) {
355+
case lldb::eSeverityWarning:
356+
event_type = EVENTLOG_WARNING_TYPE;
357+
break;
358+
case lldb::eSeverityError:
359+
event_type = EVENTLOG_ERROR_TYPE;
360+
break;
361+
case lldb::eSeverityInfo:
362+
default:
363+
event_type = EVENTLOG_INFORMATION_TYPE;
364+
}
365+
366+
ReportEventW(h, event_type, 0, 0, nullptr, 1, 0, &msg_ptr, nullptr);
367+
}

0 commit comments

Comments
 (0)