[llvm-dev] [RFC] Runtime checks for ABI breaking build of LLVM
Mehdi Amini via llvm-dev
llvm-dev at lists.llvm.org
Wed Nov 16 10:48:34 PST 2016
Hi all,
An issue that come up from time to time and has cost hours for debug for many of us and users of LLVM is that an assert build isn’t ABI compatible with a release build.
The CMake flags that controls this behavior is LLVM_ABI_BREAKING_CHECKS (
LLVM_ABI_BREAKING_CHECKS:STRING
Used to decide if LLVM should be built with ABI breaking checks or not. Allowed values are WITH_ASSERTS (default), FORCE_ON and FORCE_OFF. WITH_ASSERTS turns on ABI breaking checks in an assertion enabled build. FORCE_ON (FORCE_OFF) turns them on (off) irrespective of whether normal (NDEBUG-based) assertions are enabled or not. A version of LLVM built with ABI breaking checks is not ABI compatible with a version built without it.
I propose to add a runtime check to detect when we have incorrectly setup build.
The idea is that every translation unit that includes such header will get a weak definition of a symbol with an initializer calling the runtime check. The symbol name would be different if the ABI break is enabled or not.
The runtime check maintains two boolean to track if it there is in the image at least a translation unit for each value of this flag. If both flags are set the process is aborted.
The cost is *one* static initializer per DSO (or per image I believe).
A straw-man patch (likely not windows compatible because of weak) is:
diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake
index 4121e865ea00..4274c942d3b6 100644
--- a/llvm/include/llvm/Config/llvm-config.h.cmake
+++ b/llvm/include/llvm/Config/llvm-config.h.cmake
@@ -80,4 +80,18 @@
/* LLVM version string */
#define LLVM_VERSION_STRING "${PACKAGE_VERSION}"
+
+#ifdef __cplusplus
+namespace llvm {
+bool setABIBreakingChecks(bool Enabled);
+__attribute__((weak))
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+bool
+ABICheckEnabled = setABIBreakingChecks(true);
+#else
+bool ABICheckDisabled = setABIBreakingChecks(true);
+#endif
+}
+#endif
+
#endif
diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp
index 7436a1fd38ee..151fcdcbfb27 100644
--- a/llvm/lib/Support/Error.cpp
+++ b/llvm/lib/Support/Error.cpp
@@ -112,3 +112,17 @@ void report_fatal_error(Error Err, bool GenCrashDiag) {
}
}
+
+
+bool llvm::setABIBreakingChecks(bool Enabled) {
+ static char abi_breaking_checks_enabled = 0;
+ static char abi_breaking_checks_disabled = 0;
+ if (Enabled)
+ abi_breaking_checks_enabled = 1;
+ else
+ abi_breaking_checks_disabled = 1;
+ if (abi_breaking_checks_enabled && abi_breaking_checks_disabled)
+ report_fatal_error("Error initializing LLVM: mixing translation units built"
+ "with and without LLVM_ABI_BREAKING_CHECKS");
+ return true;
+}
—
Mehdi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161116/acad9e06/attachment.html>
More information about the llvm-dev
mailing list