Skip to content

Commit c1c6cba

Browse files
[windows][lldb] implement system logging on Windows (llvm#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 840bc2a commit c1c6cba

File tree

2 files changed

+84
-6
lines changed

2 files changed

+84
-6
lines changed

lldb/source/Host/common/Host.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,27 @@ int __pthread_fchdir(int fildes);
8888
using namespace lldb;
8989
using namespace lldb_private;
9090

91-
#if !defined(__APPLE__)
92-
// The system log is currently only meaningful on Darwin, where this means
93-
// os_log. The meaning of a "system log" isn't as clear on other platforms, and
94-
// therefore we don't providate a default implementation. Vendors are free to
95-
// to implement this function if they have a use for it.
96-
void Host::SystemLog(Severity severity, llvm::StringRef message) {}
91+
#if !defined(__APPLE__) && !defined(_WIN32)
92+
#include <syslog.h>
93+
void Host::SystemLog(Severity severity, llvm::StringRef message) {
94+
static llvm::once_flag g_openlog_once;
95+
llvm::call_once(g_openlog_once, [] {
96+
openlog("lldb", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
97+
});
98+
int level = LOG_DEBUG;
99+
switch (severity) {
100+
case lldb::eSeverityInfo:
101+
level = LOG_INFO;
102+
break;
103+
case lldb::eSeverityWarning:
104+
level = LOG_WARNING;
105+
break;
106+
case lldb::eSeverityError:
107+
level = LOG_ERR;
108+
break;
109+
}
110+
syslog(level, "%s", message.data());
111+
}
97112
#endif
98113

99114
#if !defined(__APPLE__) && !defined(_WIN32)

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)