Skip to content

Commit

Permalink
Add Sanitizer option to CMake build
Browse files Browse the repository at this point in the history
  • Loading branch information
hcho3 committed Nov 11, 2020
1 parent 2ad21ab commit 5ca3f20
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 0 deletions.
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ OPTION(USE_HDFS "Enable HDFS support (EXPERIMENTAL)" OFF)
OPTION(USE_TIMETAG "Set to ON to output time costs" OFF)
OPTION(USE_CUDA "Enable CUDA-accelerated training (EXPERIMENTAL)" OFF)
OPTION(USE_DEBUG "Set to ON for Debug mode" OFF)
OPTION(USE_SANITIZER "Use santizer flags" OFF)
option(SANITIZER_PATH "Path to sanitizer libs")
set(ENABLED_SANITIZERS "address" "leak" "undefined" CACHE STRING
"Semicolon separated list of sanitizer names. E.g 'address;leak'. Supported sanitizers are
address, leak, undefined and thread.")
OPTION(BUILD_STATIC_LIB "Build static library" OFF)
OPTION(__BUILD_FOR_R "Set to ON if building lib_lightgbm for use with the R package" OFF)
OPTION(__INTEGRATE_OPENCL "Set to ON if building LightGBM with the OpenCL ICD Loader and its dependencies included" OFF)
Expand Down Expand Up @@ -37,6 +42,14 @@ else()
PROJECT(lightgbm LANGUAGES C CXX)
endif()

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")

#-- Sanitizer
if (USE_SANITIZER)
include(cmake/Sanitizer.cmake)
enable_sanitizers("${ENABLED_SANITIZERS}")
endif (USE_SANITIZER)

if(__INTEGRATE_OPENCL)
set(__INTEGRATE_OPENCL ON CACHE BOOL "" FORCE)
set(USE_GPU OFF CACHE BOOL "" FORCE)
Expand Down
69 changes: 69 additions & 0 deletions cmake/Sanitizer.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Set appropriate compiler and linker flags for sanitizers.
#
# Usage of this module:
# enable_sanitizers("address;leak")

# Add flags
macro(enable_sanitizer sanitizer)
if(${sanitizer} MATCHES "address")
find_package(ASan)
set(SAN_COMPILE_FLAGS "${SAN_COMPILE_FLAGS} -fsanitize=address")
if (ASan_FOUND)
link_libraries(${ASan_LIBRARY})
endif (ASan_FOUND)

elseif(${sanitizer} MATCHES "thread")
find_package(TSan)
set(SAN_COMPILE_FLAGS "${SAN_COMPILE_FLAGS} -fsanitize=thread")
if (TSan_FOUND)
link_libraries(${TSan_LIBRARY})
endif (TSan_FOUND)

elseif(${sanitizer} MATCHES "leak")
find_package(LSan)
set(SAN_COMPILE_FLAGS "${SAN_COMPILE_FLAGS} -fsanitize=leak")
if (LSan_FOUND)
link_libraries(${LSan_LIBRARY})
endif (LSan_FOUND)

elseif(${sanitizer} MATCHES "undefined")
find_package(UBSan)
set(SAN_COMPILE_FLAGS "${SAN_COMPILE_FLAGS} -fsanitize=undefined -fno-sanitize-recover=undefined")
if (UBSan_FOUND)
link_libraries(${UBSan_LIBRARY})
endif (UBSan_FOUND)

else()
message(FATAL_ERROR "Santizer ${sanitizer} not supported.")
endif()
endmacro()

macro(enable_sanitizers SANITIZERS)
# Check sanitizers compatibility.
foreach ( _san ${SANITIZERS} )
string(TOLOWER ${_san} _san)
if (_san MATCHES "thread")
if (${_use_other_sanitizers})
message(FATAL_ERROR
"thread sanitizer is not compatible with ${_san} sanitizer.")
endif()
set(_use_thread_sanitizer 1)
else ()
if (${_use_thread_sanitizer})
message(FATAL_ERROR
"${_san} sanitizer is not compatible with thread sanitizer.")
endif()
set(_use_other_sanitizers 1)
endif()
endforeach()

message("Sanitizers: ${SANITIZERS}")

foreach( _san ${SANITIZERS} )
string(TOLOWER ${_san} _san)
enable_sanitizer(${_san})
endforeach()
message("Sanitizers compile flags: ${SAN_COMPILE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_COMPILE_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_COMPILE_FLAGS}")
endmacro()
13 changes: 13 additions & 0 deletions cmake/modules/FindASan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(ASan_LIB_NAME ASan)

find_library(ASan_LIBRARY
NAMES libasan.so libasan.so.5 libasan.so.4 libasan.so.3 libasan.so.2 libasan.so.1 libasan.so.0
PATHS ${SANITIZER_PATH} /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib ${CMAKE_PREFIX_PATH}/lib)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ASan DEFAULT_MSG
ASan_LIBRARY)

mark_as_advanced(
ASan_LIBRARY
ASan_LIB_NAME)
13 changes: 13 additions & 0 deletions cmake/modules/FindLSan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(LSan_LIB_NAME lsan)

find_library(LSan_LIBRARY
NAMES liblsan.so liblsan.so.0 liblsan.so.0.0.0
PATHS ${SANITIZER_PATH} /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib ${CMAKE_PREFIX_PATH}/lib)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LSan DEFAULT_MSG
LSan_LIBRARY)

mark_as_advanced(
LSan_LIBRARY
LSan_LIB_NAME)
13 changes: 13 additions & 0 deletions cmake/modules/FindTSan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(TSan_LIB_NAME tsan)

find_library(TSan_LIBRARY
NAMES libtsan.so libtsan.so.0 libtsan.so.0.0.0
PATHS ${SANITIZER_PATH} /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib ${CMAKE_PREFIX_PATH}/lib)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TSan DEFAULT_MSG
TSan_LIBRARY)

mark_as_advanced(
TSan_LIBRARY
TSan_LIB_NAME)
13 changes: 13 additions & 0 deletions cmake/modules/FindUBSan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
set(UBSan_LIB_NAME UBSan)

find_library(UBSan_LIBRARY
NAMES libubsan.so libubsan.so.5 libubsan.so.4 libubsan.so.3 libubsan.so.2 libubsan.so.1 libubsan.so.0
PATHS ${SANITIZER_PATH} /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib ${CMAKE_PREFIX_PATH}/lib)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(UBSan DEFAULT_MSG
UBSan_LIBRARY)

mark_as_advanced(
UBSan_LIBRARY
UBSan_LIB_NAME)

0 comments on commit 5ca3f20

Please sign in to comment.