[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