JDevlieghere created this revision.
JDevlieghere added reviewers: labath, DavidSpickett, jingham, mib, clayborg.
Herald added a project: All.
JDevlieghere requested review of this revision.
Add an "always on" log channel. The channel is meant to be used sparsely and
deliberately for logging high-value information. Unlike other log channels,
it's not exposed to the user. Log messages are logged to a ring buffer with a
fixed number of entries. The ring buffer is dumped to disk as part of the
diagnostics, i.e. when the debugger crashes or when the user explicitly
requests a dump.
https://reviews.llvm.org/D135621
Files:
lldb/include/lldb/Utility/Diagnostics.h
lldb/include/lldb/Utility/LLDBLog.h
lldb/include/lldb/Utility/Log.h
lldb/source/Utility/Diagnostics.cpp
lldb/source/Utility/LLDBLog.cpp
lldb/source/Utility/Log.cpp
Index: lldb/source/Utility/Log.cpp
===================================================================
--- lldb/source/Utility/Log.cpp
+++ lldb/source/Utility/Log.cpp
@@ -48,7 +48,8 @@
lambda("all", "all available logging categories");
lambda("default", "default set of logging categories");
for (const auto &category : entry.second.m_channel.categories)
- lambda(category.name, category.description);
+ if (!category.internal)
+ lambda(category.name, category.description);
}
void Log::ListCategories(llvm::raw_ostream &stream,
Index: lldb/source/Utility/LLDBLog.cpp
===================================================================
--- lldb/source/Utility/LLDBLog.cpp
+++ lldb/source/Utility/LLDBLog.cpp
@@ -63,6 +63,10 @@
{{"on-demand"},
{"log symbol on-demand related activities"},
LLDBLog::OnDemand},
+ {{"always-on"},
+ {"log pertinent activities for diagnosing issues in the debugger"},
+ LLDBLog::AlwaysOn,
+ /*internal=*/true},
};
static Log::Channel g_log_channel(g_categories,
Index: lldb/source/Utility/Diagnostics.cpp
===================================================================
--- lldb/source/Utility/Diagnostics.cpp
+++ lldb/source/Utility/Diagnostics.cpp
@@ -8,6 +8,7 @@
#include "lldb/Utility/Diagnostics.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/LLDBLog.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
@@ -17,6 +18,8 @@
using namespace lldb;
using namespace llvm;
+const size_t Diagnostics::g_log_messages = 100;
+
void Diagnostics::Initialize() {
lldbassert(!InstanceImpl() && "Already initialized.");
InstanceImpl().emplace();
@@ -34,9 +37,18 @@
Diagnostics &Diagnostics::Instance() { return *InstanceImpl(); }
-Diagnostics::Diagnostics() {}
+Diagnostics::Diagnostics()
+ : m_always_on_log_handler(
+ std::make_shared<RotatingLogHandler>(g_log_messages)) {
+ const uint32_t log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+ Log::EnableLogChannel(m_always_on_log_handler, log_options, "lldb",
+ {"always-on"}, llvm::nulls());
+ AddCallback([&](const FileSpec &dir) { return DumpAlwaysOnLog(dir); });
+}
-Diagnostics::~Diagnostics() {}
+Diagnostics::~Diagnostics() {
+ Log::DisableLogChannel("lldb", {"always-on"}, llvm::nulls());
+}
void Diagnostics::AddCallback(Callback callback) {
std::lock_guard<std::mutex> guard(m_callbacks_mutex);
@@ -66,9 +78,22 @@
}
Error Diagnostics::Create(const FileSpec &dir) {
+ LLDB_LOG(GetLog(LLDBLog::AlwaysOn), "Dumping {0} diagnostics to '{1}'",
+ m_callbacks.size(), dir.GetPath());
+
for (Callback c : m_callbacks) {
if (Error err = c(dir))
return err;
}
return Error::success();
}
+
+llvm::Error Diagnostics::DumpAlwaysOnLog(const FileSpec &dir) const {
+ FileSpec log_file = dir.CopyByAppendingPathComponent("always-on.log");
+ std::error_code ec;
+ llvm::raw_fd_ostream stream(log_file.GetPath(), ec, llvm::sys::fs::OF_None);
+ if (ec)
+ return errorCodeToError(ec);
+ m_always_on_log_handler->Dump(stream);
+ return Error::success();
+}
Index: lldb/include/lldb/Utility/Log.h
===================================================================
--- lldb/include/lldb/Utility/Log.h
+++ lldb/include/lldb/Utility/Log.h
@@ -131,11 +131,14 @@
llvm::StringLiteral name;
llvm::StringLiteral description;
MaskType flag;
+ bool internal;
template <typename Cat>
constexpr Category(llvm::StringLiteral name,
- llvm::StringLiteral description, Cat mask)
- : name(name), description(description), flag(MaskType(mask)) {
+ llvm::StringLiteral description, Cat mask,
+ bool internal = false)
+ : name(name), description(description), flag(MaskType(mask)),
+ internal(internal) {
static_assert(
std::is_same<Log::MaskType, std::underlying_type_t<Cat>>::value);
}
Index: lldb/include/lldb/Utility/LLDBLog.h
===================================================================
--- lldb/include/lldb/Utility/LLDBLog.h
+++ lldb/include/lldb/Utility/LLDBLog.h
@@ -48,7 +48,8 @@
Unwind = Log::ChannelFlag<29>,
Watchpoints = Log::ChannelFlag<30>,
OnDemand = Log::ChannelFlag<31>,
- LLVM_MARK_AS_BITMASK_ENUM(OnDemand),
+ AlwaysOn = Log::ChannelFlag<32>,
+ LLVM_MARK_AS_BITMASK_ENUM(AlwaysOn),
};
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
Index: lldb/include/lldb/Utility/Diagnostics.h
===================================================================
--- lldb/include/lldb/Utility/Diagnostics.h
+++ lldb/include/lldb/Utility/Diagnostics.h
@@ -46,6 +46,11 @@
private:
static llvm::Optional<Diagnostics> &InstanceImpl();
+ static const size_t g_log_messages;
+
+ llvm::Error DumpAlwaysOnLog(const FileSpec &dir) const;
+
+ std::shared_ptr<RotatingLogHandler> m_always_on_log_handler;
llvm::SmallVector<Callback, 4> m_callbacks;
std::mutex m_callbacks_mutex;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits