--- /dev/null
+/*===-- clang-c/FatalErrorHandler.h - Fatal Error Handling --------*- C -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_FATAL_ERROR_HANDLER_H
+#define LLVM_CLANG_C_FATAL_ERROR_HANDLER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Installs error handler that prints error message to stderr and calls abort().
+ * Replaces currently installed error handler (if any).
+ */
+void clang_install_aborting_llvm_fatal_error_handler();
+
+/**
+ * Removes currently installed error handler (if any).
+ * If no error handler is intalled, the default strategy is to print error
+ * message to stderr and call exit(1).
+ */
+void clang_uninstall_llvm_fatal_error_handler();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
#include "CXTranslationUnit.h"
#include "CXType.h"
#include "CursorVisitor.h"
+#include "clang-c/FatalErrorHandler.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/StmtVisitor.h"
// Misc. API hooks.
//===----------------------------------------------------------------------===//
-static void fatal_error_handler(void *user_data, const std::string& reason,
- bool gen_crash_diag) {
- // Write the result out to stderr avoiding errs() because raw_ostreams can
- // call report_fatal_error.
- fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
- ::abort();
-}
-
namespace {
struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler() {
- llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
+ clang_install_aborting_llvm_fatal_error_handler();
}
};
}
CXString.cpp
CXType.cpp
Indexing.cpp
+ FatalErrorHandler.cpp
ADDITIONAL_HEADERS
CIndexDiagnostic.h
clangSema
clangSerialization
clangTooling
+ LLVMSupport
)
if (CLANG_ENABLE_ARCMT)
--- /dev/null
+/*===-- clang-c/FatalErrorHandler.cpp - Fatal Error Handling ------*- C -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#include "clang-c/FatalErrorHandler.h"
+#include "llvm/Support/ErrorHandling.h"
+
+static void aborting_fatal_error_handler(void *, const std::string &reason,
+ bool) {
+ // Write the result out to stderr avoiding errs() because raw_ostreams can
+ // call report_fatal_error.
+ fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
+ ::abort();
+}
+
+void clang_install_aborting_llvm_fatal_error_handler() {
+ llvm::remove_fatal_error_handler();
+ llvm::install_fatal_error_handler(aborting_fatal_error_handler, nullptr);
+}
+
+void clang_uninstall_llvm_fatal_error_handler() {
+ llvm::remove_fatal_error_handler();
+}
clang_PrintingPolicy_getProperty
clang_PrintingPolicy_setProperty
clang_PrintingPolicy_dispose
+clang_install_aborting_llvm_fatal_error_handler
+clang_uninstall_llvm_fatal_error_handler
PRIVATE
libclang
)
+
+add_subdirectory(CrashTests)
--- /dev/null
+add_clang_unittest(libclangCrashTests
+ LibclangCrashTest.cpp
+ )
+
+target_link_libraries(libclangCrashTests
+ PRIVATE
+ libclang
+ )
--- /dev/null
+//===- unittests/libclang/LibclangCrashTest.cpp --- libclang tests --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../TestUtils.h"
+#include "clang-c/FatalErrorHandler.h"
+#include "gtest/gtest.h"
+#include <string>
+
+TEST_F(LibclangParseTest, InstallAbortingLLVMFatalErrorHandler) {
+ clang_toggleCrashRecovery(0);
+ clang_install_aborting_llvm_fatal_error_handler();
+
+ std::string Main = "main.h";
+ WriteFile(Main, "#pragma clang __debug llvm_fatal_error");
+
+ EXPECT_DEATH(clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0,
+ nullptr, 0, TUFlags),
+ "");
+}
+
+TEST_F(LibclangParseTest, UninstallAbortingLLVMFatalErrorHandler) {
+ clang_toggleCrashRecovery(0);
+ clang_install_aborting_llvm_fatal_error_handler();
+ clang_uninstall_llvm_fatal_error_handler();
+
+ std::string Main = "main.h";
+ WriteFile(Main, "#pragma clang __debug llvm_fatal_error");
+
+ EXPECT_NO_FATAL_FAILURE(clang_parseTranslationUnit(
+ Index, Main.c_str(), nullptr, 0, nullptr, 0, TUFlags));
+}