ci: add MemorySanitizer CI job
CI / release (arm64, ubuntu-latest-arm64) (push) Successful in 2m19s
CI / pre-commit (push) Failing after 1s
CI / test (-DCMAKE_BUILD_TYPE=Debug, debug) (push) Failing after 0s
CI / test (-DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 64-bit-versions) (push) Failing after 0s
CI / test (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc) (push) Failing after 0s
CI / test (-DUSE_SIMD_FALLBACK=ON, simd-fallback) (push) Failing after 0s
CI / release (amd64, ubuntu-latest-amd64) (push) Failing after 0s
CI / msan (push) Failing after 1s
CI / coverage (push) Failing after 0s
CI / release (arm64, ubuntu-latest-arm64) (push) Successful in 2m19s
CI / pre-commit (push) Failing after 1s
CI / test (-DCMAKE_BUILD_TYPE=Debug, debug) (push) Failing after 0s
CI / test (-DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 64-bit-versions) (push) Failing after 0s
CI / test (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc) (push) Failing after 0s
CI / test (-DUSE_SIMD_FALLBACK=ON, simd-fallback) (push) Failing after 0s
CI / release (amd64, ubuntu-latest-amd64) (push) Failing after 0s
CI / msan (push) Failing after 1s
CI / coverage (push) Failing after 0s
Add build_msan_toolchain.sh to produce a tarball containing an MSan-instrumented libc++/libc++abi/libunwind toolchain, and add an msan CI job that downloads the tarball and runs the test suite under MSan. Also add USE_MSAN CMake option that disables conflicting sanitizers, switches to lld, and propagates -fsanitize=memory to the shared library and fuzz_driver targets.
This commit is contained in:
@@ -218,6 +218,87 @@ jobs:
|
|||||||
--link "https://minio.weaselab.dev/jenkins/conflict-set/${{ gitea.run_number }}/release-${{ matrix.arch }}/Test.xml.zst" \
|
--link "https://minio.weaselab.dev/jenkins/conflict-set/${{ gitea.run_number }}/release-${{ matrix.arch }}/Test.xml.zst" \
|
||||||
| tee -a "$GITHUB_STEP_SUMMARY"
|
| tee -a "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
msan:
|
||||||
|
runs-on: ubuntu-latest-amd64
|
||||||
|
env:
|
||||||
|
MSAN_VERSION: "21.1.8"
|
||||||
|
MSAN_URL: "https://minio.weaselab.dev/public/x86_64/msan-toolchain-21.1.8.tar.zst"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: /var/cache/apt/archives
|
||||||
|
key: apt-amd64-${{ hashFiles('.gitea/workflows/ci.yml') }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
. /etc/os-release
|
||||||
|
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
|
||||||
|
echo "deb http://apt.llvm.org/${VERSION_CODENAME}/ llvm-toolchain-${VERSION_CODENAME}-21 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential ccache clang-21 cmake libc6-dbg \
|
||||||
|
llvm-21 lld-21 mold ninja-build python3 zstd
|
||||||
|
for tool in clang clang++ llvm-ar llvm-nm llvm-ranlib llvm-objcopy llvm-cov llvm-symbolizer lld ld.lld; do
|
||||||
|
sudo update-alternatives --install /usr/bin/${tool} ${tool} /usr/bin/${tool}-21 100
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Download MSan toolchain
|
||||||
|
run: |
|
||||||
|
curl -Ls "${MSAN_URL}" -o /tmp/msan-toolchain.tar.zst
|
||||||
|
sudo mkdir -p /opt/msan
|
||||||
|
sudo tar --zstd -xf /tmp/msan-toolchain.tar.zst -C /opt/msan
|
||||||
|
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: .ccache
|
||||||
|
key: ccache-msan-${{ gitea.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
ccache-msan-
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
export CCACHE_DIR="$GITHUB_WORKSPACE/.ccache"
|
||||||
|
rm -rf build
|
||||||
|
cmake -S . -B build -G Ninja \
|
||||||
|
-DCMAKE_C_COMPILER=clang \
|
||||||
|
-DCMAKE_CXX_COMPILER=clang++ \
|
||||||
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DDISABLE_TSAN=ON \
|
||||||
|
-DUSE_MSAN=ON \
|
||||||
|
-DCMAKE_CXX_FLAGS="-fsanitize=memory -stdlib=libc++ -I/opt/msan/include/c++/v1 -L/opt/msan/lib -UNDEBUG" \
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ -Wl,-rpath,/opt/msan/lib" \
|
||||||
|
-DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++ -Wl,-rpath,/opt/msan/lib"
|
||||||
|
ninja -C build
|
||||||
|
ccache -s
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
ctest --no-compress-output --test-output-size-passed 100000 --test-output-size-failed 100000 -T Test -j "$(nproc)" --timeout 300 > /dev/null
|
||||||
|
|
||||||
|
- name: Upload test results to MinIO
|
||||||
|
if: always()
|
||||||
|
env:
|
||||||
|
MINIO_ACCESS_KEY: ${{ secrets.MINIO_ACCESS_KEY }}
|
||||||
|
MC_HOST_minio: https://${{ secrets.MINIO_ACCESS_KEY }}:${{ secrets.MINIO_SECRET_KEY }}@minio.weaselab.dev
|
||||||
|
run: |
|
||||||
|
if [ -z "$MINIO_ACCESS_KEY" ]; then
|
||||||
|
echo "MinIO credentials not configured; skipping upload"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
zstd build/Testing/*/Test.xml
|
||||||
|
mc cp build/Testing/*/Test.xml.zst "minio/jenkins/conflict-set/${{ gitea.run_number }}/msan/"
|
||||||
|
|
||||||
|
- name: Test summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
python3 ctest_summary.py build/Testing/*/Test.xml \
|
||||||
|
--link "https://minio.weaselab.dev/jenkins/conflict-set/${{ gitea.run_number }}/msan/Test.xml.zst" \
|
||||||
|
| tee -a "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
runs-on: ubuntu-latest-amd64
|
runs-on: ubuntu-latest-amd64
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
+31
-3
@@ -49,6 +49,18 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|||||||
${LLVM_OBJCOPY}
|
${LLVM_OBJCOPY}
|
||||||
CACHE FILEPATH "path to objcopy binary" FORCE)
|
CACHE FILEPATH "path to objcopy binary" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
if(USE_MSAN)
|
||||||
|
find_program(LLD_LINKER lld)
|
||||||
|
if(LLD_LINKER)
|
||||||
|
set(CMAKE_LINKER_TYPE
|
||||||
|
"LLD"
|
||||||
|
CACHE STRING "Use LLD linker" FORCE)
|
||||||
|
set(CMAKE_LINKER
|
||||||
|
${LLD_LINKER}
|
||||||
|
CACHE FILEPATH "path to linker binary" FORCE)
|
||||||
|
add_link_options("-fuse-ld=lld")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
@@ -103,6 +115,8 @@ option(USE_SIMD_FALLBACK
|
|||||||
|
|
||||||
option(DISABLE_TSAN "Disable TSAN" OFF)
|
option(DISABLE_TSAN "Disable TSAN" OFF)
|
||||||
|
|
||||||
|
option(USE_MSAN "Build with MemorySanitizer (disables ASan/UBSan)" OFF)
|
||||||
|
|
||||||
# This is encouraged according to
|
# This is encouraged according to
|
||||||
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
|
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
|
||||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/valgrind)
|
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/valgrind)
|
||||||
@@ -232,8 +246,10 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
|
|||||||
target_compile_definitions(conflict_set_main PRIVATE ENABLE_MAIN)
|
target_compile_definitions(conflict_set_main PRIVATE ENABLE_MAIN)
|
||||||
target_link_libraries(conflict_set_main PRIVATE nanobench)
|
target_link_libraries(conflict_set_main PRIVATE nanobench)
|
||||||
|
|
||||||
if(NOT APPLE)
|
if(NOT APPLE AND NOT USE_MSAN)
|
||||||
# libfuzzer target, to generate/manage corpus
|
# libfuzzer target, to generate/manage corpus. MSan requires an instrumented
|
||||||
|
# libfuzzer runtime, which is not shipped with the compiler, so skip this
|
||||||
|
# target when building with MSan.
|
||||||
set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined")
|
set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined")
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
cmake_push_check_state()
|
cmake_push_check_state()
|
||||||
@@ -257,9 +273,14 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
|
|||||||
add_executable(fuzz_driver ConflictSet.cpp FuzzTestDriver.cpp)
|
add_executable(fuzz_driver ConflictSet.cpp FuzzTestDriver.cpp)
|
||||||
target_compile_options(fuzz_driver PRIVATE ${TEST_FLAGS})
|
target_compile_options(fuzz_driver PRIVATE ${TEST_FLAGS})
|
||||||
if(NOT CMAKE_CROSSCOMPILING)
|
if(NOT CMAKE_CROSSCOMPILING)
|
||||||
|
if(USE_MSAN)
|
||||||
|
target_compile_options(fuzz_driver PRIVATE -fsanitize=memory)
|
||||||
|
target_link_options(fuzz_driver PRIVATE -fsanitize=memory)
|
||||||
|
else()
|
||||||
target_compile_options(fuzz_driver PRIVATE -fsanitize=address,undefined)
|
target_compile_options(fuzz_driver PRIVATE -fsanitize=address,undefined)
|
||||||
target_link_options(fuzz_driver PRIVATE -fsanitize=address,undefined)
|
target_link_options(fuzz_driver PRIVATE -fsanitize=address,undefined)
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
target_compile_definitions(fuzz_driver PRIVATE ENABLE_FUZZ)
|
target_compile_definitions(fuzz_driver PRIVATE ENABLE_FUZZ)
|
||||||
target_include_directories(fuzz_driver
|
target_include_directories(fuzz_driver
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
@@ -269,7 +290,9 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# tsan tests
|
# tsan tests
|
||||||
if(NOT CMAKE_CROSSCOMPILING AND NOT DISABLE_TSAN)
|
if(NOT CMAKE_CROSSCOMPILING
|
||||||
|
AND NOT DISABLE_TSAN
|
||||||
|
AND NOT USE_MSAN)
|
||||||
add_executable(tsan_driver ConflictSet.cpp FuzzTestDriver.cpp)
|
add_executable(tsan_driver ConflictSet.cpp FuzzTestDriver.cpp)
|
||||||
target_compile_options(tsan_driver PRIVATE ${TEST_FLAGS} -fsanitize=thread)
|
target_compile_options(tsan_driver PRIVATE ${TEST_FLAGS} -fsanitize=thread)
|
||||||
target_link_options(tsan_driver PRIVATE -fsanitize=thread)
|
target_link_options(tsan_driver PRIVATE -fsanitize=thread)
|
||||||
@@ -491,6 +514,11 @@ target_include_directories(
|
|||||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>)
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>)
|
||||||
|
|
||||||
|
if(USE_MSAN)
|
||||||
|
target_compile_options(${PROJECT_NAME} PUBLIC -fsanitize=memory)
|
||||||
|
target_link_options(${PROJECT_NAME} PUBLIC -fsanitize=memory)
|
||||||
|
endif()
|
||||||
|
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}
|
${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}
|
||||||
SOVERSION ${PROJECT_VERSION_MAJOR})
|
SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||||
|
|||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
LLVM_VERSION="${LLVM_VERSION:-21}"
|
||||||
|
MSAN_PREFIX="${MSAN_PREFIX:-$PWD/msan}"
|
||||||
|
JOBS="${JOBS:-$(nproc)}"
|
||||||
|
|
||||||
|
cd /tmp
|
||||||
|
rm -rf libcxx-msan
|
||||||
|
mkdir libcxx-msan
|
||||||
|
cd libcxx-msan
|
||||||
|
|
||||||
|
git clone --depth=1 "https://github.com/llvm/llvm-project.git" -b "release/${LLVM_VERSION}.x"
|
||||||
|
|
||||||
|
cmake -S llvm-project/runtimes -B build \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_C_COMPILER="clang-${LLVM_VERSION}" \
|
||||||
|
-DCMAKE_CXX_COMPILER="clang++-${LLVM_VERSION}" \
|
||||||
|
-DLLVM_USE_SANITIZER=MemoryWithOrigins \
|
||||||
|
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
|
||||||
|
-DLLVM_TARGETS_TO_BUILD=Native \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="${MSAN_PREFIX}" \
|
||||||
|
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \
|
||||||
|
-DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
|
||||||
|
-DLIBCXX_USE_COMPILER_RT=ON \
|
||||||
|
-DLIBCXXABI_USE_COMPILER_RT=ON \
|
||||||
|
-DLIBUNWIND_USE_COMPILER_RT=ON \
|
||||||
|
-DLIBCXX_INCLUDE_TESTS=OFF \
|
||||||
|
-DLIBCXXABI_INCLUDE_TESTS=OFF \
|
||||||
|
-DLIBUNWIND_INCLUDE_TESTS=OFF \
|
||||||
|
-DLIBCXX_ENABLE_CLANG_TIDY=OFF
|
||||||
|
|
||||||
|
cmake --build build -j"${JOBS}"
|
||||||
|
cmake --install build
|
||||||
|
|
||||||
|
VERSION="$(clang-"${LLVM_VERSION}" --version | head -n1 | sed -E 's/.*clang version ([0-9.]+).*/\1/')"
|
||||||
|
TARBALL="msan-toolchain-${VERSION}.tar.zst"
|
||||||
|
|
||||||
|
tar --zstd -cf "${TARBALL}" -C "${MSAN_PREFIX}" .
|
||||||
|
|
||||||
|
TARBALL_PATH="$(pwd)/${TARBALL}"
|
||||||
|
echo "Created: ${TARBALL_PATH}"
|
||||||
Reference in New Issue
Block a user