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`.
19 AddressSanitizer is a memory error detector. It can detect the following types
22 * Out of bound accesses to heap, stack and globals
24 * Use after return (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`)
26 * Double-free, invalid free
29 AddressSanitizer is supported on the following targets:
31 * `x86_64-apple-darwin`
32 * `x86_64-unknown-linux-gnu`
34 AddressSanitizer works with non-instrumented code although it will impede its
35 ability to detect some bugs. It is not expected to produce false positive
40 Stack buffer overflow:
44 let xs = [0, 1, 2, 3];
45 let _y = unsafe { *xs.as_ptr().offset(4) };
50 $ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
51 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
52 ==37882==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe400e6250 at pc 0x5609a841fb20 bp 0x7ffe400e6210 sp 0x7ffe400e6208
53 READ of size 4 at 0x7ffe400e6250 thread T0
54 #0 0x5609a841fb1f in example::main::h628ffc6626ed85b2 /.../src/main.rs:3:23
57 Address 0x7ffe400e6250 is located in stack of thread T0 at offset 48 in frame
58 #0 0x5609a841f8af in example::main::h628ffc6626ed85b2 /.../src/main.rs:1
60 This frame has 1 object(s):
61 [32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
62 HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
63 (longjmp and C++ exceptions *are* supported)
64 SUMMARY: AddressSanitizer: stack-buffer-overflow /.../src/main.rs:3:23 in example::main::h628ffc6626ed85b2
65 Shadow bytes around the buggy address:
66 0x100048014bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
67 0x100048014c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
68 0x100048014c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
69 0x100048014c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 0x100048014c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
71 =>0x100048014c40: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
72 0x100048014c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
73 0x100048014c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
74 0x100048014c70: f1 f1 f1 f1 00 00 f3 f3 00 00 00 00 00 00 00 00
75 0x100048014c80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
76 0x100048014c90: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
77 Shadow byte legend (one shadow byte represents 8 application bytes):
79 Partially addressable: 01 02 03 04 05 06 07
82 Stack left redzone: f1
84 Stack right redzone: f3
85 Stack after return: f5
86 Stack use after scope: f8
90 Container overflow: fc
92 Intra object redzone: bb
94 Left alloca redzone: ca
95 Right alloca redzone: cb
100 Use of a stack object after its scope has already ended:
103 static mut P: *mut usize = std::ptr::null_mut();
111 std::ptr::write_volatile(P, 123);
117 $ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
118 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
119 =================================================================
120 ==39249==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc7ed3e1a0 at pc 0x55c98b262a8e bp 0x7ffc7ed3e050 sp 0x7ffc7ed3e048
121 WRITE of size 8 at 0x7ffc7ed3e1a0 thread T0
122 #0 0x55c98b262a8d in core::ptr::write_volatile::he21f1df5a82f329a /.../src/rust/src/libcore/ptr/mod.rs:1048:5
123 #1 0x55c98b262cd2 in example::main::h628ffc6626ed85b2 /.../src/main.rs:9:9
126 Address 0x7ffc7ed3e1a0 is located in stack of thread T0 at offset 32 in frame
127 #0 0x55c98b262bdf in example::main::h628ffc6626ed85b2 /.../src/main.rs:3
129 This frame has 1 object(s):
130 [32, 40) 'x' (line 6) <== Memory access at offset 32 is inside this variable
131 HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
132 (longjmp and C++ exceptions *are* supported)
133 SUMMARY: AddressSanitizer: stack-use-after-scope /.../src/rust/src/libcore/ptr/mod.rs:1048:5 in core::ptr::write_volatile::he21f1df5a82f329a
134 Shadow bytes around the buggy address:
135 0x10000fd9fbe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
136 0x10000fd9fbf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
137 0x10000fd9fc00: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
138 0x10000fd9fc10: f8 f8 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
139 0x10000fd9fc20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140 =>0x10000fd9fc30: f1 f1 f1 f1[f8]f3 f3 f3 00 00 00 00 00 00 00 00
141 0x10000fd9fc40: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
142 0x10000fd9fc50: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
143 0x10000fd9fc60: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3
144 0x10000fd9fc70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
145 0x10000fd9fc80: 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3 00 00 00 00
146 Shadow byte legend (one shadow byte represents 8 application bytes):
148 Partially addressable: 01 02 03 04 05 06 07
149 Heap left redzone: fa
150 Freed heap region: fd
151 Stack left redzone: f1
152 Stack mid redzone: f2
153 Stack right redzone: f3
154 Stack after return: f5
155 Stack use after scope: f8
157 Global init order: f6
159 Container overflow: fc
161 Intra object redzone: bb
163 Left alloca redzone: ca
164 Right alloca redzone: cb
171 MemorySanitizer is detector of uninitialized reads. It is only supported on the
172 `x86_64-unknown-linux-gnu` target.
174 MemorySanitizer requires all program code to be instrumented. C/C++ dependencies
175 need to be recompiled using Clang with `-fsanitize=memory` option. Failing to
176 achieve that will result in false positive reports.
180 Detecting the use of uninitialized memory. The `-Zbuild-std` flag rebuilds and
181 instruments the standard library, and is strictly necessary for the correct
182 operation of the tool. The `-Zsanitizer-track-origins` enables tracking of the
183 origins of uninitialized memory:
186 use std::mem::MaybeUninit;
190 let a = MaybeUninit::<[usize; 4]>::uninit();
191 let a = a.assume_init();
192 println!("{}", a[2]);
201 CFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \
202 CXXFLAGS='-fsanitize=memory -fsanitize-memory-track-origins' \
203 RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \
204 RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins'
206 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
207 ==9416==WARNING: MemorySanitizer: use-of-uninitialized-value
208 #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
210 Uninitialized value was stored to memory at
211 #0 0x560c04ae898a in __msan_memcpy.part.0 $RUST/src/llvm-project/compiler-rt/lib/msan/msan_interceptors.cc:1558:3
212 #1 0x560c04b2bf88 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:6:16
214 Uninitialized value was created by an allocation of 'a' in the stack frame of function '_ZN6memory4main17hd2333c1899d997f5E'
215 #0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3
220 ThreadSanitizer is a data race detection tool. It is supported on the following
223 * `x86_64-apple-darwin`
224 * `x86_64-unknown-linux-gnu`
226 To work correctly ThreadSanitizer needs to be "aware" of all synchronization
227 operations in a program. It generally achieves that through combination of
228 library interception (for example synchronization performed through
229 `pthread_mutex_lock` / `pthread_mutex_unlock`) and compile time instrumentation
230 (e.g. atomic operations). Using it without instrumenting all the program code
231 can lead to false positive reports.
233 ThreadSanitizer does not support atomic fences `std::sync::atomic::fence`,
234 nor synchronization performed using inline assembly code.
239 static mut A: usize = 0;
242 let t = std::thread::spawn(|| {
252 $ export RUSTFLAGS=-Zsanitizer=thread RUSTDOCFLAGS=-Zsanitizer=thread
253 $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
255 WARNING: ThreadSanitizer: data race (pid=10574)
256 Read of size 8 at 0x5632dfe3d030 by thread T1:
257 #0 example::main::_$u7b$$u7b$closure$u7d$$u7d$::h23f64b0b2f8c9484 ../src/main.rs:5:18 (example+0x86cec)
260 Previous write of size 8 at 0x5632dfe3d030 by main thread:
261 #0 example::main::h628ffc6626ed85b2 /.../src/main.rs:7:14 (example+0x868c8)
263 #11 main <null> (example+0x86a1a)
265 Location is global 'example::A::h43ac149ddf992709' of size 8 at 0x5632dfe3d030 (example+0x000000bd9030)
268 # Instrumentation of external dependencies and std
270 The sanitizers to varying degrees work correctly with partially instrumented
271 code. On the one extreme is LeakSanitizer that doesn't use any compile time
272 instrumentation, on the other is MemorySanitizer that requires that all program
273 code to be instrumented (failing to achieve that will inevitably result in
276 It is strongly recommended to combine sanitizers with recompiled and
277 instrumented standard library, for example using [cargo `-Zbuild-std`
278 functionality][build-std].
280 [build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
282 # Build scripts and procedural macros
284 Use of sanitizers together with build scripts and procedural macros is
285 technically possible, but in almost all cases it would be best avoided. This
286 is especially true for procedural macros which would require an instrumented
289 In more practical terms when using cargo always remember to pass `--target`
290 flag, so that rustflags will not be applied to build scripts and procedural
293 # Symbolizing the Reports
295 Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PATH`.
297 # Additional Information
299 * [Sanitizers project page](https://github.com/google/sanitizers/wiki/)
300 * [AddressSanitizer in Clang][clang-asan]
301 * [LeakSanitizer in Clang][clang-lsan]
302 * [MemorySanitizer in Clang][clang-msan]
303 * [ThreadSanitizer in Clang][clang-tsan]
305 [clang-asan]: https://clang.llvm.org/docs/AddressSanitizer.html
306 [clang-lsan]: https://clang.llvm.org/docs/LeakSanitizer.html
307 [clang-msan]: https://clang.llvm.org/docs/MemorySanitizer.html
308 [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html