3 The tracking issue for this feature is: [#39699](https://github.com/rust-lang/rust/issues/39699).
5 ------------------------
7 This feature allows for use of one of following sanitizers:
9 * [AddressSanitizer][clang-asan] a fast memory error detector.
10 * [LeakSanitizer][clang-lsan] a run-time memory leak detector.
11 * [MemorySanitizer][clang-msan] a detector of uninitialized reads.
12 * [ThreadSanitizer][clang-tsan] a fast data race detector.
14 To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=leak`,
15 `-Zsanitizer=memory` or `-Zsanitizer=thread`. Only a single sanitizer can be
20 AddressSanitizer is a memory error detector. It can detect the following types
23 * Out of bound accesses to heap, stack and globals
25 * Use after return (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`)
27 * Double-free, invalid free
30 AddressSanitizer is supported on the following targets:
32 * `x86_64-apple-darwin`
33 * `x86_64-unknown-linux-gnu`
35 AddressSanitizer works with non-instrumented code although it will impede its
36 ability to detect some bugs. It is not expected to produce false positive
41 Stack buffer overflow:
45 let xs = [0, 1, 2, 3];
46 let _y = unsafe { *xs.as_ptr().offset(4) };
51 $ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
52 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
53 ==37882==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe400e6250 at pc 0x5609a841fb20 bp 0x7ffe400e6210 sp 0x7ffe400e6208
54 READ of size 4 at 0x7ffe400e6250 thread T0
55 #0 0x5609a841fb1f in example::main::h628ffc6626ed85b2 /.../src/main.rs:3:23
58 Address 0x7ffe400e6250 is located in stack of thread T0 at offset 48 in frame
59 #0 0x5609a841f8af in example::main::h628ffc6626ed85b2 /.../src/main.rs:1
61 This frame has 1 object(s):
62 [32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
63 HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
64 (longjmp and C++ exceptions *are* supported)
65 SUMMARY: AddressSanitizer: stack-buffer-overflow /.../src/main.rs:3:23 in example::main::h628ffc6626ed85b2
66 Shadow bytes around the buggy address:
67 0x100048014bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
68 0x100048014c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
69 0x100048014c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 0x100048014c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
71 0x100048014c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
72 =>0x100048014c40: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
73 0x100048014c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
74 0x100048014c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
75 0x100048014c70: f1 f1 f1 f1 00 00 f3 f3 00 00 00 00 00 00 00 00
76 0x100048014c80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
77 0x100048014c90: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
78 Shadow byte legend (one shadow byte represents 8 application bytes):
80 Partially addressable: 01 02 03 04 05 06 07
83 Stack left redzone: f1
85 Stack right redzone: f3
86 Stack after return: f5
87 Stack use after scope: f8
91 Container overflow: fc
93 Intra object redzone: bb
95 Left alloca redzone: ca
96 Right alloca redzone: cb
101 Use of a stack object after its scope has already ended:
104 static mut P: *mut usize = std::ptr::null_mut();
112 std::ptr::write_volatile(P, 123);
118 $ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
119 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
120 =================================================================
121 ==39249==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc7ed3e1a0 at pc 0x55c98b262a8e bp 0x7ffc7ed3e050 sp 0x7ffc7ed3e048
122 WRITE of size 8 at 0x7ffc7ed3e1a0 thread T0
123 #0 0x55c98b262a8d in core::ptr::write_volatile::he21f1df5a82f329a /.../src/rust/src/libcore/ptr/mod.rs:1048:5
124 #1 0x55c98b262cd2 in example::main::h628ffc6626ed85b2 /.../src/main.rs:9:9
127 Address 0x7ffc7ed3e1a0 is located in stack of thread T0 at offset 32 in frame
128 #0 0x55c98b262bdf in example::main::h628ffc6626ed85b2 /.../src/main.rs:3
130 This frame has 1 object(s):
131 [32, 40) 'x' (line 6) <== Memory access at offset 32 is inside this variable
132 HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
133 (longjmp and C++ exceptions *are* supported)
134 SUMMARY: AddressSanitizer: stack-use-after-scope /.../src/rust/src/libcore/ptr/mod.rs:1048:5 in core::ptr::write_volatile::he21f1df5a82f329a
135 Shadow bytes around the buggy address:
136 0x10000fd9fbe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
137 0x10000fd9fbf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
138 0x10000fd9fc00: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
139 0x10000fd9fc10: f8 f8 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
140 0x10000fd9fc20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
141 =>0x10000fd9fc30: f1 f1 f1 f1[f8]f3 f3 f3 00 00 00 00 00 00 00 00
142 0x10000fd9fc40: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
143 0x10000fd9fc50: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
144 0x10000fd9fc60: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3
145 0x10000fd9fc70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
146 0x10000fd9fc80: 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3 00 00 00 00
147 Shadow byte legend (one shadow byte represents 8 application bytes):
149 Partially addressable: 01 02 03 04 05 06 07
150 Heap left redzone: fa
151 Freed heap region: fd
152 Stack left redzone: f1
153 Stack mid redzone: f2
154 Stack right redzone: f3
155 Stack after return: f5
156 Stack use after scope: f8
158 Global init order: f6
160 Container overflow: fc
162 Intra object redzone: bb
164 Left alloca redzone: ca
165 Right alloca redzone: cb
172 MemorySanitizer is detector of uninitialized reads. It is only supported on the
173 `x86_64-unknown-linux-gnu` target.
175 MemorySanitizer requires all program code to be instrumented. C/C++ dependencies
176 need to be recompiled using Clang with `-fsanitize=memory` option. Failing to
177 achieve that will result in false positive reports.
181 Detecting the use of uninitialized memory. The `-Zbuild-std` flag rebuilds and
182 instruments the standard library, and is strictly necessary for the correct
183 operation of the tool. The `-Zsanitizer-track-origins` enables tracking of the
184 origins of uninitialized memory:
187 use std::mem::MaybeUninit;
191 let a = MaybeUninit::<[usize; 4]>::uninit();
192 let a = a.assume_init();
193 println!("{}", a[2]);
202 CFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \
203 CXXFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \
204 RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \
205 RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins'
207 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
208 ==9416==WARNING: MemorySanitizer: use-of-uninitialized-value
209 #0 0x560c04f7488a in core::fmt::num::imp::fmt_u64::haa293b0b098501ca $RUST/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/src/libcore/fmt/num.rs:202:16
211 Uninitialized value was stored to memory at
212 #0 0x560c04ae898a in __msan_memcpy.part.0 $RUST/src/llvm-project/compiler-rt/lib/msan/msan_interceptors.cc:1558:3
213 #1 0x560c04b2bf88 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:6:16
215 Uninitialized value was created by an allocation of 'a' in the stack frame of function '_ZN6memory4main17hd2333c1899d997f5E'
216 #0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3
221 ThreadSanitizer is a data race detection tool. It is supported on the following
224 * `x86_64-apple-darwin`
225 * `x86_64-unknown-linux-gnu`
227 To work correctly ThreadSanitizer needs to be "aware" of all synchronization
228 operations in a program. It generally achieves that through combination of
229 library interception (for example synchronization performed through
230 `pthread_mutex_lock` / `pthread_mutex_unlock`) and compile time instrumentation
231 (e.g. atomic operations). Using it without instrumenting all the program code
232 can lead to false positive reports.
234 ThreadSanitizer does not support atomic fences `std::sync::atomic::fence`,
235 nor synchronization performed using inline assembly code.
240 static mut A: usize = 0;
243 let t = std::thread::spawn(|| {
253 $ export RUSTFLAGS=-Zsanitizer=thread RUSTDOCFLAGS=-Zsanitizer=thread
254 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
256 WARNING: ThreadSanitizer: data race (pid=10574)
257 Read of size 8 at 0x5632dfe3d030 by thread T1:
258 #0 example::main::_$u7b$$u7b$closure$u7d$$u7d$::h23f64b0b2f8c9484 ../src/main.rs:5:18 (example+0x86cec)
261 Previous write of size 8 at 0x5632dfe3d030 by main thread:
262 #0 example::main::h628ffc6626ed85b2 /.../src/main.rs:7:14 (example+0x868c8)
264 #11 main <null> (example+0x86a1a)
266 Location is global 'example::A::h43ac149ddf992709' of size 8 at 0x5632dfe3d030 (example+0x000000bd9030)
269 # Instrumentation of external dependencies and std
271 The sanitizers to varying degrees work correctly with partially instrumented
272 code. On the one extreme is LeakSanitizer that doesn't use any compile time
273 instrumentation, on the other is MemorySanitizer that requires that all program
274 code to be instrumented (failing to achieve that will inevitably result in
277 It is strongly recommended to combine sanitizers with recompiled and
278 instrumented standard library, for example using [cargo `-Zbuild-std`
279 functionality][build-std].
281 [build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
283 # Build scripts and procedural macros
285 Use of sanitizers together with build scripts and procedural macros is
286 technically possible, but in almost all cases it would be best avoided. This
287 is especially true for procedural macros which would require an instrumented
290 In more practical terms when using cargo always remember to pass `--target`
291 flag, so that rustflags will not be applied to build scripts and procedural
294 # Symbolizing the Reports
296 Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PATH`.
298 # Additional Information
300 * [Sanitizers project page](https://github.com/google/sanitizers/wiki/)
301 * [AddressSanitizer in Clang][clang-asan]
302 * [LeakSanitizer in Clang][clang-lsan]
303 * [MemorySanitizer in Clang][clang-msan]
304 * [ThreadSanitizer in Clang][clang-tsan]
306 [clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html
307 [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html
308 [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html
309 [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html