diff --git a/lldb/include/lldb/Utility/LLDBAssert.h b/lldb/include/lldb/Utility/LLDBAssert.h index 21dbdb3b3202d..cc0146be25998 100644 --- a/lldb/include/lldb/Utility/LLDBAssert.h +++ b/lldb/include/lldb/Utility/LLDBAssert.h @@ -10,6 +10,7 @@ #define LLDB_UTILITY_LLDBASSERT_H #include "llvm/ADT/StringRef.h" +#include #ifndef NDEBUG #define lldbassert(x) assert(x) @@ -19,8 +20,11 @@ // __FILE__ but only renders the last path component (the filename) instead of // an invocation dependent full path to that file. #define lldbassert(x) \ - lldb_private::_lldb_assert(static_cast(x), #x, __FUNCTION__, \ - __FILE_NAME__, __LINE__) + do { \ + static std::once_flag _once_flag; \ + lldb_private::_lldb_assert(static_cast(x), #x, __FUNCTION__, \ + __FILE_NAME__, __LINE__, _once_flag); \ + } while (0) #else #define lldbassert(x) \ lldb_private::_lldb_assert(static_cast(x), #x, __FUNCTION__, __FILE__, \ @@ -33,7 +37,8 @@ namespace lldb_private { /// Don't use _lldb_assert directly. Use the lldbassert macro instead so that /// LLDB asserts become regular asserts in NDEBUG builds. void _lldb_assert(bool expression, const char *expr_text, const char *func, - const char *file, unsigned int line); + const char *file, unsigned int line, + std::once_flag &once_flag); /// The default LLDB assert callback, which prints to stderr. typedef void (*LLDBAssertCallback)(llvm::StringRef message, diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt index 17ab33f7c55b8..00b9f2390c15f 100644 --- a/lldb/source/Core/CMakeLists.txt +++ b/lldb/source/Core/CMakeLists.txt @@ -71,6 +71,7 @@ add_lldb_library(lldbCore lldbTarget lldbUtility lldbValueObject + lldbVersion lldbPluginCPlusPlusLanguage lldbPluginObjCLanguage ${LLDB_CURSES_LIBS} diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index aef3c8f1e7322..41629dc949270 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -52,6 +52,7 @@ #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" +#include "lldb/Version/Version.h" #include "lldb/lldb-enumerations.h" #if defined(_WIN32) @@ -1546,8 +1547,9 @@ bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format, void Debugger::AssertCallback(llvm::StringRef message, llvm::StringRef backtrace, llvm::StringRef prompt) { - Debugger::ReportError( - llvm::formatv("{0}\n{1}{2}", message, backtrace, prompt).str()); + Debugger::ReportError(llvm::formatv("{0}\n{1}{2}\n{3}", message, backtrace, + GetVersion(), prompt) + .str()); } void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, diff --git a/lldb/source/Utility/LLDBAssert.cpp b/lldb/source/Utility/LLDBAssert.cpp index d7adb52f95fa4..611ad43cd071b 100644 --- a/lldb/source/Utility/LLDBAssert.cpp +++ b/lldb/source/Utility/LLDBAssert.cpp @@ -11,6 +11,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" +#include #if LLVM_SUPPORT_XCODE_SIGNPOSTS #include @@ -33,29 +34,33 @@ static std::atomic g_lldb_assert_callback = &DefaultAssertCallback; void _lldb_assert(bool expression, const char *expr_text, const char *func, - const char *file, unsigned int line) { + const char *file, unsigned int line, + std::once_flag &once_flag) { if (LLVM_LIKELY(expression)) return; + std::call_once(once_flag, [&]() { #if LLVM_SUPPORT_XCODE_SIGNPOSTS - if (__builtin_available(macos 10.12, iOS 10, tvOS 10, watchOS 3, *)) { - os_log_fault(OS_LOG_DEFAULT, - "Assertion failed: (%s), function %s, file %s, line %u\n", - expr_text, func, file, line); - } + if (__builtin_available(macos 10.12, iOS 10, tvOS 10, watchOS 3, *)) { + os_log_fault(OS_LOG_DEFAULT, + "Assertion failed: (%s), function %s, file %s, line %u\n", + expr_text, func, file, line); + } #endif - std::string buffer; - llvm::raw_string_ostream backtrace(buffer); - llvm::sys::PrintStackTrace(backtrace); + 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(), - buffer, - "Please file a bug report against lldb reporting this failure log, and " - "as many details as possible"); + (*g_lldb_assert_callback.load())( + llvm::formatv( + "Assertion failed: ({0}), function {1}, file {2}, line {3}", + expr_text, func, file, line) + .str(), + buffer, + "Please file a bug report against lldb and include the backtrace, the " + "version and as many details as possible."); + }); } void SetLLDBAssertCallback(LLDBAssertCallback callback) {