owned this note
owned this note
Published
Linked with GitHub
# Prebuilt sanitizer instrumented rust-std
Sanitizers are compiler passes (sometimes with a runtime component) used in software development to detect various types of bugs and undefined behavior during runtime.
Some sanitizers, such as e.g., AddressSanitizer and LeakSanitizer, are OK to run without instrumenting the standard libraries and only risk lower coverage and therefore false negatives.
Other sanitizers, such as MemorySanitizer and ThreadSanitizer, actually generate false positives if not the whole binary, including the standard libraries, is instrumented. There is some context in [PR #123617](https://github.com/rust-lang/rust/pull/123617#issuecomment-2192800482).
It therefore requires the combination with `-Z build-std` which, at least in my understanding, is not going to be stabilized in the near future. That caused the [suggestion](https://github.com/rust-lang/rust/issues/78533) to provide prebuilt standard library artifacts, so people **can** use the stabilized sanitizers without a nightly compiler.
However, this will need support in the compiler, bootstrap, and potentially cargo and rustup.
## High level design proposal
Currently `rustc` has a single `--sysroot` that allows to set the entire sysroot but there is no way to toggle between different standard library variants there.
We could have a structure inside that looks something like this:
```
.../lib/rustlib/
└── x86_64-unknown-linux-gnu/
├── lib/ # The default standard library
├── lib-asan/ # The variant built with AddressSanitizer
└── lib-msan/ # The variant built with MemorySanitizer
```
In order to do so, we would need: A) compiler support to enable the variant required and B) bootstrap support in order to provide the variants through rustup.
## Bootstrap (and rustup) changes
There was already a [preliminary zulip discussion](https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/2025H2.20Goal.20Review/near/532154795), discussing the potential bootstrap and rustup changes involved.
In the discussion, three options came up to provide the sanitizer instrumented standard libraries.
* A) Include all the sanitizer instrumented standard libraries within the `rust-std` component. This is probably not desired since it will just increase download size for everybody, even if they are not using sanitizers.
* B) Have a separate new component for every sanitizer. I'm not sure having so many new components is preferred and makes a lot of sense.
* C) (In my mind preferred) Create a new component (e.g. `rust-std-sanitizers`) that includes all the sanitizer instrumented standard libraries together.
## Compiler changes
The compiler will need some modifications to use the instrumented standard libraries.
I can see two options to do this:
* A) (Preferred) If you enable e.g. AddressSanitizer (`-Csanitize=address`), the compiler automatically looks for the standard libraries in `lib-asan`. If someone would want to use e.g., ASAN without an instrumented standard library, they could explicitly opt-out of that (using `-Zsanitizer-use-prebuilt-library=no`). We need such a mechanism to e.g. be passed to the compiler by cargo with `build-std` since otherwise even building the standard libraries for `build-std` would need to have the prebuilt libraries.
* B) You need to explicitly tell the compiler which standard library to use (e.g. `-Cstd-variant=asan`).
While A) definitely provides the simplicity for the user ([eholk](https://github.com/eholk) has some code to show this in a [commit](https://github.com/rust-lang/rust/commit/c4fdc5c4b65feef92a9ebcaaf3748c0bd70ac002)), we need to make sure there is a sufficient error message if e.g., `lib-asan` cannot be found. Finally, we need to handle the edge case of a user having multiple sanitizers enabled since we don't want to provide artifacts for all possible combinations.
B) is significantly more explicit and allows the user to manually choose which variant to use, **if** e.g., multiple sanitizers are enabled. But it also requires an additional choice from the user (which in most cases could just be infered, if only one sanitizer is enabled).
Currently, I lean towards A) and providing good error messages to suggest downloading the necessary rustup component, if it's missing, or suggest using `-Z build-std` if multiple sanitizers are enabled.
## Discussion
I've setup this document primarily to familiarize and organize myself with the necessary steps required and as a baseline for discussion. So if you see any issues or have suggestions, please [reach out](https://rust-lang.zulipchat.com/#user/785440)!