0fe0f453be
Every lane here was either asserting coverage it did not have, or was reachable only by bypassing the entry point that is supposed to define the ladder. TSan: no exclusions any more. The three suites the Makefile documented as excluded are back. daemon_ipc and daemon_frontend no longer reproduce the harness race and thread leaks they were excluded for. daemon_runtime did not deadlock as the comment claimed -- it reported a real production data race on the log sink, fixed separately. Excluding a suite from a sanitizer lane hides exactly the class of bug the lane exists to find, so the comment block now records what was actually true rather than what was assumed. TSAN_OPTIONS gains report_thread_leaks=0. This disables the thread- HYGIENE check only; race detection is untouched. Several daemon fixtures fork after the process has gone multi-threaded, and in the forked child TSan sees the parent's already-finished threads as never-joined even where the fixture joins them. It fires on macOS and not Linux, i.e. it tracks fork semantics rather than anything about this code. The alternative was dropping whole suites, which costs real race coverage; this costs none. UBSan: tre.o no longer builds with -fno-sanitize=alignment. Alignment was switched off for a vendored regex engine that ships in the product, which is where the check is least redundant, not most. LSan on macOS: new test-lsan target and test-lsan-macos CI leg. LSan is on by default under ASan on Linux, so the Linux legs have always had leak coverage. On macOS it is off by default and Apple's clang refuses to enable it outright, so that platform had none at all. Apple's refusal is not a darwin limitation -- upstream LLVM supports LSan on darwin/ arm64. The lane is the ordinary ASan suite built with Homebrew LLVM and run with detect_leaks=1; it runs the full suite clean and was checked to still catch a deliberately leaked allocation. MSan: reachable from the local ladder. The image and compose service existed but run.sh had no leg, so the only way in was to drive docker compose by hand -- which means it was not part of the ladder in any meaningful sense. The image also moves to clang 22, matching the diag and analyzer lanes instead of sitting four majors behind on noble's default. The leg documents the aarch64 shadow-mapping failure so a local arm64 stack overflow in the grammar suites is not mistaken for a code defect; the GitHub leg runs x86-64, which is the mapping that matters. Off-by-default ASan checks: the diagnostic lane, and its CI twin, now run detect_stack_use_after_return, detect_stack_use_after_scope, detect_invalid_pointer_pairs (with the -fsanitize=pointer-compare, pointer-subtract instrumentation it requires) and strict_string_checks. Running ASan is not the same as running all of it, and these four cover bug classes nothing in the matrix was looking for. They stay on the diagnostic lane rather than the gating ones until they have a clean history there; promoting them is a separate deliberate step. Verified: macOS TSan 940 passed / 3 skipped / 0 races over the full suite set; the macOS leak lane 7375 passed / 4 skipped / 0 leaks, with LeakSanitizer confirmed armed under that exact toolchain and option set by checking it still reports a deliberately leaked allocation. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
78 lines
3.6 KiB
Docker
78 lines
3.6 KiB
Docker
# MemorySanitizer lane image — stage-2 of the memory-diagnostics program.
|
|
#
|
|
# MSan requires EVERY linked library to be MSan-instrumented, or reads of
|
|
# memory those libraries wrote report as uninitialized. The vendored deps
|
|
# (sqlite3, lz4, zstd, tree-sitter runtime, grammars) compile in-tree and get
|
|
# instrumented for free; the two external links -lstdc++/-lz do not. This
|
|
# image provides an MSan-instrumented libc++/libc++abi/libunwind and zlib in
|
|
# /opt/msan, and scripts/msan.sh points the build at them.
|
|
#
|
|
# Sources are pinned by release tag from their canonical upstreams (same
|
|
# precedent as the cppcheck 2.20.0 build in _lint.yml).
|
|
#
|
|
# Build: docker build -f test-infrastructure/Dockerfile.msan -t cbm-msan test-infrastructure/
|
|
# Run: see scripts/msan.sh (driven via docker-compose service test-msan)
|
|
|
|
# Same pinned base as the primary test image — bump deliberately, never to a tag.
|
|
FROM ubuntu:noble@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90
|
|
|
|
# clang 22 from apt.llvm.org, matching the diag and analyzer lanes. Noble's
|
|
# default is clang 18 — four majors behind everything else here, which is both
|
|
# an inconsistency and a bad vantage point for debugging sanitizer behaviour.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends wget gnupg ca-certificates \
|
|
&& wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key > /etc/apt/trusted.gpg.d/apt.llvm.org.asc \
|
|
&& echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-22 main" > /etc/apt/sources.list.d/llvm-22.list \
|
|
&& apt-get update && apt-get install -y --no-install-recommends \
|
|
clang-22 libclang-rt-22-dev llvm-22 \
|
|
&& ln -sf /usr/bin/clang-22 /usr/bin/clang \
|
|
&& ln -sf /usr/bin/clang++-22 /usr/bin/clang++
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
cmake \
|
|
ninja-build \
|
|
make \
|
|
python3 \
|
|
git \
|
|
curl \
|
|
zsh \
|
|
ccache \
|
|
ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# libc++ + libc++abi + libunwind with MemoryWithOrigins, at the SAME major as
|
|
# the compiler above — a runtimes build must match its clang.
|
|
RUN git clone --depth 1 --branch llvmorg-22.1.0 \
|
|
https://github.com/llvm/llvm-project.git /tmp/llvm-project \
|
|
&& cmake -G Ninja -S /tmp/llvm-project/runtimes -B /tmp/llvm-msan \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_C_COMPILER=clang \
|
|
-DCMAKE_CXX_COMPILER=clang++ \
|
|
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
|
|
-DLLVM_USE_SANITIZER=MemoryWithOrigins \
|
|
-DCMAKE_INSTALL_PREFIX=/opt/msan \
|
|
-DLIBCXX_INCLUDE_TESTS=OFF \
|
|
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
|
|
-DLIBCXXABI_INCLUDE_TESTS=OFF \
|
|
-DLIBUNWIND_INCLUDE_TESTS=OFF \
|
|
&& ninja -C /tmp/llvm-msan cxx cxxabi unwind \
|
|
&& ninja -C /tmp/llvm-msan install-cxx install-cxxabi install-unwind \
|
|
&& rm -rf /tmp/llvm-project /tmp/llvm-msan
|
|
|
|
# zlib with MSan (static, so the runner needs no runtime path for it).
|
|
RUN git clone --depth 1 --branch v1.3.1 https://github.com/madler/zlib.git /tmp/zlib \
|
|
&& cd /tmp/zlib \
|
|
&& CC=clang CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -O2" \
|
|
./configure --prefix=/opt/msan --static \
|
|
&& make -j"$(nproc)" install \
|
|
&& rm -rf /tmp/zlib
|
|
|
|
# Symbolizer path in its own (last) layer so adding tools never invalidates
|
|
# the expensive libc++ build layers above. libclang-rt-22-dev is installed
|
|
# explicitly with the compiler: it is only a Recommends of clang, which
|
|
# --no-install-recommends drops, and the link then fails to find
|
|
# libclang_rt.msan-*.a.
|
|
ENV MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-22/bin/llvm-symbolizer
|
|
|
|
WORKDIR /src
|
|
ENTRYPOINT ["scripts/msan.sh"]
|