# Sanitizers Support

The rustc compiler contains support for following sanitizers:

* [AddressSanitizer][clang-asan] a faster memory error detector. Can
  detect out-of-bounds access to heap, stack, and globals, use after free, use
  after return, double free, invalid free, memory leaks.
* [LeakSanitizer][clang-lsan] a run-time memory leak detector.
* [MemorySanitizer][clang-msan] a detector of uninitialized reads.
* [ThreadSanitizer][clang-tsan] a fast data race detector.

## How to use the sanitizers?

To enable a sanitizer compile with `-Zsanitizer=...` option, where value is one
of `address`, `leak`, `memory` or `thread`. For more details how to use
sanitizers please refer to [the unstable book](https://doc.rust-lang.org/unstable-book/).

## How are sanitizers implemented in rustc?

The implementation of sanitizers relies almost entirely on LLVM. The rustc is
an integration point for LLVM compile time instrumentation passes and runtime
libraries. Highlight of the most important aspects of the implementation:

*  The sanitizer runtime libraries are part of the [compiler-rt] project, and
   [will be built on supported targets][sanitizer-build] when enabled in `config.toml`:

   ```toml
   [build]
   sanitizers = true
   ```

   The runtimes are [placed into target libdir][sanitizer-copy].

*  During LLVM code generation, the functions intended for instrumentation are
   [marked][sanitizer-attribute] with appropriate LLVM attribute:
   `SanitizeAddress`, `SanitizeMemory`, or `SanitizeThread`. By default all
   functions are instrumented, but this behaviour can be changed with
   `#[no_sanitize(...)]`.

*  The decision whether to perform instrumentation or not is possible only at a
   function granularity. In the cases were those decision differ between
   functions it might be necessary to inhibit inlining, both at [MIR
   level][inline-mir] and [LLVM level][inline-llvm].

*  The LLVM IR generated by rustc is instrumented by [dedicated LLVM
   passes][sanitizer-pass], different for each sanitizer. Instrumentation
   passes are invoked after optimization passes.

*  When producing an executable, the sanitizer specific runtime library is
   [linked in][sanitizer-link]. The libraries are searched for in target libdir
   relative to default system root, so that this process is not affected
   by sysroot overrides used for example by cargo `-Zbuild-std` functionality.

[compiler-rt]: https://github.com/llvm/llvm-project/tree/master/compiler-rt
[sanitizer-build]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/bootstrap/native.rs#L566-L624
[sanitizer-copy]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/bootstrap/compile.rs#L270-L304
[sanitizer-attribute]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/librustc_codegen_llvm/attributes.rs#L49-L72
[inline-mir]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/librustc_mir/transform/inline.rs#L232-L252
[inline-llvm]: https://github.com/rust-lang/llvm-project/blob/9330ec5a4c1df5fc1fa62f993ed6a04da68cb040/llvm/include/llvm/IR/Attributes.td#L225-L241
[sanitizer-pass]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/librustc_codegen_llvm/back/write.rs#L454-L475
[sanitizer-link]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/librustc_codegen_ssa/back/link.rs#L748-L787

## Additional Information

* [Sanitizers project page](https://github.com/google/sanitizers/wiki/)
* [AddressSanitizer in Clang][clang-asan]
* [LeakSanitizer in Clang][clang-lsan]
* [MemorySanitizer in Clang][clang-msan]
* [ThreadSanitizer in Clang][clang-tsan]

[clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html
[clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html
[clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html
[clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html
