mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 06:40:01 +08:00
[lldb] Make lldbassert fire only once per instance (#134343)
The `lldbassert` macro in LLDB behaves like a regular `assert` when assertions are enabled, and otherwise prints a pretty backtrace and prompts the user to file a bug. By default, this is emitted as a diagnostic event, but vendors can provide their own behavior, for example pre-populating a bug report. Recently, we ran into an issue where an `lldbassert` (in the Swift language plugin) would fire excessively, to the point that it was interfering with the usability of the debugger. Once an `lldbasser` has fired, there's no point in bothering the user over and over again for the same problem. This PR solves the problem by introducing a static `std::once_flag` in the macro. This way, every `lldbasser` will fire at most once per lldb instance. rdar://148520448
This commit is contained in:
committed by
GitHub
parent
9069ba183d
commit
03604a7840
@@ -10,6 +10,7 @@
|
||||
#define LLDB_UTILITY_LLDBASSERT_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <mutex>
|
||||
|
||||
#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<bool>(x), #x, __FUNCTION__, \
|
||||
__FILE_NAME__, __LINE__)
|
||||
do { \
|
||||
static std::once_flag _once_flag; \
|
||||
lldb_private::_lldb_assert(static_cast<bool>(x), #x, __FUNCTION__, \
|
||||
__FILE_NAME__, __LINE__, _once_flag) \
|
||||
} while (0)
|
||||
#else
|
||||
#define lldbassert(x) \
|
||||
lldb_private::_lldb_assert(static_cast<bool>(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,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <mutex>
|
||||
|
||||
#if LLVM_SUPPORT_XCODE_SIGNPOSTS
|
||||
#include <os/log.h>
|
||||
@@ -33,29 +34,33 @@ 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) {
|
||||
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 and include the backtrace, the "
|
||||
"version 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) {
|
||||
|
||||
Reference in New Issue
Block a user