Added option for static linking gcc sanitizers.

If you like to preload a sanitized library in front of an application, it will
fail, because it is not the first in the library list anymore. This behaviour
is gcc specific - clang will static link the sanitizers instead. To get the
same for gcc, the new SANITIZE_LINK_STATIC flag will link the sanitizers
static in gcc environments.

Note: The preloaded executable must be sanitized, too! Otherwise ASan will
      print an error message!
This commit is contained in:
Alexander Haase 2016-05-12 19:59:28 +02:00
parent a6b6ae43db
commit 179e77d612
3 changed files with 51 additions and 27 deletions

View File

@ -25,7 +25,8 @@
option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off) option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off)
set(FLAG_CANDIDATES set(FLAG_CANDIDATES
# Clang 3.2+ use this version # Clang 3.2+ use this version. The no-omit-frame-pointer option is optional.
"-g -sanitize=address -fno-omit-frame-pointer"
"-g -fsanitize=address" "-g -fsanitize=address"
# Older deprecated flag for ASan # Older deprecated flag for ASan

View File

@ -22,6 +22,13 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
# If any of the used compiler is a GNU compiler, add a second option to static
# link against the sanitizers.
option(SANITIZE_LINK_STATIC "Try to link static against sanitizers." Off)
set(FIND_QUIETLY_FLAG "") set(FIND_QUIETLY_FLAG "")
if (DEFINED Sanitizers_FIND_QUIETLY) if (DEFINED Sanitizers_FIND_QUIETLY)
set(FIND_QUIETLY_FLAG "QUIET") set(FIND_QUIETLY_FLAG "QUIET")

View File

@ -66,6 +66,33 @@ function (sanitizer_target_compilers TARGET RETURN_VAR)
endfunction () endfunction ()
# Helper function to check compiler flags for language compiler.
function (sanitizer_check_compiler_flag FLAG LANG VARIABLE)
if (${LANG} STREQUAL "C")
include(CheckCCompilerFlag)
check_c_compiler_flag("${FLAG}" ${VARIABLE})
elseif (${LANG} STREQUAL "CXX")
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("${FLAG}" ${VARIABLE})
elseif (${LANG} STREQUAL "Fortran")
# CheckFortranCompilerFlag was introduced in CMake 3.x. To be compatible
# with older Cmake versions, we will check if this module is present
# before we use it. Otherwise we will define Fortran coverage support as
# not available.
include(CheckFortranCompilerFlag OPTIONAL RESULT_VARIABLE INCLUDED)
if (INCLUDED)
check_fortran_compiler_flag("${FLAG}" ${VARIABLE})
elseif (NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VARIABLE}")
message(STATUS "Performing Test ${VARIABLE}"
" - Failed (Check not supported)")
endif ()
endif()
endfunction ()
# Helper function to test compiler flags. # Helper function to test compiler flags.
function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX) function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX)
set(CMAKE_REQUIRED_QUIET ${${PREFIX}_FIND_QUIETLY}) set(CMAKE_REQUIRED_QUIET ${${PREFIX}_FIND_QUIETLY})
@ -84,34 +111,23 @@ function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX)
set(CMAKE_REQUIRED_FLAGS "${FLAG}") set(CMAKE_REQUIRED_FLAGS "${FLAG}")
unset(${PREFIX}_FLAG_DETECTED CACHE) unset(${PREFIX}_FLAG_DETECTED CACHE)
sanitizer_check_compiler_flag("${FLAG}" ${LANG}
if (${LANG} STREQUAL "C")
include(CheckCCompilerFlag)
check_c_compiler_flag("${FLAG}" ${PREFIX}_FLAG_DETECTED)
elseif (${LANG} STREQUAL "CXX")
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("${FLAG}" ${PREFIX}_FLAG_DETECTED)
elseif (${LANG} STREQUAL "Fortran")
# CheckFortranCompilerFlag was introduced in CMake 3.x. To
# be compatible with older Cmake versions, we will check if
# this module is present before we use it. Otherwise we will
# define Fortran coverage support as not available.
include(CheckFortranCompilerFlag OPTIONAL
RESULT_VARIABLE INCLUDED)
if (INCLUDED)
check_fortran_compiler_flag("${FLAG}"
${PREFIX}_FLAG_DETECTED) ${PREFIX}_FLAG_DETECTED)
elseif (NOT CMAKE_REQUIRED_QUIET)
message(STATUS
"Performing Test ${PREFIX}_FLAG_DETECTED")
message(STATUS "Performing Test ${PREFIX}_FLAG_DETECTED"
" - Failed (Check not supported)")
endif ()
endif()
if (${PREFIX}_FLAG_DETECTED) if (${PREFIX}_FLAG_DETECTED)
# If compiler is a GNU compiler, search for static flag, if
# SANITIZE_LINK_STATIC is enabled.
if (SANITIZE_LINK_STATIC)
string(TOLOWER ${PREFIX} PREFIX_lower)
sanitizer_check_compiler_flag(
"-static-lib${PREFIX_lower}" ${LANG}
${PREFIX}_STATIC_FLAG_DETECTED)
if (${PREFIX}_STATIC_FLAG_DETECTED)
set(FLAG "-static-lib${PREFIX_lower} ${FLAG}")
endif ()
endif ()
set(${PREFIX}_${COMPILER}_FLAGS "${FLAG}" CACHE STRING set(${PREFIX}_${COMPILER}_FLAGS "${FLAG}" CACHE STRING
"${NAME} flags for ${COMPILER} compiler.") "${NAME} flags for ${COMPILER} compiler.")
mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS) mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS)