From d5576b1cb8422e38716c99aab34622b5dc23437c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Tue, 30 Sep 2014 09:50:22 +0200 Subject: [PATCH] Add support for gcc/clang's sanitize features GCC and Clang support compiler intrinsic error detections tools: address, memory, thread, undefined Let users conveniently enable it in qmake, for instance with CONFIG += sanitizer sanitize_address Also add a -sanitize [...] option to configure to use it by default for both the Qt libraries, and user applications. [ChangeLog][configure] Added support for GCC/Clang -fsanitize= options Change-Id: Ie5418abcdf41842566df510d7707e41739e66f87 Reviewed-by: Oswald Buddenhagen --- configure | 49 ++++++++++++++++++++++++++++++++++ mkspecs/common/gcc-base.conf | 2 ++ mkspecs/common/sanitize.conf | 23 ++++++++++++++++ mkspecs/features/sanitizer.prf | 30 +++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 mkspecs/common/sanitize.conf create mode 100644 mkspecs/features/sanitizer.prf diff --git a/configure b/configure index bcde69eca5..d610759ae2 100755 --- a/configure +++ b/configure @@ -716,6 +716,11 @@ CFG_PULSEAUDIO=auto CFG_COREWLAN=auto CFG_ICU=auto CFG_FORCE_ASSERTS=no +CFG_SANITIZERS=none +CFG_SANITIZE_ADDRESS=no +CFG_SANITIZE_THREAD=no +CFG_SANITIZE_MEMORY=no +CFG_SANITIZE_UNDEFINED=no CFG_PCRE=auto QPA_PLATFORM_GUARD=yes CFG_CXX11=auto @@ -887,6 +892,7 @@ while [ "$#" -gt 0 ]; do -qpa| \ -qconfig| \ -qreal| \ + -sanitize| \ -xkb-config-root| \ -android-sdk| \ -android-ndk| \ @@ -1158,6 +1164,25 @@ while [ "$#" -gt 0 ]; do print "\"$result\"";' "$CFG_QREAL"` fi ;; + sanitize) + if [ "$VAL" = "address" ]; then + CFG_SANITIZE_ADDRESS=yes + elif [ "$VAL" = "thread" ]; then + CFG_SANITIZE_THREAD=yes + elif [ "$VAL" = "memory" ]; then + CFG_SANITIZE_MEMORY=yes + elif [ "$VAL" = "undefined" ]; then + CFG_SANITIZE_UNDEFINED=yes + else + echo "Unknown sanitizer: '$VAL'" + ERROR=true + fi + if [ "$CFG_SANITIZERS" = "none" ]; then + CFG_SANITIZERS=$VAL + else + CFG_SANITIZERS="$CFG_SANITIZERS $VAL" + fi + ;; sysroot) CFG_SYSROOT="$VAL" ;; @@ -2466,6 +2491,8 @@ Additional options: -force-asserts ........ Force Q_ASSERT to be enabled even in release builds. + -sanitize [address|thread|memory|undefined] Enables the specified compiler sanitizer. + -device ............... Cross-compile for device (experimental) -device-option ... Add device specific options for the device mkspec (experimental) @@ -5816,6 +5843,27 @@ if [ "$CFG_FORCE_ASSERTS" = "yes" ]; then QT_CONFIG="$QT_CONFIG force_asserts" fi +if [ "$CFG_SANITIZERS" != "none" ]; then + + QTCONFIG_CONFIG="$QTCONFIG_CONFIG sanitizer" + + if [ "$CFG_SANITIZE_ADDRESS" = "yes" ]; then + QTCONFIG_CONFIG="$QTCONFIG_CONFIG sanitize_address" + fi + + if [ "$CFG_SANITIZE_THREAD" = "yes" ]; then + QTCONFIG_CONFIG="$QTCONFIG_CONFIG sanitize_thread" + fi + + if [ "$CFG_SANITIZE_MEMORY" = "yes" ]; then + QTCONFIG_CONFIG="$QTCONFIG_CONFIG sanitize_memory" + fi + + if [ "$CFG_SANITIZE_UNDEFINED" = "yes" ]; then + QTCONFIG_CONFIG="$QTCONFIG_CONFIG sanitize_undefined" + fi +fi + if [ "$CFG_PCRE" = "qt" ]; then QMAKE_CONFIG="$QMAKE_CONFIG pcre" fi @@ -6503,6 +6551,7 @@ else echo " Mode ................... $build_mode" fi unset build_mode release +echo " Using sanitizer(s)...... $CFG_SANITIZERS" echo " Using C++11 ............ $CFG_CXX11" echo " Using gold linker....... $CFG_USE_GOLD_LINKER" echo " Using PCH .............. $CFG_PRECOMPILE" diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index a149f4d907..8310db52cc 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -80,3 +80,5 @@ QMAKE_CFLAGS_SSE4_2 += -msse4.2 QMAKE_CFLAGS_AVX += -mavx QMAKE_CFLAGS_AVX2 += -mavx2 QMAKE_CFLAGS_NEON += -mfpu=neon + +include(sanitize.conf) diff --git a/mkspecs/common/sanitize.conf b/mkspecs/common/sanitize.conf new file mode 100644 index 0000000000..5e09406cfb --- /dev/null +++ b/mkspecs/common/sanitize.conf @@ -0,0 +1,23 @@ +# +# Qmake configuration for the GCC / Clang sanitize features +# + +QMAKE_COMMON_SANITIZE_CFLAGS = -fno-omit-frame-pointer +QMAKE_COMMON_SANITIZE_CXXFLAGS = -fno-omit-frame-pointer + +QMAKE_SANITIZE_ADDRESS_CFLAGS = -fsanitize=address +QMAKE_SANITIZE_ADDRESS_CXXFLAGS = -fsanitize=address +QMAKE_SANITIZE_ADDRESS_LFLAGS = -fsanitize=address + +QMAKE_SANITIZE_THREAD_CFLAGS = -fsanitize=thread +QMAKE_SANITIZE_THREAD_CXXFLAGS = -fsanitize=thread +QMAKE_SANITIZE_THREAD_LFLAGS = -fsanitize=thread + +QMAKE_SANITIZE_MEMORY_CFLAGS = -fsanitize=memory +QMAKE_SANITIZE_MEMORY_CXXFLAGS = -fsanitize=memory +QMAKE_SANITIZE_MEMORY_LFLAGS = -fsanitize=memory + +QMAKE_SANITIZE_UNDEFINED_CFLAGS = -fsanitize=undefined +QMAKE_SANITIZE_UNDEFINED_CXXFLAGS = -fsanitize=undefined +QMAKE_SANITIZE_UNDEFINED_LFLAGS = -fsanitize=undefined + diff --git a/mkspecs/features/sanitizer.prf b/mkspecs/features/sanitizer.prf new file mode 100644 index 0000000000..9e7ff0218a --- /dev/null +++ b/mkspecs/features/sanitizer.prf @@ -0,0 +1,30 @@ +# Sanitizer flags + + +sanitize_address { + QMAKE_CFLAGS += $$QMAKE_SANITIZE_ADDRESS_CFLAGS + QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_ADDRESS_CXXFLAGS + QMAKE_LFLAGS += $$QMAKE_SANITIZE_ADDRESS_LFLAGS +} + +sanitize_memory { + QMAKE_CFLAGS += $$QMAKE_SANITIZE_MEMORY_CFLAGS + QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_MEMORY_CXXFLAGS + QMAKE_LFLAGS += $$QMAKE_SANITIZE_MEMORY_LFLAGS +} + +sanitize_thread { + QMAKE_CFLAGS += $$QMAKE_SANITIZE_THREAD_CFLAGS + QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_THREAD_CXXFLAGS + QMAKE_LFLAGS += $$QMAKE_SANITIZE_THREAD_LFLAGS +} + +sanitize_undefined { + QMAKE_CFLAGS += $$QMAKE_SANITIZE_UNDEFINED_CFLAGS + QMAKE_CXXFLAGS += $$QMAKE_SANITIZE_UNDEFINED_CXXFLAGS + QMAKE_LFLAGS += $$QMAKE_SANITIZE_UNDEFINED_LFLAGS +} + +QMAKE_CFLAGS += $$QMAKE_COMMON_SANITIZE_CFLAGS +QMAKE_CXXFLAGS += $$QMAKE_COMMON_SANITIZE_CXXFLAGS +