From 0ad5c85c6cade24f065e3179071b74a13afb14bf Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Sat, 24 Aug 2024 20:55:00 +1000 Subject: [PATCH 1/2] Run the sanitizers in CI --- .github/workflows/sanitisers.yaml | 88 ++++++++++++++++++++++++++++++ cmake/Sanitizers.cmake | 89 +++++++++++++++++++++---------- 2 files changed, 150 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/sanitisers.yaml diff --git a/.github/workflows/sanitisers.yaml b/.github/workflows/sanitisers.yaml new file mode 100644 index 00000000..4326453d --- /dev/null +++ b/.github/workflows/sanitisers.yaml @@ -0,0 +1,88 @@ +# Continuous Integration tests +name: GCC + +on: + push: + branches: [main] + pull_request: + branches: [main] + +# Ensure that only one instance of the workflow is run at a time for each branch/tag. +# Jobs currently running on the branch/tag will be cancelled when new commits are pushed. +# See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency. +concurrency: + # `github.workflow` is the workflow name, `github.ref` is the current branch/tag identifier + group: ${{ format('{0}:{1}', github.workflow, github.ref) }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + linux-gcc: + strategy: + matrix: + sanitiser: + - ADDRESS + - LEAK + - MEMORY + - THREAD + - UNDEFINED + + name: Sanitising ${{ matrix.sanitiser }} + runs-on: ubuntu-latest + continue-on-error: true + + # Use the container for this specific version of gcc + container: ubuntu:22.04 + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + # Update for all the actions that need to install stuff + - run: | + apt-get update + apt-get install -y software-properties-common unzip + + - name: Install GCC + run: | + add-apt-repository ppa:ubuntu-toolchain-r/test + apt-get update + apt-get install -y gcc-13 g++-13 + + - name: Install CMake + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.27.1 + ninjaVersion: 1.11.1 + + - name: Setup CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }}-gcc-${{ matrix.sanitiser }} + max-size: 100M + + - name: Configure CMake + run: | + cmake -E make_directory build + cmake -S . -B build \ + -GNinja \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-13 \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-13 \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DSANITIZE_${{ matrix.sanitiser }}=ON \ + -DBUILD_TESTS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCI_BUILD=ON \ + -DENABLE_CLANG_TIDY=OFF + + - name: Build + timeout-minutes: 30 + run: cmake --build build --config Release + + - name: CCache Stats + run: ccache --show-stats + + - name: Test + timeout-minutes: 5 + working-directory: build/tests + run: ctest --output-on-failure -j$(nproc) -E "dsl/UDP" diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake index 91877a30..0710db22 100644 --- a/cmake/Sanitizers.cmake +++ b/cmake/Sanitizers.cmake @@ -4,33 +4,68 @@ ### User beware: ### ### Not all sanitisers can be enabled at the same time. ### ############################################################################### -option(USE_ASAN "Enable address sanitization" OFF) -if(USE_ASAN) - add_compile_options(-fsanitize=address -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) - add_link_options(-fsanitize=address) - link_libraries(asan) -endif(USE_ASAN) - -option(USE_LSAN "Enable leak sanitization" OFF) -if(USE_LSAN) - add_compile_options(-fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) - add_link_options(-fsanitize=leak) - link_libraries(lsan) -endif(USE_LSAN) - -option(USE_TSAN "Enable thread sanitization" OFF) -if(USE_TSAN) - add_compile_options(-fsanitize=thread -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) - add_link_options(-fsanitize=thread) - link_libraries(tsan) -endif(USE_TSAN) - -option(USE_UBSAN "Enable undefined behaviour sanitization" OFF) -if(USE_UBSAN) - add_compile_options(-fsanitize=undefined -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) - add_link_options(-fsanitize=undefined) - link_libraries(ubsan) -endif(USE_UBSAN) + +option(SANITIZE_ADDRESS "Enable AddressSanitizer." OFF) +option(SANITIZE_LEAK "Enable Leak Sanitizer." OFF) +option(SANITIZE_MEMORY "Enable MemorySanitizer." OFF) +option(SANITIZE_THREAD "Enable ThreadSanitizer." OFF) +option(SANITIZE_UNDEFINED "Enable UndefinedBehaviourSanitizer." OFF) + +if(SANITIZE_ADDRESS AND (SANITIZE_THREAD OR SANITIZE_MEMORY)) + message(FATAL_ERROR "AddressSanitizer is not compatible with " "ThreadSanitizer or MemorySanitizer.") +endif() + +if(SANITIZE_ADDRESS) + if(MSVC) + add_compile_options("/fsanitize=address") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options("-g" "-fsanitize=address" "-fno-omit-frame-pointer") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options("-g" "-fsanitize=address") + else() + message(FATAL_ERROR "Unsupported compiler") + endif() +endif() + +if(SANITIZE_LEAK) + if(MSVC) + add_compile_options("/fsanitize=leak") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options("-g" "-fsanitize=leak") + else() + message(FATAL_ERROR "Unsupported compiler") + endif() +endif() + +if(SANITIZE_MEMORY) + if(MSVC) + add_compile_options("/fsanitize=memory") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options("-g" "-fsanitize=memory") + else() + message(FATAL_ERROR "Unsupported compiler") + endif() +endif() + +if(SANITIZE_THREAD) + if(MSVC) + add_compile_options("/fsanitize=thread") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options("-g" "-fsanitize=thread") + else() + message(FATAL_ERROR "Unsupported compiler") + endif() +endif() + +if(SANITIZE_UNDEFINED) + if(MSVC) + add_compile_options("/fsanitize=undefined") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options("-g" "-fsanitize=undefined") + else() + message(FATAL_ERROR "Unsupported compiler") + endif() +endif() # Option for enabling code profiling. Disabled by default option(ENABLE_PROFILING "Compile with profiling support enabled." OFF) From e42a2dad0ef9a902f55c37456d0ed621dd484137 Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Sun, 25 Aug 2024 11:35:05 +1000 Subject: [PATCH 2/2] . --- .github/workflows/sanitisers.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sanitisers.yaml b/.github/workflows/sanitisers.yaml index 4326453d..f9a4c03e 100644 --- a/.github/workflows/sanitisers.yaml +++ b/.github/workflows/sanitisers.yaml @@ -1,5 +1,5 @@ # Continuous Integration tests -name: GCC +name: Sanitizers on: push: @@ -16,7 +16,7 @@ concurrency: cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} jobs: - linux-gcc: + sanitizers: strategy: matrix: sanitiser: @@ -26,7 +26,7 @@ jobs: - THREAD - UNDEFINED - name: Sanitising ${{ matrix.sanitiser }} + name: Sanitizing ${{ matrix.sanitiser }} runs-on: ubuntu-latest continue-on-error: true