Skip to content

Commit 10ccf25

Browse files
committed
Cpu: disable IFUNC with sanitizers, and fail if it's enabled on them.
Since Corrade can be built without -fsanitize= first and then used by code that has -fsanitize= enabled, there needs to be also a check directly inside configure.h.
1 parent eccc8cb commit 10ccf25

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

CMakeLists.txt

+22
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,28 @@ int main() { return foo() - 42; }\
221221
endif()
222222
set(_CORRADE_CPU_USE_IFUNC_DEFAULT OFF)
223223
endif()
224+
225+
# If sanitizers are enabled, call into the dispatch function crashes.
226+
# Upstream bugreport https://github.com/google/sanitizers/issues/342
227+
# suggests using __attribute__((no_sanitize_address)), but that doesn't
228+
# work / can't be used because it would mean marking basically
229+
# everything including the actual implementation that's being
230+
# dispatched to.
231+
#
232+
# Sanitizers can be also enabled any other way such as with
233+
# CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER or with per-target properties
234+
# which isn't easy to detect, so as a secondary measure there's a kill
235+
# switch in Corrade/configure.h that will fail with an error if a
236+
# sanitizer is detected and CORRADE_CPU_USE_IFUNC is enabled.
237+
#
238+
# While Clang and GCC use -fsanitize=whatever, MSVC allows also
239+
# /fsanitize=, so catch both.
240+
if(CMAKE_CXX_FLAGS MATCHES "[-/]fsanitize=")
241+
if(NOT DEFINED CORRADE_CPU_USE_IFUNC)
242+
message(WARNING "Disabling CORRADE_CPU_USE_IFUNC by default as it crashes when used together with sanitizers. See https://github.com/google/sanitizers/issues/342 for more information.")
243+
endif()
244+
set(_CORRADE_CPU_USE_IFUNC_DEFAULT OFF)
245+
endif()
224246
else()
225247
set(_CORRADE_CPU_USE_IFUNC_DEFAULT OFF)
226248
endif()

src/Corrade/configure.h.cmake

+19
Original file line numberDiff line numberDiff line change
@@ -361,4 +361,23 @@ static_assert(sizeof(1 ? "" : "") == 1,
361361
"enabled or ensure /permissive- is set for all files that include Corrade " "headers.");
362362
#endif
363363

364+
/* Kill switch for when presence of a sanitizer is detected and
365+
CORRADE_CPU_USE_IFUNC is enabled. Unfortunately in our case the
366+
__attribute__((no_sanitize_address)) workaround as described on
367+
https://github.com/google/sanitizers/issues/342 doesn't work / can't be used
368+
because it would mean marking basically everything including the actual
369+
implementation that's being dispatched to. */
370+
#ifdef CORRADE_CPU_USE_IFUNC
371+
#ifdef __has_feature
372+
#if __has_feature(address_sanitizer) || __has_feature(thread_sanitizer) || __has_feature(memory_sanitizer) || __has_feature(undefined_behavior_sanitizer)
373+
#define _CORRADE_SANITIZER_IFUNC_DETECTED
374+
#endif
375+
#elif defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__)
376+
#define _CORRADE_SANITIZER_IFUNC_DETECTED
377+
#endif
378+
#ifdef _CORRADE_SANITIZER_IFUNC_DETECTED
379+
#error Corrade was built with CORRADE_CPU_USE_IFUNC, which is incompatible with sanitizers. Rebuild without this option or disable sanitizers.
380+
#endif
381+
#endif
382+
364383
#endif // kate: hl c++

0 commit comments

Comments
 (0)