Skip to content

Commit 1d628f7

Browse files
authored
Merge pull request #1179 from trws/add-sanitizers
Add sanitizers
2 parents 927be23 + 5ad50b7 commit 1d628f7

25 files changed

+965
-3
lines changed

.typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# do not check testing data
33
[files]
44
extend-exclude = [
5+
"cmake/sanitizers-cmake/*",
56
"config/*",
67
"m4/*",
78
"src/common/libutil/json.hpp",

CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ if("${isSystemDir}" STREQUAL "-1")
3636
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
3737
endif("${isSystemDir}" STREQUAL "-1")
3838

39-
4039
# Setting the include directory for the application to find config.h
4140
include_directories( ${CMAKE_BINARY_DIR} )
4241
# Since we have created a config.h add a global define for it
@@ -46,11 +45,12 @@ add_definitions( "-DPACKAGE_VERSION=\"${FLUX_SCHED_VER}\"" )
4645
# We build a lot of shared libs, build them all with PIC
4746
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
4847

49-
# variable to store paths to add to module path for tests
50-
5148
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
49+
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/sanitizers-cmake/cmake)
5250
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX})
5351

52+
include(FindSanitizers)
53+
5454
# external dependencies
5555
find_package(PkgConfig REQUIRED)
5656
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CMAKE_INSTALL_PREFIX}/lib/pkgconfig")
@@ -147,6 +147,7 @@ function(flux_add_plugin TargetName PluginType)
147147
)
148148
target_link_options(${TargetName} PRIVATE
149149
"LINKER:--version-script=${CMAKE_SOURCE_DIR}/flux-plugin.map" ${LinkerOpts})
150+
add_sanitizers(${TargetName})
150151
target_link_libraries(${TargetName} PRIVATE flux::core)
151152
if (NOT ARG_NOINSTALL)
152153
install(TARGETS ${TargetName}

CMakePresets.json

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"version": 6,
3+
"cmakeMinimumRequired": {
4+
"major": 3,
5+
"minor": 23,
6+
"patch": 0
7+
},
8+
"include": [
9+
"otherThings.json",
10+
"moreThings.json"
11+
],
12+
"configurePresets": [
13+
{
14+
"name": "default",
15+
"displayName": "Default Config",
16+
"description": "Default build using Ninja generator",
17+
"generator": "Ninja",
18+
"binaryDir": "${sourceDir}/build/default",
19+
"cacheVariables": {},
20+
"environment": {},
21+
"vendor": {}
22+
},
23+
{
24+
"name": "asan",
25+
"displayName": "Debug with address sanitizer",
26+
"description": "ASAN build using Ninja generator",
27+
"inherits": "default",
28+
"binaryDir": "${sourceDir}/build/asan",
29+
"cacheVariables": {
30+
"SANITIZE_ADDRESS": "ON"
31+
}
32+
}
33+
],
34+
"buildPresets": [
35+
{
36+
"name": "default",
37+
"configurePreset": "default"
38+
},
39+
{
40+
"name": "asan",
41+
"configurePreset": "asan"
42+
}
43+
],
44+
"testPresets": [
45+
{
46+
"name": "default",
47+
"configurePreset": "default",
48+
"output": {
49+
"outputOnFailure": true
50+
},
51+
"execution": {
52+
"noTestsAction": "error",
53+
"stopOnFailure": true
54+
}
55+
},
56+
{
57+
"name": "Asan",
58+
"configurePreset": "asan",
59+
"output": {
60+
"outputOnFailure": true,
61+
"verbosity": "verbose"
62+
},
63+
"environment": {
64+
"ASAN_OPTIONS": "detect_leaks=0,start_deactivated=true,replace_str=true,verify_asan_link_order=false"
65+
},
66+
"execution": {
67+
"noTestsAction": "error",
68+
"stopOnFailure": true
69+
}
70+
}
71+
],
72+
"packagePresets": [
73+
{
74+
"name": "default",
75+
"configurePreset": "default",
76+
"generators": []
77+
}
78+
],
79+
"workflowPresets": [],
80+
"vendor": {}
81+
}

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 ()

0 commit comments

Comments
 (0)