Index: lldb/include/lldb/Core/Debugger.h =================================================================== --- lldb/include/lldb/Core/Debugger.h +++ lldb/include/lldb/Core/Debugger.h @@ -128,6 +128,9 @@ const ExecutionContext *exe_ctx, const Address *addr, Stream &s); + static void AssertCallback(std::string message, std::string backtrace, + std::string prompt); + void Clear(); bool GetAsyncExecution(); @@ -395,7 +398,6 @@ /// Since the two checks are mutually exclusive, however, it's also convenient /// to have just one function to check the interrupt state. - /// Bump the "interrupt requested" count on the debugger to support /// cooperative interruption. If this is non-zero, InterruptRequested will /// return true. Interruptible operations are expected to query the Index: lldb/include/lldb/Utility/LLDBAssert.h =================================================================== --- lldb/include/lldb/Utility/LLDBAssert.h +++ lldb/include/lldb/Utility/LLDBAssert.h @@ -9,6 +9,8 @@ #ifndef LLDB_UTILITY_LLDBASSERT_H #define LLDB_UTILITY_LLDBASSERT_H +#include + #ifndef NDEBUG #define lldbassert(x) assert(x) #else @@ -29,6 +31,11 @@ namespace lldb_private { void lldb_assert(bool expression, const char *expr_text, const char *func, const char *file, unsigned int line); + +typedef void (*LLDBAssertCallback)(std::string message, std::string backtrace, + std::string prompt); + +void SetLLDBAssertCallback(LLDBAssertCallback callback); } // namespace lldb_private #endif // LLDB_UTILITY_LLDBASSERT_H Index: lldb/source/API/SystemInitializerFull.cpp =================================================================== --- lldb/source/API/SystemInitializerFull.cpp +++ lldb/source/API/SystemInitializerFull.cpp @@ -78,6 +78,9 @@ // Settings must be initialized AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); + // Use the Debugger's LLDBAssert callback. + SetLLDBAssertCallback(Debugger::AssertCallback); + return llvm::Error::success(); } Index: lldb/source/Core/Debugger.cpp =================================================================== --- lldb/source/Core/Debugger.cpp +++ lldb/source/Core/Debugger.cpp @@ -1352,6 +1352,11 @@ function_changed, initial_function); } +void Debugger::AssertCallback(std::string message, std::string backtrace, + std::string prompt) { + Debugger::ReportError(message + "\n" + backtrace + prompt); +} + 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 Index: lldb/source/Utility/LLDBAssert.cpp =================================================================== --- lldb/source/Utility/LLDBAssert.cpp +++ 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 #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 DefaultLLDBAssertCallback(std::string message, + std::string backtrace, + std::string prompt) { + llvm::errs() << message << '\n'; + llvm::errs() << backtrace; // Backtrace includes a newline. + llvm::errs() << prompt << '\n'; +} + +static std::atomic g_lldb_assert_callback = + &DefaultLLDBAssertCallback; + +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 @@ // 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