tsan: support macOS arm64 hosts alongside Linux x86_64 - #7238
Merged
Conversation
Generalizes the ThreadSanitizer configuration so it also runs on Apple Silicon
Macs, where most workerd development happens. Linux behavior is unchanged.
- The tsan platform inherits the host (like the asan one) instead of pinning
linux/x86_64, and the single Rust toolchain becomes a tsan_rust_toolchain
macro instantiated per host: Linux x86_64 (unchanged attributes) and macOS
arm64 (mirroring rules_rust's generated aarch64-apple-darwin toolchain).
--extra_toolchains lists both; resolution picks the host's. A select() alias
keeps //build/rust:tsan_rust_std working for tsan-test.
- .bazelrc: the portable flags move to `tsan-common`; `--config=tsan` (Linux)
adds the GNU-ld-only unwinder linkopt and is otherwise identical to before;
`--config=tsan-macos` is the macOS entry point. bazelrc cannot make a single
linkopt OS-conditional, hence two entry points.
- rustc passes -nodefaultlibs to the linker driver, and unlike Linux, Darwin's
clang then also omits the sanitizer runtime that -Zexternal-clangrt expects
it to supply. The macOS toolchain adds -Cdefault-linker-libraries=yes so
every Rust-driven link gets libclang_rt.tsan_osx_dynamic.dylib, sharing
Clang's runtime with C++ exactly as on Linux. For the same reason the
build-std script's throwaway test binary links Rust's own runtime instead
(the flag is link-only and never affects the rlibs we keep).
- build_std.sh hermeticity: cargo reads config.toml from every ancestor of the
sandbox, which lives under $HOME on both Linux (~/.cache/bazel) and macOS
(~/Library/Caches/bazel), so a developer's ~/.cargo/config.toml leaked in
(observed: rustc-wrapper = "sccache"). RUSTC_WRAPPER and
RUSTC_WORKSPACE_WRAPPER are now explicitly cleared.
- build_std.sh portability: no bash-4-only ${var^^}/mapfile (macOS ships bash
3.2) and no GNU realpath -m; the runtime-library filter matches the
librustc-nightly_rt.tsan.* stem (a .a on Linux, a .dylib on macOS).
Verified on macOS arm64: `bazel test --config=tsan-macos //src/rust/tsan-test/...
//src/rust/cxx/kj-rs/tests/...` passes, binaries carry __tsan_* symbols and
link libclang_rt.tsan_osx_dynamic.dylib, and tsan-integration-test confirms the
rebuilt standard library is instrumented and a racy Rust binary is detected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
danlapid
force-pushed
the
dlapid/tsanMacos
branch
from
September 3, 2026 22:35
626d084 to
98f8e6b
Compare
mikea
approved these changes
Sep 3, 2026
jasnell
approved these changes
Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #7214. Generalizes the TSan configuration so it also runs on Apple Silicon Macs (where most of us develop); Linux behavior is unchanged.
What changes
sanitizer_thread_platforminherits the host (like the asan platform) instead of pinning linux/x86_64.tsan_rust_toolchainmacro (build/rust/tsan_toolchain.bzl) instantiated for Linux x86_64 (attributes unchanged) and macOS arm64 (mirroring rules_rust's generatedaarch64-apple-darwintoolchain).--extra_toolchainslists both; aselect()alias keeps//build/rust:tsan_rust_stdworking fortsan-test..bazelrc: portable flags move totsan-common;--config=tsan(Linux) adds the GNU-ld-only-l:libunwind.so.8and is otherwise identical to before;--config=tsan-macosis the macOS entry point. bazelrc can't make one linkopt OS-conditional, hence the two entry points.Three issues found while porting (the first affects Linux too)
config.tomlfrom every ancestor of the sandbox, which lives under$HOMEon both platforms (~/.cache/bazel,~/Library/Caches/bazel) — my~/.cargo/config.toml'srustc-wrapper = "sccache"broke the build-std action.RUSTC_WRAPPER/RUSTC_WORKSPACE_WRAPPERare now explicitly cleared.-nodefaultlibsto the linker driver; Darwin's clang then also omits the sanitizer runtime that-Zexternal-clangrtrelies on it to supply (Linux clang adds it regardless). The macOS toolchain adds-Cdefault-linker-libraries=yesso every Rust-driven link getslibclang_rt.tsan_osx_dynamic.dylib— sharing Clang's runtime with C++, as on Linux. The build-std script's throwaway test binary links Rust's own runtime instead for the same reason (link-only flag; rlibs unaffected).build_std.shused bash-4-only${var^^}/mapfileand GNUrealpath -m; macOS ships bash 3.2. Now portable. The runtime-library filter matches thelibrustc-nightly_rt.tsan.*stem (.aon Linux,.dylibon macOS).Verified on macOS arm64:
bazel test --config=tsan-macos //src/rust/tsan-test/... //src/rust/cxx/kj-rs/tests/...— 7/7 pass; the binaries carry__tsan_*symbols and linklibclang_rt.tsan_osx_dynamic.dylib;tsan-integration-testconfirms the rebuilt stdlib is instrumented and a racy Rust binary is detected. Not re-verified on Linux (no x86_64 box here) — the Linux net flags and toolchain attributes are unchanged, but a CI/local run there would be welcome.🤖 Generated with Claude Code