Author: Jonas Devlieghere Date: 2023-06-13T20:46:33-07:00 New Revision: 83a6a0a620476d2fa181cb663ccbf06cc9d7a24f
URL: https://github.com/llvm/llvm-project/commit/83a6a0a620476d2fa181cb663ccbf06cc9d7a24f DIFF: https://github.com/llvm/llvm-project/commit/83a6a0a620476d2fa181cb663ccbf06cc9d7a24f.diff LOG: [lldb] Print lldbassert to debugger diagnostics When hitting an lldbassert in a non-assert build, we emit a blurb including the assertion, the triggering file and line and a pretty backtrace leading up to the issue. Currently, this is all printed to stderr. That's fine on the command line, but when used as library, for example from Xcode, this information doesn't make it to the user. This patch uses the diagnostic infrastructure to report LLDB asserts as diagnostic events. The patch is slightly more complicated than I would've liked because of layering. lldbassert is part of Utility while the debugger diagnostics are implemented in Core. Differential revision: https://reviews.llvm.org/D152866 Added: Modified: lldb/include/lldb/Core/Debugger.h lldb/include/lldb/Utility/LLDBAssert.h lldb/source/API/SystemInitializerFull.cpp lldb/source/Core/Debugger.cpp lldb/source/Utility/LLDBAssert.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index b63597fc71b4c..4005bdbddacca 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -128,6 +128,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>, const ExecutionContext *exe_ctx, const Address *addr, Stream &s); + static void AssertCallback(llvm::StringRef message, llvm::StringRef backtrace, + llvm::StringRef prompt); + void Clear(); bool GetAsyncExecution(); diff --git a/lldb/include/lldb/Utility/LLDBAssert.h b/lldb/include/lldb/Utility/LLDBAssert.h index 524f56fd77c80..aeef3e51e20a8 100644 --- a/lldb/include/lldb/Utility/LLDBAssert.h +++ b/lldb/include/lldb/Utility/LLDBAssert.h @@ -9,6 +9,8 @@ #ifndef LLDB_UTILITY_LLDBASSERT_H #define LLDB_UTILITY_LLDBASSERT_H +#include "llvm/ADT/StringRef.h" + #ifndef NDEBUG #define lldbassert(x) assert(x) #else @@ -29,6 +31,12 @@ namespace lldb_private { void lldb_assert(bool expression, const char *expr_text, const char *func, const char *file, unsigned int line); + +typedef void (*LLDBAssertCallback)(llvm::StringRef message, + llvm::StringRef backtrace, + llvm::StringRef prompt); + +void SetLLDBAssertCallback(LLDBAssertCallback callback); } // namespace lldb_private #endif // LLDB_UTILITY_LLDBASSERT_H diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 521aecf36fd8b..27319debc8582 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -78,6 +78,9 @@ llvm::Error SystemInitializerFull::Initialize() { // Settings must be initialized AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); + // Use the Debugger's LLDBAssert callback. + SetLLDBAssertCallback(Debugger::AssertCallback); + return llvm::Error::success(); } diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index ad177637f45b4..6f43cc608c2ce 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -1352,6 +1352,13 @@ bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format, function_changed, initial_function); } +void Debugger::AssertCallback(llvm::StringRef message, + llvm::StringRef backtrace, + llvm::StringRef prompt) { + Debugger::ReportError( + llvm::formatv("{0}\n{1}{2}", message, backtrace, prompt).str()); +} + void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton) { // For simplicity's sake, I am not going to deal with how to close down any diff --git a/lldb/source/Utility/LLDBAssert.cpp b/lldb/source/Utility/LLDBAssert.cpp index 17689582cdc58..29bcacb6ad24c 100644 --- a/lldb/source/Utility/LLDBAssert.cpp +++ b/lldb/source/Utility/LLDBAssert.cpp @@ -8,7 +8,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "llvm/Config/llvm-config.h" -#include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" @@ -16,12 +16,21 @@ #include <os/log.h> #endif -using namespace llvm; -using namespace lldb_private; +namespace lldb_private { -void lldb_private::lldb_assert(bool expression, const char *expr_text, - const char *func, const char *file, - unsigned int line) { +static void DefaultAssertCallback(llvm::StringRef message, + llvm::StringRef backtrace, + llvm::StringRef prompt) { + llvm::errs() << message << '\n'; + llvm::errs() << backtrace; // Backtrace includes a newline. + llvm::errs() << prompt << '\n'; +} + +static std::atomic<LLDBAssertCallback> g_lldb_assert_callback = + &DefaultAssertCallback; + +void lldb_assert(bool expression, const char *expr_text, const char *func, + const char *file, unsigned int line) { if (LLVM_LIKELY(expression)) return; @@ -35,10 +44,21 @@ void lldb_private::lldb_assert(bool expression, const char *expr_text, // Print a warning and encourage the user to file a bug report, similar to // LLVM’s crash handler, and then return execution. - errs() << format("Assertion failed: (%s), function %s, file %s, line %u\n", - expr_text, func, file, line); - errs() << "backtrace leading to the failure:\n"; - llvm::sys::PrintStackTrace(errs()); - errs() << "please file a bug report against lldb reporting this failure " - "log, and as many details as possible\n"; + std::string buffer; + llvm::raw_string_ostream backtrace(buffer); + llvm::sys::PrintStackTrace(backtrace); + + (*g_lldb_assert_callback.load())( + llvm::formatv("Assertion failed: ({0}), function {1}, file {2}, line {3}", + expr_text, func, file, line) + .str(), + backtrace.str(), + "Please file a bug report against lldb reporting this failure log, and " + "as many details as possible"); } + +void SetLLDBAssertCallback(LLDBAssertCallback callback) { + g_lldb_assert_callback.exchange(callback); +} + +} // namespace lldb_private _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits