[Lldb-commits] [lldb] 8aed0ce - [lldb] Emit diagnostic events in the diagnostic dump

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 31 14:40:50 PDT 2022


Author: Jonas Devlieghere
Date: 2022-10-31T14:40:41-07:00
New Revision: 8aed0ce20fc6be41a7e49ea1433095d4cf583e56

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

LOG: [lldb] Emit diagnostic events in the diagnostic dump

Connect the diagnostic events with the diagnostic infrastructure.

 - Emit existing diagnostic events (warnings and errors) to the
   diagnostic log.
 - Introduce a new diagnostic event (info) that's used exclusively for
   diagnostic logging and does not get broadcast.

Differential revision: https://reviews.llvm.org/D136648

Added: 
    lldb/test/Shell/Diagnostics/TestDiagnosticsLog.test

Modified: 
    lldb/include/lldb/Core/Debugger.h
    lldb/include/lldb/Core/DebuggerEvents.h
    lldb/include/lldb/Utility/Diagnostics.h
    lldb/source/Core/Debugger.cpp
    lldb/source/Core/DebuggerEvents.cpp
    lldb/source/Utility/Diagnostics.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index 394dac3662345..041d1fd864733 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -425,6 +425,26 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
               llvm::Optional<lldb::user_id_t> debugger_id = llvm::None,
               std::once_flag *once = nullptr);
 
+  /// Report info events.
+  ///
+  /// Unlike warning and error events, info events are not broadcast but are
+  /// logged for diagnostic purposes.
+  ///
+  /// \param[in] message
+  ///   The info message to be reported.
+  ///
+  /// \param [in] debugger_id
+  ///   If this optional parameter has a value, it indicates this diagnostic is
+  ///   associated with a unique debugger instance.
+  ///
+  /// \param [in] once
+  ///   If a pointer is passed to a std::once_flag, then it will be used to
+  ///   ensure the given info is only logged once.
+  static void
+  ReportInfo(std::string message,
+             llvm::Optional<lldb::user_id_t> debugger_id = llvm::None,
+             std::once_flag *once = nullptr);
+
   static void ReportSymbolChange(const ModuleSpec &module_spec);
 
 protected:

