Skip to content

Commit e9704ca

Browse files
committed
[lldb] Introduce an always-on system log category/channel
Add an "always on" log category and channel. Unlike other, existing log channels, it is not exposed to users. The channel is meant to be used sparsely and deliberately for logging high-value information to the system log. We have a similar concept in the downstream Swift fork and this has proven to be extremely valuable. This is especially true on macOS where system log messages are automatically captured as part of a sysdiagnose. This patch revives https://reviews.llvm.org/D135621 although the purpose is slightly different (logging to the system log rather than to a ring buffer dumped as part of the diagnostics). This patch addresses all the remaining oustanding comments.
1 parent 7ba4968 commit e9704ca

File tree

7 files changed

+57
-6
lines changed

7 files changed

+57
-6
lines changed

lldb/include/lldb/Host/Host.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ class ProcessInstanceInfo;
3131
class ProcessInstanceInfoMatch;
3232
typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
3333

34+
// Always on system log category and channel.
35+
enum class SystemLog : Log::MaskType {
36+
System = Log::ChannelFlag<0>,
37+
LLVM_MARK_AS_BITMASK_ENUM(System)
38+
};
39+
40+
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
41+
42+
class LogChannelSystem {
43+
public:
44+
static void Initialize();
45+
static void Terminate();
46+
};
47+
48+
template <> Log::Channel &LogChannelFor<SystemLog>();
49+
3450
// Exit Type for inferior processes
3551
struct WaitStatus {
3652
enum Type : uint8_t {

lldb/include/lldb/Utility/LLDBLog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ enum class LLDBLog : Log::MaskType {
4949
Watchpoints = Log::ChannelFlag<30>,
5050
OnDemand = Log::ChannelFlag<31>,
5151
Source = Log::ChannelFlag<32>,
52+
AlwaysOn = Log::ChannelFlag<32>,
5253
LLVM_MARK_AS_BITMASK_ENUM(OnDemand),
5354
};
5455

lldb/include/lldb/Utility/Log.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,14 @@ class Log final {
165165
friend class Log;
166166

167167
public:
168+
const bool internal = false;
168169
const llvm::ArrayRef<Category> categories;
169170
const MaskType default_flags;
170171

171172
template <typename Cat>
172173
constexpr Channel(llvm::ArrayRef<Log::Category> categories,
173-
Cat default_flags)
174-
: log_ptr(nullptr), categories(categories),
174+
Cat default_flags, bool internal = false)
175+
: log_ptr(nullptr), internal(internal), categories(categories),
175176
default_flags(MaskType(default_flags)) {
176177
static_assert(
177178
std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value);

lldb/source/Host/common/Host.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,25 @@ void Host::SystemLog(Severity severity, llvm::StringRef message) {
125125
#endif
126126
#endif
127127

128+
static constexpr Log::Category g_categories[] = {
129+
{{"system"}, {"system log"}, SystemLog::System}};
130+
131+
static Log::Channel g_channel(g_categories, SystemLog::System,
132+
/*internal=*/true);
133+
134+
template <> Log::Channel &lldb_private::LogChannelFor<SystemLog>() {
135+
return g_channel;
136+
}
137+
138+
void LogChannelSystem::Initialize() {
139+
Log::Register("system", g_channel);
140+
const uint32_t log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
141+
Log::EnableLogChannel(std::make_shared<SystemLogHandler>(), log_options,
142+
"system", {"all"}, llvm::nulls());
143+
}
144+
145+
void LogChannelSystem::Terminate() { Log::Unregister("system"); }
146+
128147
#if !defined(__APPLE__) && !defined(_WIN32)
129148
static thread_result_t
130149
MonitorChildProcessThreadFunction(::pid_t pid,

lldb/source/Host/common/HostInfoBase.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,11 @@ static HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr;
7676
void HostInfoBase::Initialize(SharedLibraryDirectoryHelper *helper) {
7777
g_shlib_dir_helper = helper;
7878
g_fields = new HostInfoBaseFields();
79+
LogChannelSystem::Initialize();
7980
}
8081

8182
void HostInfoBase::Terminate() {
83+
LogChannelSystem::Terminate();
8284
g_shlib_dir_helper = nullptr;
8385
delete g_fields;
8486
g_fields = nullptr;

lldb/source/Utility/Log.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@ bool Log::DisableLogChannel(llvm::StringRef channel,
245245
error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel);
246246
return false;
247247
}
248+
if (iter->second.m_channel.internal) {
249+
error_stream << llvm::formatv(
250+
"Cannot disable internal log channel '{0}'.\n", channel);
251+
return false;
252+
}
248253
MaskType flags = categories.empty()
249254
? std::numeric_limits<MaskType>::max()
250255
: GetFlags(error_stream, *iter, categories);
@@ -296,8 +301,10 @@ void Log::ForEachChannelCategory(
296301

297302
std::vector<llvm::StringRef> Log::ListChannels() {
298303
std::vector<llvm::StringRef> result;
299-
for (const auto &channel : *g_channel_map)
300-
result.push_back(channel.first());
304+
for (const auto &entry : *g_channel_map) {
305+
if (!entry.second.m_channel.internal)
306+
result.push_back(entry.first());
307+
}
301308
return result;
302309
}
303310

@@ -307,8 +314,10 @@ void Log::ListAllLogChannels(llvm::raw_ostream &stream) {
307314
return;
308315
}
309316

310-
for (const auto &channel : *g_channel_map)
311-
ListCategories(stream, channel);
317+
for (const auto &entry : *g_channel_map) {
318+
if (!entry.second.m_channel.internal)
319+
ListCategories(stream, entry);
320+
}
312321
}
313322

314323
bool Log::GetVerbose() const {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
RUN: %lldb -o 'log list' -o 'log disable system' 2>&1 | FileCheck %s
2+
CHECK-NOT: Logging categories for 'system'
3+
CHECK: Cannot disable internal log channel 'system'.

0 commit comments

Comments
 (0)