JDevlieghere updated this revision to Diff 464395.
JDevlieghere added a comment.

Fix baseline


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134991/new/

https://reviews.llvm.org/D134991

Files:
  lldb/include/lldb/API/SBDebugger.h
  lldb/include/lldb/Target/Statistics.h
  lldb/include/lldb/Utility/Diagnostics.h
  lldb/include/lldb/Utility/Log.h
  lldb/source/API/SBDebugger.cpp
  lldb/source/Core/Debugger.cpp
  lldb/source/Initialization/SystemInitializerCommon.cpp
  lldb/source/Target/Statistics.cpp
  lldb/source/Utility/CMakeLists.txt
  lldb/source/Utility/Diagnostics.cpp
  lldb/tools/driver/Driver.cpp

Index: lldb/tools/driver/Driver.cpp
===================================================================
--- lldb/tools/driver/Driver.cpp
+++ lldb/tools/driver/Driver.cpp
@@ -788,6 +788,10 @@
                        << '\n';
     return 1;
   }
+
+  // Setup LLDB signal handlers once the debugger has been initialized.
+  SBDebugger::PrintDiagnosticsOnError();
+
   SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
 
   signal(SIGINT, sigint_handler);
Index: lldb/source/Utility/Diagnostics.cpp
===================================================================
--- /dev/null
+++ lldb/source/Utility/Diagnostics.cpp
@@ -0,0 +1,81 @@
+//===-- Diagnostics.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Diagnostics.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb_private;
+using namespace lldb;
+using namespace llvm;
+
+void Diagnostics::Initialize() {
+  lldbassert(!InstanceImpl() && "Already initialized.");
+  InstanceImpl().emplace();
+}
+
+void Diagnostics::Terminate() {
+  lldbassert(InstanceImpl() && "Already terminated.");
+  InstanceImpl().reset();
+}
+
+Optional<Diagnostics> &Diagnostics::InstanceImpl() {
+  static Optional<Diagnostics> g_diagnostics;
+  return g_diagnostics;
+}
+
+Diagnostics &Diagnostics::Instance() { return *InstanceImpl(); }
+
+Diagnostics::Diagnostics() {}
+
+Diagnostics::~Diagnostics() {}
+
+void Diagnostics::AddCallback(Callback callback) {
+  std::lock_guard<std::mutex> guard(m_callbacks_mutex);
+  m_callbacks.push_back(callback);
+}
+
+void Diagnostics::RemoveCallback(Callback callback) {
+  std::lock_guard<std::mutex> guard(m_callbacks_mutex);
+  m_callbacks.erase(
+      std::remove(m_callbacks.begin(), m_callbacks.end(), callback),
+      m_callbacks.end());
+}
+
+bool Diagnostics::Dump(raw_ostream &stream) {
+  SmallString<128> diagnostics_dir;
+  std::error_code ec =
+      sys::fs::createUniqueDirectory("diagnostics", diagnostics_dir);
+  if (ec) {
+    stream << "unable to create diagnostic dir: "
+           << toString(errorCodeToError(ec)) << '\n';
+    return false;
+  }
+
+  Error error = Create(FileSpec(diagnostics_dir.str()));
+  if (error) {
+    stream << toString(std::move(error)) << '\n';
+    return false;
+  }
+
+  stream << "LLDB diagnostics written to " << diagnostics_dir << "\n";
+  stream << "Please include the directory content when filing a bug report\n";
+
+  return true;
+}
+
+Error Diagnostics::Create(const FileSpec &dir) {
+  for (Callback c : m_callbacks) {
+    if (Error err = c(dir))
+      return err;
+  }
+  return Error::success();
+}
Index: lldb/source/Utility/CMakeLists.txt
===================================================================
--- lldb/source/Utility/CMakeLists.txt
+++ lldb/source/Utility/CMakeLists.txt
@@ -35,6 +35,7 @@
   DataBufferLLVM.cpp
   DataEncoder.cpp
   DataExtractor.cpp
+  Diagnostics.cpp
   Environment.cpp
   Event.cpp
   FileSpec.cpp
Index: lldb/source/Target/Statistics.cpp
===================================================================
--- lldb/source/Target/Statistics.cpp
+++ lldb/source/Target/Statistics.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/Diagnostics.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -275,3 +276,29 @@
   };
   return std::move(global_stats);
 }
+
+void Stats::Initialize() { Diagnostics::Instance().AddCallback(Stats::Dump); }
+
+void Stats::Terminate() { Diagnostics::Instance().RemoveCallback(Stats::Dump); }
+
+llvm::Error Stats::Dump(const FileSpec &dir) {
+  for (size_t debugger_idx = 0; debugger_idx < Debugger::GetNumDebuggers();
+       debugger_idx++) {
+    DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
+    if (!debugger_sp)
+      continue;
+
+    std::string filename =
+        (Twine("debugger-") + Twine(debugger_idx) + Twine("-stats.json")).str();
+    FileSpec stat_file = dir.CopyByAppendingPathComponent(filename);
+
+    std::error_code ec;
+    raw_fd_ostream stats_stream(stat_file.GetPath(), ec, sys::fs::OF_None);
+    if (ec)
+      return errorCodeToError(ec);
+
+    stats_stream << DebuggerStats::ReportStatistics(*debugger_sp, nullptr);
+  }
+
+  return llvm::Error::success();
+}
Index: lldb/source/Initialization/SystemInitializerCommon.cpp
===================================================================
--- lldb/source/Initialization/SystemInitializerCommon.cpp
+++ lldb/source/Initialization/SystemInitializerCommon.cpp
@@ -12,6 +12,8 @@
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/Socket.h"
+#include "lldb/Target/Statistics.h"
+#include "lldb/Utility/Diagnostics.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Timer.h"
 #include "lldb/Version/Version.h"