diff  --git a/lldb/include/lldb/Core/DebuggerEvents.h b/lldb/include/lldb/Core/DebuggerEvents.h
index e1203dcf38c8c..f2e23a94e610f 100644
--- a/lldb/include/lldb/Core/DebuggerEvents.h
+++ b/lldb/include/lldb/Core/DebuggerEvents.h
@@ -52,6 +52,7 @@ class ProgressEventData : public EventData {
 class DiagnosticEventData : public EventData {
 public:
   enum class Type {
+    Info,
     Warning,
     Error,
   };

diff  --git a/lldb/include/lldb/Utility/Diagnostics.h b/lldb/include/lldb/Utility/Diagnostics.h
index 86c97c7ff074d..d4041d5ea8bcb 100644
--- a/lldb/include/lldb/Utility/Diagnostics.h
+++ b/lldb/include/lldb/Utility/Diagnostics.h
@@ -39,11 +39,15 @@ class Diagnostics {
   bool Dump(llvm::raw_ostream &stream, const FileSpec &dir);
   /// @}
 
+  void Report(llvm::StringRef message);
+
   using Callback = std::function<llvm::Error(const FileSpec &)>;
 
   void AddCallback(Callback callback);
 
   static Diagnostics &Instance();
+
+  static bool Enabled();
   static void Initialize();
   static void Terminate();
 
@@ -53,6 +57,10 @@ class Diagnostics {
 private:
   static llvm::Optional<Diagnostics> &InstanceImpl();
 
+  llvm::Error DumpDiangosticsLog(const FileSpec &dir) const;
+
+  RotatingLogHandler m_log_handler;
+
   llvm::SmallVector<Callback, 4> m_callbacks;
   std::mutex m_callbacks_mutex;
 };

diff  --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index a4c453c6f422c..77d943787df9c 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1311,6 +1311,9 @@ static void PrivateReportDiagnostic(Debugger &debugger,
                                     bool debugger_specific) {
   uint32_t event_type = 0;
   switch (type) {
+  case DiagnosticEventData::Type::Info:
+    assert(false && "DiagnosticEventData::Type::Info should not be broadcast");
+    return;
   case DiagnosticEventData::Type::Warning:
     event_type = Debugger::eBroadcastBitWarning;
     break;
@@ -1339,6 +1342,15 @@ void Debugger::ReportDiagnosticImpl(DiagnosticEventData::Type type,
                                     llvm::Optional<lldb::user_id_t> debugger_id,
                                     std::once_flag *once) {
   auto ReportDiagnosticLambda = [&]() {
+    // The diagnostic subsystem is optional but we still want to broadcast
+    // events when it's disabled.
+    if (Diagnostics::Enabled())
+      Diagnostics::Instance().Report(message);
+
+    // We don't broadcast info events.
+    if (type == DiagnosticEventData::Type::Info)
+      return;
+
     // Check if this diagnostic is for a specific debugger.
     if (debugger_id) {
       // It is debugger specific, grab it and deliver the event if the debugger
@@ -1377,6 +1389,13 @@ void Debugger::ReportError(std::string message,
                        debugger_id, once);
 }
 
+void Debugger::ReportInfo(std::string message,
+                          llvm::Optional<lldb::user_id_t> debugger_id,
+                          std::once_flag *once) {
+  ReportDiagnosticImpl(DiagnosticEventData::Type::Info, std::move(message),
+                       debugger_id, once);
+}
+
 void Debugger::ReportSymbolChange(const ModuleSpec &module_spec) {
   if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
     std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);

diff  --git a/lldb/source/Core/DebuggerEvents.cpp b/lldb/source/Core/DebuggerEvents.cpp
index 0cc9ee9ad96f5..6b33af9e0ee1f 100644
--- a/lldb/source/Core/DebuggerEvents.cpp
+++ b/lldb/source/Core/DebuggerEvents.cpp
@@ -51,6 +51,8 @@ ProgressEventData::GetEventDataFromEvent(const Event *event_ptr) {
 
 llvm::StringRef DiagnosticEventData::GetPrefix() const {
   switch (m_type) {
+  case Type::Info:
+    return "info";
   case Type::Warning:
     return "warning";
   case Type::Error:

diff  --git a/lldb/source/Utility/Diagnostics.cpp b/lldb/source/Utility/Diagnostics.cpp
index 6bd8fcf28b58b..a6e51e25d51fb 100644
--- a/lldb/source/Utility/Diagnostics.cpp
+++ b/lldb/source/Utility/Diagnostics.cpp
@@ -17,6 +17,8 @@ using namespace lldb_private;
 using namespace lldb;
 using namespace llvm;
 
+static constexpr size_t g_num_log_messages = 100;
+
 void Diagnostics::Initialize() {
   lldbassert(!InstanceImpl() && "Already initialized.");
   InstanceImpl().emplace();
@@ -27,6 +29,8 @@ void Diagnostics::Terminate() {
   InstanceImpl().reset();
 }
 
+bool Diagnostics::Enabled() { return InstanceImpl().operator bool(); }
+
 Optional<Diagnostics> &Diagnostics::InstanceImpl() {
   static Optional<Diagnostics> g_diagnostics;
   return g_diagnostics;
@@ -34,7 +38,7 @@ Optional<Diagnostics> &Diagnostics::InstanceImpl() {
 
 Diagnostics &Diagnostics::Instance() { return *InstanceImpl(); }
 
-Diagnostics::Diagnostics() {}
+Diagnostics::Diagnostics() : m_log_handler(g_num_log_messages) {}
 
 Diagnostics::~Diagnostics() {}
 
@@ -58,8 +62,7 @@ bool Diagnostics::Dump(raw_ostream &stream, const FileSpec &dir) {
   stream << "LLDB diagnostics will be written to " << dir.GetPath() << "\n";
   stream << "Please include the directory content when filing a bug report\n";
 
-  Error error = Create(dir);
-  if (error) {
+  if (Error error = Create(dir)) {
     stream << toString(std::move(error)) << '\n';
     return false;
   }
@@ -77,9 +80,27 @@ llvm::Expected<FileSpec> Diagnostics::CreateUniqueDirectory() {
 }
 
 Error Diagnostics::Create(const FileSpec &dir) {
+  if (Error err = DumpDiangosticsLog(dir))
+    return err;
+
   for (Callback c : m_callbacks) {
     if (Error err = c(dir))
       return err;
   }
+
   return Error::success();
 }
+
+llvm::Error Diagnostics::DumpDiangosticsLog(const FileSpec &dir) const {
+  FileSpec log_file = dir.CopyByAppendingPathComponent("diagnostics.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_log_handler.Dump(stream);
+  return Error::success();
+}
+
+void Diagnostics::Report(llvm::StringRef message) {
+  m_log_handler.Emit(message);
+}

diff  --git a/lldb/test/Shell/Diagnostics/TestDiagnosticsLog.test b/lldb/test/Shell/Diagnostics/TestDiagnosticsLog.test
new file mode 100644
index 0000000000000..3be56e747fd24
--- /dev/null
+++ b/lldb/test/Shell/Diagnostics/TestDiagnosticsLog.test
@@ -0,0 +1,33 @@
+# RUN: yaml2obj %s -o %t
+# RUN: mkdir -p %t.diags
+# RUN: %lldb -c %t -o 'diagnostics dump -d %t.diags' 2> %t.stderr
+
+# RUN: cat %t.stderr | FileCheck %s --check-prefix ERROR
+# RUN: cat %t.diags/diagnostics.log | FileCheck %s --check-prefix ERROR
+
+# ERROR: unable to retrieve process ID from minidump file, setting process ID to 1
+
+--- !minidump
+Streams:
+  - Type:            ThreadList
+    Threads:
+      - Thread Id:       0x00003E81
+        Context:         0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+        Stack:
+          Start of Memory Range: 0x00007FFCEB34A000
+          Content:         ''
+  - Type:            ModuleList
+    Modules:
+      - Base of Image:   0x0000000000400000
+        Size of Image:   0x00017000
+        Module Name:     'a.out'
+        CodeView Record: ''
+  - Type:            SystemInfo
+    Processor Arch:  AMD64
+    Platform ID:     Linux
+    CSD Version:     'Linux 3.13'
+    CPU:
+      Vendor ID:       GenuineIntel
+      Version Info:    0x00000000
+      Feature Info:    0x00000000
+...


        


More information about the lldb-commits mailing list