Skip to content

Commit 7fff2f1

Browse files
committed
Merge commit '3d86073df164f7ab64fc90416f40d03255e75c2f' as 'cmake/sanitizers-cmake'
2 parents 927be23 + 3d86073 commit 7fff2f1

File tree

14 files changed

+861
-0
lines changed

14 files changed

+861
-0
lines changed

cmake/sanitizers-cmake/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# out-of-source build top-level folders.
2+
build/
3+
_build/
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# This file is part of CMake-sanitizers.
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
#
21+
#
22+
# Copyright (c)
23+
# 2013-2015 Matt Arsenault
24+
# 2015 RWTH Aachen University, Federal Republic of Germany
25+
#
26+
27+
28+
#
29+
# project information
30+
#
31+
32+
# minimum required cmake version
33+
cmake_minimum_required(VERSION 2.8.12)
34+
35+
# project name
36+
project("CMake-sanitizers")
37+
38+
39+
40+
#
41+
# cmake configuration
42+
#
43+
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
44+
45+
46+
47+
#
48+
# add tests
49+
#
50+
enable_testing()
51+
add_subdirectory(tests)

cmake/sanitizers-cmake/LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c)
4+
2013 Matthew Arsenault
5+
2015-2016 RWTH Aachen University, Federal Republic of Germany
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of
8+
this software and associated documentation files (the "Software"), to deal in
9+
the Software without restriction, including without limitation the rights to
10+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11+
the Software, and to permit persons to whom the Software is furnished to do so,
12+
subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

