The rustc compiler contains support for following 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.
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 when enabled in config.toml
:
[build] sanitizers = true
The runtimes are placed into target libdir.
During LLVM code generation, the functions intended for instrumentation are marked 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 and LLVM level.
The LLVM IR generated by rustc is instrumented by dedicated LLVM passes, different for each sanitizer. Instrumentation passes are invoked after optimization passes.
When producing an executable, the sanitizer specific runtime library is linked in. 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.