[Lldb-commits] [lldb] 6ac608b - [lldb] Add RotatingLogHandler
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 16 15:17:45 PDT 2022
Author: Jonas Devlieghere
Date: 2022-06-16T15:17:40-07:00
New Revision: 6ac608b3d897502c987e02667e87315c5fe0e90f
URL: https://github.com/llvm/llvm-project/commit/6ac608b3d897502c987e02667e87315c5fe0e90f
DIFF: https://github.com/llvm/llvm-project/commit/6ac608b3d897502c987e02667e87315c5fe0e90f.diff
LOG: [lldb] Add RotatingLogHandler
Add a log handler that maintains a circular buffer with a fixed size.
Differential revision: https://reviews.llvm.org/D127937
Added:
Modified:
lldb/include/lldb/Utility/Log.h
lldb/source/Utility/Log.cpp
lldb/unittests/Utility/LogTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h
index d4ce30dde6c6..0beb97b4891f 100644
--- a/lldb/include/lldb/Utility/Log.h
+++ b/lldb/include/lldb/Utility/Log.h
@@ -82,6 +82,26 @@ class CallbackLogHandler : public LogHandler {
void *m_baton;
};
+class RotatingLogHandler : public LogHandler {
+public:
+ RotatingLogHandler(size_t size);
+
+ void Emit(llvm::StringRef message) override;
+ void Dump(llvm::raw_ostream &stream) const;
+
+ static std::shared_ptr<RotatingLogHandler> Create(size_t size);
+
+private:
+ size_t NormalizeIndex(size_t i) const;
+ size_t GetNumMessages() const;
+ size_t GetFirstMessageIndex() const;
+
+ std::unique_ptr<std::string[]> m_messages;
+ const size_t m_size = 0;
+ size_t m_next_index = 0;
+ size_t m_total_count = 0;
+};
+
class Log final {
public:
/// The underlying type of all log channel enums. Declare them as:
diff --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp
index b9b79636d0dc..62547154dbee 100644
--- a/lldb/source/Utility/Log.cpp
+++ b/lldb/source/Utility/Log.cpp
@@ -365,3 +365,37 @@ std::shared_ptr<CallbackLogHandler>
CallbackLogHandler::Create(lldb::LogOutputCallback callback, void *baton) {
return std::make_shared<CallbackLogHandler>(callback, baton);
}
+
+RotatingLogHandler::RotatingLogHandler(size_t size)
+ : m_messages(std::make_unique<std::string[]>(size)), m_size(size) {}
+
+void RotatingLogHandler::Emit(llvm::StringRef message) {
+ ++m_total_count;
+ const size_t index = m_next_index;
+ m_next_index = NormalizeIndex(index + 1);
+ m_messages[index] = message.str();
+}
+
+size_t RotatingLogHandler::NormalizeIndex(size_t i) const { return i % m_size; }
+
+size_t RotatingLogHandler::GetNumMessages() const {
+ return m_total_count < m_size ? m_total_count : m_size;
+}
+
+size_t RotatingLogHandler::GetFirstMessageIndex() const {
+ return m_total_count < m_size ? 0 : m_next_index;
+}
+
+void RotatingLogHandler::Dump(llvm::raw_ostream &stream) const {
+ const size_t start_idx = GetFirstMessageIndex();
+ const size_t stop_idx = start_idx + GetNumMessages();
+ for (size_t i = start_idx; i < stop_idx; ++i) {
+ const size_t idx = NormalizeIndex(i);
+ stream << m_messages[idx];
+ }
+ stream.flush();
+}
+
+std::shared_ptr<RotatingLogHandler> RotatingLogHandler::Create(size_t size) {
+ return std::make_shared<RotatingLogHandler>(size);
+}
diff --git a/lldb/unittests/Utility/LogTest.cpp b/lldb/unittests/Utility/LogTest.cpp
index 2b61c99630ea..d89f6df1ce44 100644
--- a/lldb/unittests/Utility/LogTest.cpp
+++ b/lldb/unittests/Utility/LogTest.cpp
@@ -104,6 +104,13 @@ class LogChannelEnabledTest : public LogChannelTest {
public:
void SetUp() override;
};
+
+static std::string GetDumpAsString(const RotatingLogHandler &handler) {
+ std::string buffer;
+ llvm::raw_string_ostream stream(buffer);
+ handler.Dump(stream);
+ return buffer;
+}
} // end anonymous namespace
void LogChannelEnabledTest::SetUp() {
@@ -171,6 +178,21 @@ TEST(LogTest, CallbackLogHandler) {
EXPECT_EQ(1u, callback_count);
}
+TEST(LogHandlerTest, RotatingLogHandler) {
+ RotatingLogHandler handler(3);
+
+ handler.Emit("foo");
+ handler.Emit("bar");
+ EXPECT_EQ(GetDumpAsString(handler), "foobar");
+
+ handler.Emit("baz");
+ handler.Emit("qux");
+ EXPECT_EQ(GetDumpAsString(handler), "barbazqux");
+
+ handler.Emit("quux");
+ EXPECT_EQ(GetDumpAsString(handler), "bazquxquux");
+}
+
TEST_F(LogChannelTest, Enable) {
EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
std::string message;
More information about the lldb-commits
mailing list