From 18a0b399688eaa5210c92c711ee05030b0468d6a Mon Sep 17 00:00:00 2001 From: Daniel Agar Date: Sun, 23 Sep 2018 16:52:09 -0400 Subject: [PATCH] sanitizers cleanup (#10551) - add to AddressSanitizer and UndefinedBehaviorSanitizer to CMAKE_BUILD_TYPE options - handle environment variable helpers outside of CMake - add -O1 optimization - cleanup whitespace --- .ci/Jenkinsfile-SITL_tests | 18 +--- CMakeLists.txt | 2 +- Makefile | 22 +++++ cmake/common/sanitizers.cmake | 158 +++++++++++++++++----------------- 4 files changed, 104 insertions(+), 96 deletions(-) diff --git a/.ci/Jenkinsfile-SITL_tests b/.ci/Jenkinsfile-SITL_tests index 740ff0f74b..86010a838b 100644 --- a/.ci/Jenkinsfile-SITL_tests +++ b/.ci/Jenkinsfile-SITL_tests @@ -6,27 +6,13 @@ pipeline { parameters { choice( name: 'PX4_CMAKE_BUILD_TYPE', - choices: ['RelWithDebInfo', 'Coverage', 'AddressSanitizer'], + choices: ['RelWithDebInfo', 'Coverage', 'AddressSanitizer', 'UndefinedBehaviorSanitizer'], description: "CMake build type" ) } stages { - stage('Setup Environment') { - steps { - script { - - env.CTEST_OUTPUT_ON_FAILURE=1 - - if (env.PX4_CMAKE_BUILD_TYPE == 'AddressSanitizer') { - env.PX4_ASAN=1 - env.ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1" - } - } - } - } - stage('Build') { agent { @@ -206,8 +192,10 @@ pipeline { } //stages environment { + ASAN_OPTIONS = 'detect_stack_use_after_return=1:check_initialization_order=1' CCACHE_DIR = '/tmp/ccache' CI = true + CTEST_OUTPUT_ON_FAILURE = 1 } options { buildDiscarder(logRotator(numToKeepStr: '10', artifactDaysToKeepStr: '30')) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7d70d7826..f7446955e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,7 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${PX4_BUILD_TYPE} CACHE STRING "Build type" FORCE) endif() -set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel;Coverage") +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel;Coverage;AddressSanitizer;UndefinedBehaviorSanitizer") #============================================================================= diff --git a/Makefile b/Makefile index 7384676034..202492bad1 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,28 @@ endif ifdef PX4_CMAKE_BUILD_TYPE CMAKE_ARGS += -DCMAKE_BUILD_TYPE=${PX4_CMAKE_BUILD_TYPE} +else + + # Address Sanitizer + ifdef PX4_ASAN + CMAKE_ARGS += -DCMAKE_BUILD_TYPE=AddressSanitizer + endif + + # Memory Sanitizer + ifdef PX4_MSAN + CMAKE_ARGS += -DCMAKE_BUILD_TYPE=MemorySanitizer + endif + + # Thread Sanitizer + ifdef PX4_TSAN + CMAKE_ARGS += -DCMAKE_BUILD_TYPE=ThreadSanitizer + endif + + # Undefined Behavior Sanitizer + ifdef PX4_UBSAN + CMAKE_ARGS += -DCMAKE_BUILD_TYPE=UndefinedBehaviorSanitizer + endif + endif # Functions diff --git a/cmake/common/sanitizers.cmake b/cmake/common/sanitizers.cmake index fd2ad4d938..01705b91c9 100644 --- a/cmake/common/sanitizers.cmake +++ b/cmake/common/sanitizers.cmake @@ -31,110 +31,108 @@ # ############################################################################ -option(SANITIZE_ADDRESS "Enable AddressSanitizer" Off) -option(SANITIZE_MEMORY "Enable MemorySanitizer" Off) -option(SANITIZE_THREAD "Enable ThreadSanitizer" Off) -option(SANITIZE_UNDEFINED "Enable UndefinedBehaviorSanitizer" Off) +if (CMAKE_BUILD_TYPE STREQUAL AddressSanitizer) + message(STATUS "AddressSanitizer enabled") -if(DEFINED ENV{PX4_ASAN}) - set(SANITIZE_ADDRESS ON) -elseif(DEFINED ENV{PX4_MSAN}) - set(SANITIZE_MEMORY ON) -elseif(DEFINED ENV{PX4_TSAN}) - set(SANITIZE_THREAD ON) -elseif(DEFINED ENV{PX4_UBSAN}) - set(SANITIZE_UNDEFINED ON) -endif() + # environment variables + # ASAN_OPTIONS=check_initialization_order=1,detect_stack_use_after_return=1 + add_compile_options( + -O1 + -g3 -if (SANITIZE_ADDRESS) - message(STATUS "AddressSanitizer enabled") + -fsanitize=address - # environment variables - # ASAN_OPTIONS=detect_stack_use_after_return=1 - # ASAN_OPTIONS=check_initialization_order=1 - add_compile_options( - -g3 - -fno-omit-frame-pointer - -fsanitize=address - #-fsanitize-address-use-after-scope - -fno-optimize-sibling-calls - ) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" CACHE INTERNAL "" FORCE) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address" CACHE INTERNAL "" FORCE) - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address" CACHE INTERNAL "" FORCE) + -fno-omit-frame-pointer # Leave frame pointers. Allows the fast unwinder to function properly. + -fno-common # Do not treat global variable in C as common variables (allows ASan to instrument them) + -fno-optimize-sibling-calls # disable inlining and and tail call elimination for perfect stack traces + ) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" CACHE INTERNAL "" FORCE) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address" CACHE INTERNAL "" FORCE) + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address" CACHE INTERNAL "" FORCE) function(sanitizer_fail_test_on_error test_name) - set_tests_properties(${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR: AddressSanitizer") - set_tests_properties(${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR: LeakSanitizer") - endfunction(sanitizer_fail_test_on_error) + set_tests_properties(${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR: AddressSanitizer") + set_tests_properties(${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR: LeakSanitizer") + endfunction(sanitizer_fail_test_on_error) -elseif(SANITIZE_MEMORY) - message(STATUS "MemorySanitizer enabled") +elseif (CMAKE_BUILD_TYPE STREQUAL MemorySanitizer) + message(STATUS "MemorySanitizer enabled") - add_compile_options( - -g3 - -fsanitize=memory - ) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory" CACHE INTERNAL "" FORCE) + add_compile_options( + -O1 + -g3 - function(sanitizer_fail_test_on_error test_name) - # TODO add right check here - endfunction(sanitizer_fail_test_on_error) + -fsanitize=memory + -fsanitize-memory-track-origins -elseif(SANITIZE_THREAD) - message(STATUS "ThreadSanitizer enabled") + -fno-omit-frame-pointer # Leave frame pointers. Allows the fast unwinder to function properly. + -fno-common # Do not treat global variable in C as common variables (allows ASan to instrument them) + -fno-optimize-sibling-calls # disable inlining and and tail call elimination for perfect stack traces + ) + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory" CACHE INTERNAL "" FORCE) + + function(sanitizer_fail_test_on_error test_name) + # TODO add right check here + endfunction(sanitizer_fail_test_on_error) + +elseif (CMAKE_BUILD_TYPE STREQUAL ThreadSanitizer) + message(STATUS "ThreadSanitizer enabled") + + add_compile_options( + -g3 + -fsanitize=thread + ) - add_compile_options( - -g3 - -fsanitize=thread - ) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread" CACHE INTERNAL "" FORCE) - function(sanitizer_fail_test_on_error test_name) - # TODO add right check here - endfunction(sanitizer_fail_test_on_error) + function(sanitizer_fail_test_on_error test_name) + # TODO add right check here + endfunction(sanitizer_fail_test_on_error) -elseif(SANITIZE_UNDEFINED) - message(STATUS "UndefinedBehaviorSanitizer enabled") +elseif (CMAKE_BUILD_TYPE STREQUAL UndefinedBehaviorSanitizer) + message(STATUS "UndefinedBehaviorSanitizer enabled") - add_compile_options( - -g3 - #-fsanitize=alignment - -fsanitize=bool + add_compile_options( + -g3 + + #-fsanitize=alignment + -fsanitize=bool #-fsanitize=builtin - -fsanitize=bounds - -fsanitize=enum - -fsanitize=float-cast-overflow - -fsanitize=float-divide-by-zero - #-fsanitize=function - -fsanitize=integer-divide-by-zero - -fsanitize=nonnull-attribute - -fsanitize=null + -fsanitize=bounds + -fsanitize=enum + -fsanitize=float-cast-overflow + -fsanitize=float-divide-by-zero + #-fsanitize=function + -fsanitize=integer-divide-by-zero + -fsanitize=nonnull-attribute + -fsanitize=null #-fsanitize=nullability-arg #-fsanitize=nullability-assign #-fsanitize=nullability-return - -fsanitize=object-size + -fsanitize=object-size #-fsanitize=pointer-overflow - -fsanitize=return - -fsanitize=returns-nonnull-attribute - -fsanitize=shift - -fsanitize=signed-integer-overflow - -fsanitize=unreachable - #-fsanitize=unsigned-integer-overflow - -fsanitize=vla-bound - -fsanitize=vptr + -fsanitize=return + -fsanitize=returns-nonnull-attribute + -fsanitize=shift + -fsanitize=signed-integer-overflow + -fsanitize=unreachable + #-fsanitize=unsigned-integer-overflow + -fsanitize=vla-bound + -fsanitize=vptr -fno-sanitize-recover=bounds,null - ) + ) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined" CACHE INTERNAL "" FORCE) - function(sanitizer_fail_test_on_error test_name) - # TODO add right check here - endfunction(sanitizer_fail_test_on_error) + function(sanitizer_fail_test_on_error test_name) + # TODO add right check here + endfunction(sanitizer_fail_test_on_error) else() - function(sanitizer_fail_test_on_error test_name) - # default: don't do anything - endfunction(sanitizer_fail_test_on_error) + function(sanitizer_fail_test_on_error test_name) + # default: don't do anything + endfunction(sanitizer_fail_test_on_error) endif()