diff options
Diffstat (limited to 'src/arrow/cpp/cmake_modules/san-config.cmake')
-rw-r--r-- | src/arrow/cpp/cmake_modules/san-config.cmake | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/arrow/cpp/cmake_modules/san-config.cmake b/src/arrow/cpp/cmake_modules/san-config.cmake new file mode 100644 index 000000000..bde9af23e --- /dev/null +++ b/src/arrow/cpp/cmake_modules/san-config.cmake @@ -0,0 +1,122 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. See accompanying LICENSE file. + +# Clang does not support using ASAN and TSAN simultaneously. +if("${ARROW_USE_ASAN}" AND "${ARROW_USE_TSAN}") + message(SEND_ERROR "Can only enable one of ASAN or TSAN at a time") +endif() + +# Flag to enable clang address sanitizer +# This will only build if clang or a recent enough gcc is the chosen compiler +if(${ARROW_USE_ASAN}) + if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION + VERSION_GREATER "4.8")) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -DADDRESS_SANITIZER") + else() + message(SEND_ERROR "Cannot use ASAN without clang or gcc >= 4.8") + endif() +endif() + +# Flag to enable clang undefined behavior sanitizer +# We explicitly don't enable all of the sanitizer flags: +# - disable 'vptr' because of RTTI issues across shared libraries (?) +# - disable 'alignment' because unaligned access is really OK on Nehalem and we do it +# all over the place. +# - disable 'function' because it appears to give a false positive +# (https://github.com/google/sanitizers/issues/911) +# - disable 'float-divide-by-zero' on clang, which considers it UB +# (https://bugs.llvm.org/show_bug.cgi?id=17000#c1) +# Note: GCC does not support the 'function' flag. +if(${ARROW_USE_UBSAN}) + if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL + "Clang") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize=alignment,vptr,function,float-divide-by-zero -fno-sanitize-recover=all" + ) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION + VERSION_GREATER_EQUAL "5.1") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize=alignment,vptr -fno-sanitize-recover=all" + ) + else() + message(SEND_ERROR "Cannot use UBSAN without clang or gcc >= 5.1") + endif() +endif() + +# Flag to enable thread sanitizer (clang or gcc 4.8) +if(${ARROW_USE_TSAN}) + if(NOT + (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION + VERSION_GREATER "4.8"))) + message(SEND_ERROR "Cannot use TSAN without clang or gcc >= 4.8") + endif() + + add_definitions("-fsanitize=thread") + + # Enables dynamic_annotations.h to actually generate code + add_definitions("-DDYNAMIC_ANNOTATIONS_ENABLED") + + # changes atomicops to use the tsan implementations + add_definitions("-DTHREAD_SANITIZER") + + # Disables using the precompiled template specializations for std::string, shared_ptr, etc + # so that the annotations in the header actually take effect. + add_definitions("-D_GLIBCXX_EXTERN_TEMPLATE=0") + + # Some of the above also need to be passed to the linker. + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fsanitize=thread") + + # Strictly speaking, TSAN doesn't require dynamic linking. But it does + # require all code to be position independent, and the easiest way to + # guarantee that is via dynamic linking (not all 3rd party archives are + # compiled with -fPIC e.g. boost). + if("${ARROW_LINK}" STREQUAL "a") + message("Using dynamic linking for TSAN") + set(ARROW_LINK "d") + elseif("${ARROW_LINK}" STREQUAL "s") + message(SEND_ERROR "Cannot use TSAN with static linking") + endif() +endif() + +if(${ARROW_USE_COVERAGE}) + if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL + "Clang") + add_definitions("-fsanitize-coverage=pc-table,inline-8bit-counters,edge,no-prune,trace-cmp,trace-div,trace-gep" + ) + + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize-coverage=pc-table,inline-8bit-counters,edge,no-prune,trace-cmp,trace-div,trace-gep" + ) + else() + message(SEND_ERROR "You can only enable coverage with clang") + endif() +endif() + +if("${ARROW_USE_UBSAN}" + OR "${ARROW_USE_ASAN}" + OR "${ARROW_USE_TSAN}") + # GCC 4.8 and 4.9 (latest as of this writing) don't allow you to specify + # disallowed entries for the sanitizer. + if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL + "Clang") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize-blacklist=${BUILD_SUPPORT_DIR}/sanitizer-disallowed-entries.txt" + ) + else() + message(WARNING "GCC does not support specifying a sanitizer disallowed entries list. Known sanitizer check failures will not be suppressed." + ) + endif() +endif() |