Skip to content

Commit a5b09d3

Browse files
committed
Auto merge of #70625 - Dylan-DPC:rollup-o8n2hw8, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #69425 (add fn make_contiguous to VecDeque) - #69458 (improve folder name for persistent doc tests) - #70268 (Document ThreadSanitizer in unstable-book) - #70600 (Ensure there are versions of test code for aarch64 windows) - #70606 (Clean up E0466 explanation) - #70614 (remove unnecessary relocation check in const_prop) - #70623 (Fix broken link in README) Failed merges: r? @ghost
2 parents 75ff311 + 011c090 commit a5b09d3

File tree

9 files changed

+454
-205
lines changed

9 files changed

+454
-205
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
256256
257257
[rust-discord]: https://discord.gg/rust-lang
258258
[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/about-this-guide.html
259-
[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
259+
[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/
260260
261261
## License
262262

src/doc/unstable-book/src/compiler-flags/sanitizer.md

+150-86
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,78 @@ The tracking issue for this feature is: [#39699](https://github.com/rust-lang/ru
66

77
This feature allows for use of one of following sanitizers:
88

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

16-
To enable a sanitizer compile with `-Zsanitizer=...` option, where value is one
17-
of `address`, `leak`, `memory` or `thread`.
14+
To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=leak`,
15+
`-Zsanitizer=memory` or `-Zsanitizer=thread`. Only a single sanitizer can be
16+
enabled at a time.
1817

19-
# Examples
18+
# AddressSanitizer
2019

21-
This sections show various issues that can be detected with sanitizers. For
22-
simplicity, the examples are prepared under assumption that optimization level
23-
used is zero.
20+
AddressSanitizer is a memory error detector. It can detect the following types
21+
of bugs:
2422

25-
## AddressSanitizer
23+
* Out of bound accesses to heap, stack and globals
24+
* Use after free
25+
* Use after return (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`)
26+
* Use after scope
27+
* Double-free, invalid free
28+
* Memory leaks
29+
30+
AddressSanitizer is supported on the following targets:
31+
32+
* `x86_64-apple-darwin`
33+
* `x86_64-unknown-linux-gnu`
34+
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
37+
reports.
38+
39+
## Examples
2640

2741
Stack buffer overflow:
2842

29-
```shell
30-
$ cat a.rs
43+
```rust
3144
fn main() {
3245
let xs = [0, 1, 2, 3];
3346
let _y = unsafe { *xs.as_ptr().offset(4) };
3447
}
35-
$ rustc -Zsanitizer=address a.rs
36-
$ ./a
37-
=================================================================
38-
==10029==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcc15f43d0 at pc 0x55f77dc015c5 bp 0x7ffcc15f4390 sp 0x7ffcc15f4388
39-
READ of size 4 at 0x7ffcc15f43d0 thread T0
40-
#0 0x55f77dc015c4 in a::main::hab3bd2a745c2d0ac (/tmp/a+0xa5c4)
41-
#1 0x55f77dc01cdb in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::haa8c76d1faa7b7ca (/tmp/a+0xacdb)
42-
#2 0x55f77dc90f02 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::hfeb9a1aef9ac820d /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/rt.rs:48:12
43-
#3 0x55f77dc90f02 in std::panicking::try::do_call::h12f0919717b8e0a6 /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panicking.rs:288:39
44-
#4 0x55f77dc926c9 in __rust_maybe_catch_panic /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libpanic_unwind/lib.rs:80:7
45-
#5 0x55f77dc9197c in std::panicking::try::h413b21cdcd6cfd86 /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panicking.rs:267:12
46-
#6 0x55f77dc9197c in std::panic::catch_unwind::hc5cc8ef2fd73424d /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/panic.rs:396:8
47-
#7 0x55f77dc9197c in std::rt::lang_start_internal::h2039f418ab92218f /rustc/c27f7568bc74c418996892028a629eed5a7f5f00/src/libstd/rt.rs:47:24
48-
#8 0x55f77dc01c61 in std::rt::lang_start::ha905d28f6b61d691 (/tmp/a+0xac61)
49-
#9 0x55f77dc0163a in main (/tmp/a+0xa63a)
50-
#10 0x7f9b3cf5bbba in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26bba)
51-
#11 0x55f77dc01289 in _start (/tmp/a+0xa289)
52-
53-
Address 0x7ffcc15f43d0 is located in stack of thread T0 at offset 48 in frame
54-
#0 0x55f77dc0135f in a::main::hab3bd2a745c2d0ac (/tmp/a+0xa35f)
48+
```
49+
50+
```shell
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
56+
...
57+
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
5560

5661
This frame has 1 object(s):
57-
[32, 48) 'xs' <== Memory access at offset 48 overflows this variable
62+
[32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
5863
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
5964
(longjmp and C++ exceptions *are* supported)
60-
SUMMARY: AddressSanitizer: stack-buffer-overflow (/tmp/a+0xa5c4) in a::main::hab3bd2a745c2d0ac
65+
SUMMARY: AddressSanitizer: stack-buffer-overflow /.../src/main.rs:3:23 in example::main::h628ffc6626ed85b2
6166
Shadow bytes around the buggy address:
62-
0x1000182b6820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
63-
0x1000182b6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
64-
0x1000182b6840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
65-
0x1000182b6850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
66-
0x1000182b6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
67-
=>0x1000182b6870: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
68-
0x1000182b6880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
69-
0x1000182b6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70-
0x1000182b68a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
71-
0x1000182b68b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
72-
0x1000182b68c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
7378
Shadow byte legend (one shadow byte represents 8 application bytes):
7479
Addressable: 00
75-
Partially addressable: 01 02 03 04 05 06 07
80+
Partially addressable: 01 02 03 04 05 06 07
7681
Heap left redzone: fa
7782
Freed heap region: fd
7883
Stack left redzone: f1
@@ -90,13 +95,12 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
9095
Left alloca redzone: ca
9196
Right alloca redzone: cb
9297
Shadow gap: cc
93-
==10029==ABORTING
98+
==37882==ABORTING
9499
```
95100
96101
Use of a stack object after its scope has already ended:
97102
98-
```shell
99-
$ cat b.rs
103+
```rust
100104
static mut P: *mut usize = std::ptr::null_mut();
101105

102106
fn main() {
@@ -108,42 +112,38 @@ fn main() {
108112
std::ptr::write_volatile(P, 123);
109113
}
110114
}
111-
$ rustc -Zsanitizer=address b.rs
112-
$./b
115+
```
116+
117+
```shell
118+
$ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
119+
$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
113120
=================================================================
114-
==424427==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fff67be6be0 at pc 0x5647a3ea4658 bp 0x7fff67be6b90 sp 0x7fff67be6b88
115-
WRITE of size 8 at 0x7fff67be6be0 thread T0
116-
#0 0x5647a3ea4657 in core::ptr::write_volatile::h4b04601757d0376d (/tmp/b+0xb8657)
117-
#1 0x5647a3ea4432 in b::main::h5574a756e615c9cf (/tmp/b+0xb8432)
118-
#2 0x5647a3ea480b in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hd57e7ee01866077e (/tmp/b+0xb880b)
119-
#3 0x5647a3eab412 in std::panicking::try::do_call::he0421ca82dd11ba3 (.llvm.8083791802951296215) (/tmp/b+0xbf412)
120-
#4 0x5647a3eacb26 in __rust_maybe_catch_panic (/tmp/b+0xc0b26)
121-
#5 0x5647a3ea5b66 in std::rt::lang_start_internal::h19bc96b28f670a64 (/tmp/b+0xb9b66)
122-
#6 0x5647a3ea4788 in std::rt::lang_start::h642d10b4b6965fb8 (/tmp/b+0xb8788)
123-
#7 0x5647a3ea449a in main (/tmp/b+0xb849a)
124-
#8 0x7fd1d18b3bba in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26bba)
125-
#9 0x5647a3df7299 in _start (/tmp/b+0xb299)
126-
127-
Address 0x7fff67be6be0 is located in stack of thread T0 at offset 32 in frame
128-
#0 0x5647a3ea433f in b::main::h5574a756e615c9cf (/tmp/b+0xb833f)
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
125+
...
126+
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
129129

130130
This frame has 1 object(s):
131-
[32, 40) 'x' <== Memory access at offset 32 is inside this variable
131+
[32, 40) 'x' (line 6) <== Memory access at offset 32 is inside this variable
132132
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
133133
(longjmp and C++ exceptions *are* supported)
134-
SUMMARY: AddressSanitizer: stack-use-after-scope (/tmp/b+0xb8657) in core::ptr::write_volatile::h4b04601757d0376d
134+
SUMMARY: AddressSanitizer: stack-use-after-scope /.../src/rust/src/libcore/ptr/mod.rs:1048:5 in core::ptr::write_volatile::he21f1df5a82f329a
135135
Shadow bytes around the buggy address:
136-
0x10006cf74d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
137-
0x10006cf74d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
138-
0x10006cf74d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
139-
0x10006cf74d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140-
0x10006cf74d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
141-
=>0x10006cf74d70: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[f8]f3 f3 f3
142-
0x10006cf74d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
143-
0x10006cf74d90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
144-
0x10006cf74da0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
145-
0x10006cf74db0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
146-
0x10006cf74dc0: f1 f1 f1 f1 00 f3 f3 f3 00 00 00 00 00 00 00 00
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
147147
Shadow byte legend (one shadow byte represents 8 application bytes):
148148
Addressable: 00
149149
Partially addressable: 01 02 03 04 05 06 07
@@ -164,17 +164,26 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
164164
Left alloca redzone: ca
165165
Right alloca redzone: cb
166166
Shadow gap: cc
167-
==424427==ABORTING
167+
==39249==ABORTING
168168
```
169169
170-
## MemorySanitizer
170+
# MemorySanitizer
171+
172+
MemorySanitizer is detector of uninitialized reads. It is only supported on the
173+
`x86_64-unknown-linux-gnu` target.
174+
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.
178+
179+
## Example
171180
172-
Use of uninitialized memory. Note that we are using `-Zbuild-std` to instrument
173-
the standard library, and passing `-Zsanitizer-track-origins` to track the
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
174184
origins of uninitialized memory:
175185
176-
```shell
177-
$ cat src/main.rs
186+
```rust
178187
use std::mem::MaybeUninit;
179188

180189
fn main() {
@@ -184,7 +193,9 @@ fn main() {
184193
println!("{}", a[2]);
185194
}
186195
}
196+
```
187197
198+
```shell
188199
$ export \
189200
CC=clang \
190201
CXX=clang++ \
@@ -193,7 +204,7 @@ $ export \
193204
RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \
194205
RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins'
195206
$ cargo clean
196-
$ cargo -Zbuild-std run --target x86_64-unknown-linux-gnu
207+
$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
197208
==9416==WARNING: MemorySanitizer: use-of-uninitialized-value
198209
#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
199210
...
@@ -205,6 +216,55 @@ $ cargo -Zbuild-std run --target x86_64-unknown-linux-gnu
205216
#0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3
206217
```
207218
219+
# ThreadSanitizer
220+
221+
ThreadSanitizer is a data race detection tool. It is supported on the following
222+
targets:
223+
224+
* `x86_64-apple-darwin`
225+
* `x86_64-unknown-linux-gnu`
226+
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.
233+
234+
ThreadSanitizer does not support atomic fences `std::sync::atomic::fence`,
235+
nor synchronization performed using inline assembly code.
236+
237+
## Example
238+
239+
```rust
240+
static mut A: usize = 0;
241+
242+
fn main() {
243+
let t = std::thread::spawn(|| {
244+
unsafe { A += 1 };
245+
});
246+
unsafe { A += 1 };
247+
248+
t.join().unwrap();
249+
}
250+
```
251+
252+
```shell
253+
$ export RUSTFLAGS=-Zsanitizer=thread RUSTDOCFLAGS=-Zsanitizer=thread
254+
$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
255+
==================
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)
259+
...
260+
261+
Previous write of size 8 at 0x5632dfe3d030 by main thread:
262+
#0 example::main::h628ffc6626ed85b2 /.../src/main.rs:7:14 (example+0x868c8)
263+
...
264+
#11 main <null> (example+0x86a1a)
265+
266+
Location is global 'example::A::h43ac149ddf992709' of size 8 at 0x5632dfe3d030 (example+0x000000bd9030)
267+
```
208268
209269
# Instrumentation of external dependencies and std
210270
@@ -231,6 +291,10 @@ In more practical terms when using cargo always remember to pass `--target`
231291
flag, so that rustflags will not be applied to build scripts and procedural
232292
macros.
233293
294+
# Symbolizing the Reports
295+
296+
Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PATH`.
297+
234298
# Additional Information
235299
236300
* [Sanitizers project page](https://github.com/google/sanitizers/wiki/)

0 commit comments

Comments
 (0)