Fix a bug in my previous patch by restoring the behavior that the fatal

error handler is only registered once.

To avoid the use of std::call_once (the obvious way to do this) I've
wrapped everything up into a managed static and done the work in
a constructor. Silly, but it should be effective.

Some out-of-tree libclang users reported this to me, and I've asked them
to put together a test case which exhibits this behavior, but I wanted
to fix things ASAP since the nature of the fix is straight forward.

llvm-svn: 211905
This commit is contained in:
Chandler Carruth 2014-06-27 16:37:27 +00:00
parent 637f6cceee
commit 6666074876
1 changed files with 14 additions and 1 deletions

View File

@ -2600,6 +2600,16 @@ static void fatal_error_handler(void *user_data, const std::string& reason,
::abort(); ::abort();
} }
namespace {
struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler() {
llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
}
};
}
static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
extern "C" { extern "C" {
CXIndex clang_createIndex(int excludeDeclarationsFromPCH, CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
int displayDiagnostics) { int displayDiagnostics) {
@ -2608,7 +2618,10 @@ CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY")) if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
llvm::CrashRecoveryContext::Enable(); llvm::CrashRecoveryContext::Enable();
llvm::install_fatal_error_handler(fatal_error_handler, nullptr); // Look through the managed static to trigger construction of the managed
// static which registers our fatal error handler. This ensures it is only
// registered once.
(void)*RegisterFatalErrorHandlerOnce;
CIndexer *CIdxr = new CIndexer(); CIndexer *CIdxr = new CIndexer();
if (excludeDeclarationsFromPCH) if (excludeDeclarationsFromPCH)