cmake/sanitizers-cmake/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# sanitizers-cmake
2+
3+
[![](https://img.shields.io/github/issues-raw/arsenm/sanitizers-cmake.svg?style=flat-square)](https://github.com/arsenm/sanitizers-cmake/issues)
4+
[![MIT](http://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)
5+
6+
CMake module to enable sanitizers for binary targets.
7+
8+
9+
## Include into your project
10+
11+
To use [FindSanitizers.cmake](cmake/FindSanitizers.cmake), simply add this repository as git submodule into your own repository
12+
```Shell
13+
mkdir externals
14+
git submodule add [email protected]:arsenm/sanitizers-cmake.git externals/sanitizers-cmake
15+
```
16+
and adding ```externals/sanitizers-cmake/cmake``` to your ```CMAKE_MODULE_PATH```
17+
```CMake
18+
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
19+
```
20+
21+
If you don't use git or dislike submodules you can copy the files in [cmake directory](cmake) into your repository. *Be careful and keep updates in mind!*
22+
23+
Now you can simply run ```find_package``` in your CMake files:
24+
```CMake
25+
find_package(Sanitizers)
26+
```
27+
28+
29+
## Usage
30+
31+
You can enable the sanitizers with ``SANITIZE_ADDRESS``, ``SANITIZE_MEMORY``, ``SANITIZE_THREAD`` or ``SANITIZE_UNDEFINED`` options in your CMake configuration. You can do this by passing e.g. ``-DSANITIZE_ADDRESS=On`` on your command line or with your graphical interface.
32+
33+
If sanitizers are supported by your compiler, the specified targets will be build with sanitizer support. If your compiler has no sanitizing capabilities (I asume intel compiler doesn't) you'll get a warning but CMake will continue processing and sanitizing will simply just be ignored.
34+
35+
#### Compiler issues
36+
37+
Different compilers may be using different implementations for sanitizers. If you'll try to sanitize targets with C and Fortran code but don't use gcc & gfortran but clang & gfortran, this will cause linking problems. To avoid this, such problems will be detected and sanitizing will be disabled for these targets.
38+
39+
Even C only targets may cause problems in certain situations. Some problems have been seen with AddressSanitizer for preloading or dynamic linking. In such cases you may try the ``SANITIZE_LINK_STATIC`` to link sanitizers for gcc static.
40+
41+
42+
43+
## Build targets with sanitizer support
44+
45+
To enable sanitizer support you simply have to add ``add_sanitizers(<TARGET>)`` after defining your target. To provide a sanitizer blacklist file you can use the ``sanitizer_add_blacklist_file(<FILE>)`` function:
46+
```CMake
47+
find_package(Sanitizers)
48+
49+
sanitizer_add_blacklist_file("blacklist.txt")
50+
51+
add_executable(some_exe foo.c bar.c)
52+
add_sanitizers(some_exe)
53+
54+
add_library(some_lib foo.c bar.c)
55+
add_sanitizers(some_lib)
56+
```
57+
58+
## Run your application
59+
60+
The sanitizers check your program, while it's running. In some situations (e.g. LD_PRELOAD your target) it might be required to preload the used AddressSanitizer library first. In this case you may use the ``asan-wrapper`` script defined in ``ASan_WRAPPER`` variable to execute your application with ``${ASan_WRAPPER} myexe arg1 ...``.
61+
62+
63+
## Contribute
64+
65+
Anyone is welcome to contribute. Simply fork this repository, make your changes **in an own branch** and create a pull-request for your change. Please do only one change per pull-request.
66+
67+
You found a bug? Please fill out an [issue](https://github.com/arsenm/sanitizers-cmake/issues) and include any data to reproduce the bug.
68+
69+
70+
#### Contributors
71+
72+
* [Matt Arsenault](https://github.com/arsenm)
73+
* [Alexander Haase](https://github.com/alehaa)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c)
4+
# 2013 Matthew Arsenault
5+
# 2015-2016 RWTH Aachen University, Federal Republic of Germany
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
25+
option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off)
26+
27+
set(FLAG_CANDIDATES
28+
# MSVC uses
29+
"/fsanitize=address"
30+
31+
# Clang 3.2+ use this version. The no-omit-frame-pointer option is optional.
32+
"-g -fsanitize=address -fno-omit-frame-pointer"
33+
"-g -fsanitize=address"
34+
35+
# Older deprecated flag for ASan
36+
"-g -faddress-sanitizer"
37+
)
38+
39+
40+
if (SANITIZE_ADDRESS AND (SANITIZE_THREAD OR SANITIZE_MEMORY))
41+
message(FATAL_ERROR "AddressSanitizer is not compatible with "
42+
"ThreadSanitizer or MemorySanitizer.")
43+
endif ()
44+
45+
46+
include(sanitize-helpers)
47+
48+
if (SANITIZE_ADDRESS)
49+
sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "AddressSanitizer"
50+
"ASan")
51+
52+
find_program(ASan_WRAPPER "asan-wrapper" PATHS ${CMAKE_MODULE_PATH})
53+
mark_as_advanced(ASan_WRAPPER)
54+
endif ()
55+
56+
function (add_sanitize_address TARGET)
57+
if (NOT SANITIZE_ADDRESS)
58+
return()
59+
endif ()
60+
61+
sanitizer_add_flags(${TARGET} "AddressSanitizer" "ASan")
62+
endfunction ()
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c)
4+
# 2013 Matthew Arsenault
5+
# 2015-2016 RWTH Aachen University, Federal Republic of Germany
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
25+
option(SANITIZE_MEMORY "Enable MemorySanitizer for sanitized targets." Off)
26+
27+
set(FLAG_CANDIDATES
28+
# MSVC uses
29+
"/fsanitize=memory"
30+
# GNU/Clang
31+
"-g -fsanitize=memory"
32+
)
33+
34+
35+
include(sanitize-helpers)
36+
37+
if (SANITIZE_MEMORY)
38+
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
39+
message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
40+
"MemorySanitizer is supported for Linux systems only.")
41+
set(SANITIZE_MEMORY Off CACHE BOOL
42+
"Enable MemorySanitizer for sanitized targets." FORCE)
43+
elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
44+
message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
45+
"MemorySanitizer is supported for 64bit systems only.")
46+
set(SANITIZE_MEMORY Off CACHE BOOL
47+
"Enable MemorySanitizer for sanitized targets." FORCE)
48+
else ()
49+
sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "MemorySanitizer"
50+
"MSan")
51+
endif ()
52+
endif ()
53+
54+
function (add_sanitize_memory TARGET)
55+
if (NOT SANITIZE_MEMORY)
56+
return()
57+
endif ()
58+
59+
sanitizer_add_flags(${TARGET} "MemorySanitizer" "MSan")
60+
endfunction ()
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c)
4+
# 2013 Matthew Arsenault
5+
# 2015-2016 RWTH Aachen University, Federal Republic of Germany
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
25+
cmake_minimum_required(VERSION 3.13) # target_link_options()
26+
27+
# If any of the used compiler is a GNU compiler, add a second option to static
28+
# link against the sanitizers.
29+
option(SANITIZE_LINK_STATIC "Try to link static against sanitizers." Off)
30+
31+
# Highlight this module has been loaded.
32+
set(Sanitizers_FOUND TRUE)
33+
34+
set(FIND_QUIETLY_FLAG "")
35+
if (DEFINED Sanitizers_FIND_QUIETLY)
36+
set(FIND_QUIETLY_FLAG "QUIET")
37+
endif ()
38+
39+
find_package(ASan ${FIND_QUIETLY_FLAG})
40+
find_package(TSan ${FIND_QUIETLY_FLAG})
41+
find_package(MSan ${FIND_QUIETLY_FLAG})
42+
find_package(UBSan ${FIND_QUIETLY_FLAG})
43+
44+
function(sanitizer_add_blacklist_file FILE)
45+
if(NOT IS_ABSOLUTE ${FILE})
46+
set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}")
47+
endif()
48+
get_filename_component(FILE "${FILE}" REALPATH)
49+
50+
sanitizer_check_compiler_flags("-fsanitize-blacklist=${FILE}"
51+
"SanitizerBlacklist" "SanBlist")
52+
endfunction()
53+
54+
function(add_sanitizers)
55+
# If no sanitizer is enabled, return immediately.
56+
if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR
57+
SANITIZE_UNDEFINED))
58+
return()
59+
endif ()
60+
61+
foreach (TARGET ${ARGV})
62+
# Check if this target will be compiled by exactly one compiler. Other-
63+
# wise sanitizers can't be used and a warning should be printed once.
64+
get_target_property(TARGET_TYPE ${TARGET} TYPE)
65+
if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
66+
message(WARNING "Can't use any sanitizers for target ${TARGET}, "
67+
"because it is an interface library and cannot be "
68+
"compiled directly.")
69+
return()
70+
endif ()
71+
sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
72+
list(LENGTH TARGET_COMPILER NUM_COMPILERS)
73+
if (NUM_COMPILERS GREATER 1)
74+
message(WARNING "Can't use any sanitizers for target ${TARGET}, "
75+
"because it will be compiled by incompatible compilers. "
76+
"Target will be compiled without sanitizers.")
77+
return()
78+
79+
elseif (NUM_COMPILERS EQUAL 0)
80+
# If the target is compiled by no known compiler, give a warning.
81+
message(WARNING "Sanitizers for target ${TARGET} may not be"
82+
" usable, because it uses no or an unknown compiler. "
83+
"This is a false warning for targets using only "
84+
"object lib(s) as input.")
85+
endif ()
86+
87+
# Add sanitizers for target.
88+
add_sanitize_address(${TARGET})
89+
add_sanitize_thread(${TARGET})
90+
add_sanitize_memory(${TARGET})
91+
add_sanitize_undefined(${TARGET})
92+
endforeach ()
93+
endfunction(add_sanitizers)

0 commit comments

Comments
 (0)