@@ -63,6 +65,8 @@
 
   InitializeLldbChannel();
 
+  Diagnostics::Initialize();
+  Stats::Initialize();
   FileSystem::Initialize();
   HostInfo::Initialize(m_shlib_dir_helper);
 
@@ -95,4 +99,6 @@
   HostInfo::Terminate();
   Log::DisableAllLogChannels();
   FileSystem::Terminate();
+  Stats::Terminate();
+  Diagnostics::Terminate();
 }
Index: lldb/source/Core/Debugger.cpp
===================================================================
--- lldb/source/Core/Debugger.cpp
+++ lldb/source/Core/Debugger.cpp
@@ -44,6 +44,7 @@
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadList.h"
 #include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/Utility/Diagnostics.h"
 #include "lldb/Utility/Event.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Listener.h"
Index: lldb/source/API/SBDebugger.cpp
===================================================================
--- lldb/source/API/SBDebugger.cpp
+++ lldb/source/API/SBDebugger.cpp
@@ -52,6 +52,7 @@
 #include "lldb/Target/TargetList.h"
 #include "lldb/Utility/Args.h"
 #include "lldb/Utility/State.h"
+#include "lldb/Utility/Diagnostics.h"
 #include "lldb/Version/Version.h"
 
 #include "llvm/ADT/STLExtras.h"
@@ -218,6 +219,16 @@
   llvm::sys::PrintStackTraceOnErrorSignal(executable);
 }
 
+static void DumpDiagnostics(void* cookie) {
+  Diagnostics::Instance().Dump(llvm::errs());
+}
+
+void SBDebugger::PrintDiagnosticsOnError() {
+  LLDB_INSTRUMENT();
+
+  llvm::sys::AddSignalHandler(&DumpDiagnostics, nullptr);
+}
+
 void SBDebugger::Terminate() {
   LLDB_INSTRUMENT();
 
Index: lldb/include/lldb/Utility/Log.h
===================================================================
--- lldb/include/lldb/Utility/Log.h
+++ lldb/include/lldb/Utility/Log.h
@@ -175,7 +175,6 @@
     }
   };
 
-
   // Static accessors for logging channels
   static void Register(llvm::StringRef name, Channel &channel);
   static void Unregister(llvm::StringRef name);
@@ -222,14 +221,14 @@
 
   template <typename... Args>
   void Format(llvm::StringRef file, llvm::StringRef function,
-              const char *format, Args &&... args) {
+              const char *format, Args &&...args) {
     Format(file, function, llvm::formatv(format, std::forward<Args>(args)...));
   }
 
   template <typename... Args>
   void FormatError(llvm::Error error, llvm::StringRef file,
                    llvm::StringRef function, const char *format,
-                   Args &&... args) {
+                   Args &&...args) {
     Format(file, function,
            llvm::formatv(format, llvm::toString(std::move(error)),
                          std::forward<Args>(args)...));
Index: lldb/include/lldb/Utility/Diagnostics.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Utility/Diagnostics.h
@@ -0,0 +1,56 @@
+//===-- Diagnostics.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_DIAGNOSTICS_H
+#define LLDB_UTILITY_DIAGNOSTICS_H
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Error.h"
+
+#include <functional>
+#include <mutex>
+#include <vector>
+
+namespace lldb_private {
+
+/// Diagnostics are a collection of files to help investigate bugs and
+/// troubleshoot issues. Any part of the debugger can register itself with the
+/// help of a callback to emit one or more files into the diagnostic directory.
+class Diagnostics {
+public:
+  Diagnostics();
+  ~Diagnostics();
+
+  /// Gather diagnostics in the given directory.
+  llvm::Error Create(const FileSpec &dir);
+
+  /// Gather diagnostics and print a message to the given output stream.
+  bool Dump(llvm::raw_ostream &stream);
+
+  using Callback = llvm::Error (*)(const FileSpec &);
+
+  void AddCallback(Callback callback);
+  void RemoveCallback(Callback callback);
+
+  static Diagnostics &Instance();
+  static void Initialize();
+  static void Terminate();
+
+private:
+  static llvm::Optional<Diagnostics> &InstanceImpl();
+
+  std::vector<Callback> m_callbacks;
+  std::mutex m_callbacks_mutex;
+};
+
+} // namespace lldb_private
+
+#endif
Index: lldb/include/lldb/Target/Statistics.h
===================================================================
--- lldb/include/lldb/Target/Statistics.h
+++ lldb/include/lldb/Target/Statistics.h
@@ -12,6 +12,7 @@
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/lldb-forward.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/JSON.h"
 #include <atomic>
 #include <chrono>
@@ -176,6 +177,13 @@
   static bool g_collecting_stats;
 };
 
+class Stats {
+public:
+  static void Initialize();
+  static void Terminate();
+  static llvm::Error Dump(const FileSpec &dir);
+};
+
 } // namespace lldb_private
 
 #endif // LLDB_TARGET_STATISTICS_H
Index: lldb/include/lldb/API/SBDebugger.h
===================================================================
--- lldb/include/lldb/API/SBDebugger.h
+++ lldb/include/lldb/API/SBDebugger.h
@@ -94,6 +94,8 @@
 
   static void PrintStackTraceOnError();
 
+  static void PrintDiagnosticsOnError();
+
   static void Terminate();
 
   // Deprecated, use the one that takes a source_init_files bool.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to