-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: enable msan [memory sanitizer] on CI #7643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8983e98
f05d458
15e829b
7d95295
573bd4f
6210fb8
b906c20
8be042b
f3e8c26
cf0e58f
b67d12a
df22d6a
591ddae
dae4fc2
bf2cae3
c7155fc
1c59091
5fdd260
6eace52
cb458b0
ae15342
f3297af
6727036
f07388c
475f809
96abb12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Copyright (c) 2020-present The Bitcoin Core developers | ||
| # Distributed under the MIT software license, see the accompanying | ||
| # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
|
||
| export LC_ALL=C.UTF-8 | ||
|
|
||
| export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04" | ||
| LIBCXX_DIR="/msan/cxx_build/" | ||
| export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" | ||
| LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" | ||
| export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" | ||
|
|
||
| export CONTAINER_NAME="ci_native_fuzz_msan" | ||
| export PACKAGES="ninja-build" | ||
| # BDB generates false-positives and will be removed in future | ||
| export DEP_OPTS="DEBUG=1 NO_BDB=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" | ||
| export GOAL="install" | ||
| # _FORTIFY_SOURCE is not compatible with MSAN. | ||
| export BITCOIN_CONFIG="--enable-fuzz --with-sanitizers=fuzzer,memory CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE -U_FORTIFY_SOURCE'" | ||
| export USE_MEMORY_SANITIZER="true" | ||
| export RUN_UNIT_TESTS="false" | ||
| export RUN_FUNCTIONAL_TESTS="false" | ||
| export RUN_FUZZ_TESTS=true | ||
| export CCACHE_MAXSIZE=250M |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Copyright (c) 2020-present The Bitcoin Core developers | ||
| # Distributed under the MIT software license, see the accompanying | ||
| # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
|
||
| export LC_ALL=C.UTF-8 | ||
|
|
||
| export CONTAINER_NAME="ci_native_msan" | ||
| export HOST=x86_64-pc-linux-gnu | ||
| # Built into the CI image by contrib/containers/ci/ci-msan.Dockerfile so that it | ||
| # lands in a cached layer instead of being rebuilt on every run. Upstream does | ||
| # the equivalent in ci/test/01_base_install.sh, which Dash does not have. | ||
| LIBCXX_DIR="/cxx_build/" | ||
| export MSAN_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls" | ||
| LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" | ||
| export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" | ||
|
|
||
| # BDB generates false-positives and will be removed in future | ||
| export DEP_OPTS="DEBUG=1 NO_BDB=1 NO_QT=1 NO_UPNP=1 NO_NATPMP=1 CC=clang-19 CXX=clang++-19 CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" | ||
| export GOAL="install" | ||
| # CC/CXX/CFLAGS/CXXFLAGS are repeated here rather than left to depends' | ||
| # config.site. Upstream dropped them in bitcoin#29800 because its | ||
| # ci/test/03_test_script.sh sets CONFIG_SITE explicitly (bitcoin#26683); | ||
| # ci/dash/build_src.sh still uses the older --prefix form, and this is the only | ||
| # target whose compiler differs from the system default, so nothing else in | ||
| # Dash's CI exercises that hand-off. | ||
| # _FORTIFY_SOURCE is not compatible with MSAN. | ||
| # --with-asm=no and --with-backend=easy keep secp256k1 and relic off | ||
| # hand-written assembly, which MSan cannot see through. | ||
| # --disable-mimalloc selects the plain malloc secure allocator; mimalloc seeds | ||
| # itself with a raw getrandom syscall before main(), which MSan cannot track. | ||
| export BITCOIN_CONFIG="--with-sanitizers=memory --with-gui=no --without-bdb --with-sqlite \ | ||
| --with-asm=no --with-backend=easy --disable-mimalloc \ | ||
| CC=clang-19 CXX=clang++-19 CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}' \ | ||
| CPPFLAGS='-U_FORTIFY_SOURCE'" | ||
| export USE_MEMORY_SANITIZER="true" | ||
| export TEST_RUNNER_TIMEOUT_FACTOR=40 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,10 +10,6 @@ if [[ $QEMU_USER_CMD == qemu-s390* ]]; then | |
| export LC_ALL=C | ||
| fi | ||
|
|
||
| # Create folders that are mounted into the docker | ||
| mkdir -p "${CCACHE_DIR}" | ||
| mkdir -p "${PREVIOUS_RELEASES_DIR}" | ||
|
|
||
| export ASAN_OPTIONS="detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1" | ||
| export LSAN_OPTIONS="suppressions=${BASE_BUILD_DIR}/test/sanitizer_suppressions/lsan:print_suppressions=0" | ||
| export TSAN_OPTIONS="suppressions=${BASE_BUILD_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1" | ||
|
|
@@ -37,7 +33,7 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then | |
|
|
||
| # shellcheck disable=SC2086 | ||
| DOCKER_ID=$(docker run $DOCKER_ADMIN -idt \ | ||
| --mount type=bind,src=$BASE_ROOT_DIR,dst=/ro_base,readonly \ | ||
| --mount type=bind,src=$BASE_READ_ONLY_DIR,dst=/ro_base,readonly \ | ||
| --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR \ | ||
| --mount type=bind,src=$DEPENDS_DIR,dst=$DEPENDS_DIR \ | ||
| --mount type=bind,src=$PREVIOUS_RELEASES_DIR,dst=$PREVIOUS_RELEASES_DIR \ | ||
|
|
@@ -60,6 +56,9 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then | |
| $DOCKER_CI_CMD_PREFIX_ROOT git config --global --add safe.directory "*" | ||
| else | ||
| echo "Running on host system without docker wrapper" | ||
| echo "Create missing folders" | ||
| mkdir -p "${CCACHE_DIR}" | ||
| mkdir -p "${PREVIOUS_RELEASES_DIR}" | ||
| fi | ||
|
|
||
| CI_EXEC () { | ||
|
|
@@ -130,6 +129,15 @@ fi | |
|
|
||
| CI_EXEC mkdir -p "${BASE_SCRATCH_DIR}/sanitizer-output/" | ||
|
|
||
| if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then | ||
| CI_EXEC_ROOT "update-alternatives --install /usr/bin/clang++ clang++ \$(which clang++-12) 100" | ||
| CI_EXEC_ROOT "update-alternatives --install /usr/bin/clang clang \$(which clang-12) 100" | ||
| DOCKER_EXEC "mkdir -p ${BASE_SCRATCH_DIR}/msan/build/" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When either new MSan environment file is run through Useful? React with 👍 / 👎. |
||
| DOCKER_EXEC "git clone --depth=1 https://github.com/llvm/llvm-project -b llvmorg-12.0.0 ${BASE_SCRATCH_DIR}/msan/llvm-project" | ||
| DOCKER_EXEC "cd ${BASE_SCRATCH_DIR}/msan/build/ && cmake -DLLVM_ENABLE_PROJECTS='libcxx;libcxxabi' -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=MemoryWithOrigins -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_TARGETS_TO_BUILD=X86 ../llvm-project/llvm/" | ||
| DOCKER_EXEC "cd ${BASE_SCRATCH_DIR}/msan/build/ && make $MAKEJOBS cxx" | ||
| fi | ||
|
|
||
| if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then | ||
| echo "Create $BASE_ROOT_DIR" | ||
| CI_EXEC rsync -a /ro_base/ "$BASE_ROOT_DIR" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # syntax = devthefuture/dockerfile-x | ||
|
|
||
| FROM ./ci.Dockerfile | ||
|
|
||
| # MemorySanitizer reports any read of memory it did not watch being written, | ||
| # so the C++ standard library has to be instrumented too. A stock libstdc++ or | ||
| # libc++ produces a flood of reports that cannot be told apart from real ones. | ||
| # | ||
| # Upstream builds this in ci/test/01_base_install.sh, which runs inside its | ||
| # docker build. Dash has no such script, so it lives here instead, which keeps | ||
| # the result in a cached image layer rather than rebuilding it on every run. | ||
|
|
||
| USER root | ||
|
|
||
| ARG LLVM_VERSION=19 | ||
| ARG LLVM_TAG=llvmorg-19.1.7 | ||
|
|
||
| RUN set -ex; \ | ||
| apt-get update && apt-get install ${APT_ARGS} ninja-build; \ | ||
| rm -rf /var/lib/apt/lists/*; \ | ||
| git clone --depth=1 -b "${LLVM_TAG}" https://github.com/llvm/llvm-project /llvm-project; \ | ||
| cmake -G Ninja -B /cxx_build/ \ | ||
| -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ | ||
| -DCMAKE_BUILD_TYPE=Release \ | ||
| -DLLVM_USE_SANITIZER=MemoryWithOrigins \ | ||
| -DCMAKE_C_COMPILER=clang-${LLVM_VERSION} \ | ||
| -DCMAKE_CXX_COMPILER=clang++-${LLVM_VERSION} \ | ||
| -DLLVM_TARGETS_TO_BUILD=Native \ | ||
| -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \ | ||
| -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ | ||
| -DLIBCXX_HARDENING_MODE=debug \ | ||
| -S /llvm-project/runtimes; \ | ||
| ninja -C /cxx_build/; \ | ||
| du -sh /llvm-project; \ | ||
| rm -rf /llvm-project; | ||
|
|
||
| USER dash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
contrib/containers/ci/ci-msan.Dockerfilechanges without changing the generic CI Dockerfiles or Ubuntu base image, this job can restore a stalelinux64_msandepends prefix: the cache key in.github/workflows/build-depends.ymlhashes onlyci.Dockerfileandci-slim.Dockerfile. That can mix dependencies compiled against an earlier instrumented libc++ with the current/cxx_buildruntime, causing ABI failures or undermining MSan coverage; incorporate the MSan Dockerfile hash or image digest into this target's cache key.AGENTS.md reference: AGENTS.md:L227-L229
Useful? React with 👍 / 👎.