Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lldb/include/lldb/Host/Host.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Member

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.

Copy link
Contributor Author

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 👍

llvm::StringRef message);

/// Get the process ID for the calling process.
///
/// \return
Expand Down
21 changes: 17 additions & 4 deletions lldb/source/Host/common/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}};

Expand Down
63 changes: 63 additions & 0 deletions lldb/source/Host/windows/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
}
Loading