[Lldb-commits] [lldb] c77b107 - [lldb] Introduce an always-on system log category/channel (#108495)

via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 10 08:47:36 PDT 2024


Author: Jonas Devlieghere
Date: 2024-10-10T08:47:30-07:00
New Revision: c77b10746160f985625603b1e9c837b44caa5c67

URL: https://github.com/llvm/llvm-project/commit/c77b10746160f985625603b1e9c837b44caa5c67
DIFF: https://github.com/llvm/llvm-project/commit/c77b10746160f985625603b1e9c837b44caa5c67.diff

LOG: [lldb] Introduce an always-on system log category/channel (#108495)

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.

Added: 
    lldb/test/Shell/Host/TestSytemLogChannel.test

Modified: 
    lldb/include/lldb/Host/Host.h
    lldb/include/lldb/Utility/Log.h
    lldb/source/API/SystemInitializerFull.cpp
    lldb/source/Host/common/Host.cpp
    lldb/source/Host/common/HostInfoBase.cpp
    lldb/source/Utility/Log.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index 9d0994978402f7..d8113a5fceeada 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -31,6 +31,25 @@ class ProcessInstanceInfo;
 class ProcessInstanceInfoMatch;
 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
 
+// System log category and channel. This log channel is always enabled and
+// therefore is supposed to be used sparsely. Use this log channel to log
+// critical information that is expected to be relevant to the majority of bug
+// reports.
+enum class SystemLog : Log::MaskType {
+  System = Log::ChannelFlag<0>,
+  LLVM_MARK_AS_BITMASK_ENUM(System)
+};
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+class LogChannelSystem {
+public:
+  static void Initialize();
+  static void Terminate();
+};
+
+template <> Log::Channel &LogChannelFor<SystemLog>();
+
 // Exit Type for inferior processes
 struct WaitStatus {
   enum Type : uint8_t {

diff  --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h
index 27707c17f9b824..ac6347153a1014 100644
--- a/lldb/include/lldb/Utility/Log.h
+++ b/lldb/include/lldb/Utility/Log.h
@@ -272,6 +272,12 @@ class Log final {
   void VAFormatf(llvm::StringRef file, llvm::StringRef function,
                  const char *format, va_list args);
 
+  void Enable(const std::shared_ptr<LogHandler> &handler_sp,
+              std::optional<MaskType> flags = std::nullopt,
+              uint32_t options = 0);
+
+  void Disable(std::optional<MaskType> flags = std::nullopt);
+
 private:
   Channel &m_channel;
 
@@ -297,11 +303,6 @@ class Log final {
     return m_handler;
   }
 
-  void Enable(const std::shared_ptr<LogHandler> &handler_sp, uint32_t options,
-              MaskType flags);
-
-  void Disable(MaskType flags);
-
   bool Dump(llvm::raw_ostream &stream);
 
   typedef llvm::StringMap<Log> ChannelMap;

diff  --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp
index 995d14f7c1fa1e..8a992a6889a91b 100644
--- a/lldb/source/API/SystemInitializerFull.cpp
+++ b/lldb/source/API/SystemInitializerFull.cpp
@@ -17,6 +17,7 @@
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Target/ProcessTrace.h"
 #include "lldb/Utility/Timer.h"
+#include "lldb/Version/Version.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/TargetSelect.h"
 
@@ -83,6 +84,8 @@ llvm::Error SystemInitializerFull::Initialize() {
   // Use the Debugger's LLDBAssert callback.
   SetLLDBAssertCallback(Debugger::AssertCallback);
 
+  LLDB_LOG(GetLog(SystemLog::System), "{0}", GetVersion());
+
   return llvm::Error::success();
 }
 

diff  --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index f08adea6546ae1..abca6068d3604a 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -125,6 +125,22 @@ void Host::SystemLog(Severity severity, llvm::StringRef message) {
 #endif
 #endif
 
+static constexpr Log::Category g_categories[] = {
+    {{"system"}, {"system log"}, SystemLog::System}};
+
+static Log::Channel g_system_channel(g_categories, SystemLog::System);
+static Log g_system_log(g_system_channel);
+
+template <> Log::Channel &lldb_private::LogChannelFor<SystemLog>() {
+  return g_system_channel;
+}
+
+void LogChannelSystem::Initialize() {
+  g_system_log.Enable(std::make_shared<SystemLogHandler>());
+}
+
+void LogChannelSystem::Terminate() { g_system_log.Disable(); }
+
 #if !defined(__APPLE__) && !defined(_WIN32)
 static thread_result_t
 MonitorChildProcessThreadFunction(::pid_t pid,

diff  --git a/lldb/source/Host/common/HostInfoBase.cpp b/lldb/source/Host/common/HostInfoBase.cpp
index 5c44c2f38b2879..89dfe4a9e9baa3 100644
--- a/lldb/source/Host/common/HostInfoBase.cpp
+++ b/lldb/source/Host/common/HostInfoBase.cpp
@@ -76,9 +76,11 @@ static HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr;
 void HostInfoBase::Initialize(SharedLibraryDirectoryHelper *helper) {
   g_shlib_dir_helper = helper;
   g_fields = new HostInfoBaseFields();
+  LogChannelSystem::Initialize();
 }
 
 void HostInfoBase::Terminate() {
+  LogChannelSystem::Terminate();
   g_shlib_dir_helper = nullptr;
   delete g_fields;
   g_fields = nullptr;

diff  --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp
index f6b1381f63ad1c..3798f406476370 100644
--- a/lldb/source/Utility/Log.cpp
+++ b/lldb/source/Utility/Log.cpp
@@ -93,22 +93,28 @@ Log::MaskType Log::GetFlags(llvm::raw_ostream &stream,
 }
 
 void Log::Enable(const std::shared_ptr<LogHandler> &handler_sp,
-                 uint32_t options, Log::MaskType flags) {
+                 std::optional<Log::MaskType> flags, uint32_t options) {
   llvm::sys::ScopedWriter lock(m_mutex);
 
-  MaskType mask = m_mask.fetch_or(flags, std::memory_order_relaxed);
-  if (mask | flags) {
+  if (!flags)
+    flags = m_channel.default_flags;
+
+  MaskType mask = m_mask.fetch_or(*flags, std::memory_order_relaxed);
+  if (mask | *flags) {
     m_options.store(options, std::memory_order_relaxed);
     m_handler = handler_sp;
     m_channel.log_ptr.store(this, std::memory_order_relaxed);
   }
 }
 
-void Log::Disable(Log::MaskType flags) {
+void Log::Disable(std::optional<Log::MaskType> flags) {
   llvm::sys::ScopedWriter lock(m_mutex);
 
-  MaskType mask = m_mask.fetch_and(~flags, std::memory_order_relaxed);
-  if (!(mask & ~flags)) {
+  if (!flags)
+    flags = std::numeric_limits<MaskType>::max();
+
+  MaskType mask = m_mask.fetch_and(~(*flags), std::memory_order_relaxed);
+  if (!(mask & ~(*flags))) {
     m_handler.reset();
     m_channel.log_ptr.store(nullptr, std::memory_order_relaxed);
   }
@@ -230,10 +236,11 @@ bool Log::EnableLogChannel(const std::shared_ptr<LogHandler> &log_handler_sp,
     error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel);
     return false;
   }
-  MaskType flags = categories.empty()
-                       ? iter->second.m_channel.default_flags
-                       : GetFlags(error_stream, *iter, categories);
-  iter->second.Enable(log_handler_sp, log_options, flags);
+
+  auto flags = categories.empty() ? std::optional<MaskType>{}
+                                  : GetFlags(error_stream, *iter, categories);
+
+  iter->second.Enable(log_handler_sp, flags, log_options);
   return true;
 }
 
@@ -245,9 +252,10 @@ bool Log::DisableLogChannel(llvm::StringRef channel,
     error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel);
     return false;
   }
-  MaskType flags = categories.empty()
-                       ? std::numeric_limits<MaskType>::max()
-                       : GetFlags(error_stream, *iter, categories);
+
+  auto flags = categories.empty() ? std::optional<MaskType>{}
+                                  : GetFlags(error_stream, *iter, categories);
+
   iter->second.Disable(flags);
   return true;
 }

diff  --git a/lldb/test/Shell/Host/TestSytemLogChannel.test b/lldb/test/Shell/Host/TestSytemLogChannel.test
new file mode 100644
index 00000000000000..4de699f0e09a4a
--- /dev/null
+++ b/lldb/test/Shell/Host/TestSytemLogChannel.test
@@ -0,0 +1,3 @@
+RUN: %lldb -o 'log list' -o 'log disable system' 2>&1 | FileCheck %s
+CHECK-NOT: Logging categories for 'system'
+CHECK: Invalid log channel 'system'


        


More information about the lldb-commits mailing list