JDevlieghere updated this revision to Diff 469399.
JDevlieghere marked 2 inline comments as done.
JDevlieghere added a comment.
Split off the statistics
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/Utility/Diagnostics.h
lldb/lldb/include/lldb/Utility/Diagnostics.h
lldb/lldb/source/Utility/Diagnostics.cpp
lldb/source/API/SBDebugger.cpp
lldb/source/Core/Debugger.cpp
lldb/source/Initialization/SystemInitializerCommon.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,74 @@
+//===-- 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);
+}
+
+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;
+ }
+
+ stream << "LLDB diagnostics written to " << diagnostics_dir << "\n";
+ stream << "Please include the directory content when filing a bug report\n";
+
+ Error error = Create(FileSpec(diagnostics_dir.str()));
+ if (error) {
+ stream << toString(std::move(error)) << '\n';
+ return false;
+ }
+
+ 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/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,7 @@
InitializeLldbChannel();
+ Diagnostics::Initialize();
FileSystem::Initialize();
HostInfo::Initialize(m_shlib_dir_helper);
@@ -95,4 +98,5 @@
HostInfo::Terminate();
Log::DisableAllLogChannels();
FileSystem::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
@@ -51,6 +51,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Utility/Args.h"
+#include "lldb/Utility/Diagnostics.h"
#include "lldb/Utility/State.h"
#include "lldb/Version/Version.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/lldb/source/Utility/Diagnostics.cpp
===================================================================
--- /dev/null
+++ lldb/lldb/source/Utility/Diagnostics.cpp
@@ -0,0 +1,74 @@
+//===-- 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);
+}
+
+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;
+ }
+
+ stream << "LLDB diagnostics written to " << diagnostics_dir << "\n";
+ stream << "Please include the directory content when filing a bug report\n";
+
+ Error error = Create(FileSpec(diagnostics_dir.str()));
+ if (error) {
+ stream << toString(std::move(error)) << '\n';
+ return false;
+ }
+
+ 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/lldb/include/lldb/Utility/Diagnostics.h
===================================================================
--- /dev/null
+++ lldb/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/SmallVector.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 = std::function<llvm::Error(const FileSpec &)>;
+
+ void AddCallback(Callback callback);
+
+ static Diagnostics &Instance();
+ static void Initialize();
+ static void Terminate();
+
+private:
+ static llvm::Optional<Diagnostics> &InstanceImpl();
+
+ llvm::SmallVector<Callback, 4> m_callbacks;
+ std::mutex m_callbacks_mutex;
+};
+
+} // namespace lldb_private
+
+#endif
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/SmallVector.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 = std::function<llvm::Error(const FileSpec &)>;
+
+ void AddCallback(Callback callback);
+
+ static Diagnostics &Instance();
+ static void Initialize();
+ static void Terminate();
+
+private:
+ static llvm::Optional<Diagnostics> &InstanceImpl();
+
+ llvm::SmallVector<Callback, 4> m_callbacks;
+ std::mutex m_callbacks_mutex;
+};
+
+} // namespace lldb_private
+
+#endif
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits