diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h index 23d5383163ffe..482a2270d6a69 100644 --- a/lldb/include/lldb/Host/Host.h +++ b/lldb/include/lldb/Host/Host.h @@ -90,6 +90,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 01fada13fae53..289da773afce5 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -110,20 +110,20 @@ void Host::SystemLog(Severity severity, llvm::StringRef message) { } syslog(level, "%s", message.data()); } -#else -void Host::SystemLog(Severity severity, llvm::StringRef message) { +#endif +#endif + +void Host::SystemLogFallback(Severity severity, llvm::StringRef message) { switch (severity) { case lldb::eSeverityInfo: case lldb::eSeverityWarning: llvm::outs() << message; - break; + return; case lldb::eSeverityError: llvm::errs() << message; - break; + return; } } -#endif -#endif #if !defined(__APPLE__) && !defined(_WIN32) static thread_result_t diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp index a7369e7eade3b..90e46a58299c7 100644 --- a/lldb/source/Host/windows/Host.cpp +++ b/lldb/source/Host/windows/Host.cpp @@ -22,10 +22,13 @@ #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 +#include using namespace lldb; using namespace lldb_private; @@ -302,3 +305,61 @@ Environment Host::GetEnvironment() { } return env; } + +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 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; +}