rust-san
How-to: Sanitize your Rust code!
Intro
As of nightly-2017-02-15,
rustc
ships with experimental support for the following sanitizers:
Note that sanitizer support is available on x86_64 Linux and on x86_64 macOS (ASan and TSan only).
How to use the sanitizers?
You have to compile your crate and all its dependencies with the -Z sanitizer
flag. Setting RUSTFLAGS
does the trick:
# if you have a binary crate (an application) or want to sanitize an example, use `cargo run`
$ RUSTFLAGS="-Z sanitizer=$SAN" cargo run --target x86_64-unknown-linux-gnu
# if you have a library crate, use `cargo test` to sanitize your unit tests
$ RUSTFLAGS="-Z sanitizer=$SAN" cargo test --target x86_64-unknown-linux-gnu
Where $SAN
is one of address
, leak
, memory
or thread
.
Be sure to always pass --target x86_64-unknown-linux-gnu
to Cargo or else
you'll end up sanitizing the build scripts that Cargo runs or run into
compilation error if your crate depends on a dylib.
Examples
This section shows what kind of issues can be detected with the sanitizers through some examples that you can find in this repository
AddressSanitizer
This sanitizer can detect, among other things, out of bounds accesses and uses of freed memory.
Out of bounds access
asan/examples/out-of-bounds.rs
fn main() {
let xs = [0, 1, 2, 3];
let y = unsafe { *xs.as_ptr().offset(4) };
}
$ ( cd asan && \
RUSTFLAGS="-Z sanitizer=address" cargo run --target x86_64-unknown-linux-gnu --example out-of-bounds )
Running `target/x86_64-unknown-linux-gnu/debug/examples/out-of-bounds`
=================================================================
==821==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe9808e5f0 at pc 0x56500e096f7e bp 0x7ffe9808e5b0 sp 0x7ffe9808e5a8
READ of size 4 at 0x7ffe9808e5f0 thread T0
#0 0x56500e096f7d in out_of_bounds::main::h86e0ef2cff62a67d $PWD/examples/out-of-bounds.rs:3
#1 0x56500e18b536 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/out-of-bounds+0xfe536)
#2 0x56500e183ee9 in std::rt::lang_start::h6954771f55df116b ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/out-of-bounds+0xf6ee9)
#3 0x56500e097002 in main ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/out-of-bounds+0xa002)
#4 0x7f9e21a46290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#5 0x56500e096719 in _start ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/out-of-bounds+0x9719)
Address 0x7ffe9808e5f0 is located in stack of thread T0 at offset 48 in frame
#0 0x56500e096d5f in out_of_bounds::main::h86e0ef2cff62a67d $PWD/examples/out-of-bounds.rs:1
This frame has 1 object(s):
[32, 48) 'xs' <== Memory access at offset 48 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow $PWD/examples/out-of-bounds.rs:3 in out_of_bounds::main::h86e0ef2cff62a67d
Shadow bytes around the buggy address:
0x100053009c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100053009cb0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3
0x100053009cc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100053009d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==821==ABORTING
Use after free
asan/examples/use-after-free.rs
fn main() {
let xs = vec![0, 1, 2, 3];
let y = xs.as_ptr();
drop(xs);
let z = unsafe { *y };
}
$ ( cd asan && \
RUSTFLAGS="-Z sanitizer=address" cargo run --target x86_64-unknown-linux-gnu --example use-after-free )
Running `target/x86_64-unknown-linux-gnu/debug/examples/use-after-free`
=================================================================
==8768==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200000efb0 at pc 0x55b0dfb2da24 bp 0x7ffccf297230 sp 0x7ffccf297228
READ of size 4 at 0x60200000efb0 thread T0
#0 0x55b0dfb2da23 in use_after_free::main::hd24e5b31a91cd260 $PWD/examples/use-after-free.rs:5
#1 0x55b0dfc22046 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0x103046)
#2 0x55b0dfc1a9f9 in std::rt::lang_start::h6954771f55df116b ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0xfb9f9)
#3 0x55b0dfb2db12 in main ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0xeb12)
#4 0x7fb186053290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#5 0x55b0dfb28869 in _start ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0x9869)
0x60200000efb0 is located 0 bytes inside of 16-byte region [0x60200000efb0,0x60200000efc0)
freed by thread T0 here:
#0 0x55b0dfbe0290 in __interceptor_cfree.localalias.0 $RUST_SRC/src/compiler-rt/lib/asan/asan_malloc_linux.cc:54
#1 0x55b0dfb2c05c in alloc::heap::deallocate::hfc4464969f6c2d6d $RUST_SRC/src/liballoc/heap.rs:113
#2 0x55b0dfb2d584 in _$LT$alloc..raw_vec..RawVec$LT$T$GT$$u20$as$u20$core..ops..Drop$GT$::drop::h379e52d625f89e1f $RUST_SRC/src/liballoc/raw_vec.rs:551
#3 0x55b0dfb2b780 in drop::h7608d0590516eb20 ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0xc780)
#4 0x55b0dfb29988 in drop_contents::ha8e051e1000be907 ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0xa988)
#5 0x55b0dfb2b7e6 in drop::ha8e051e1000be907 ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0xc7e6)
#6 0x55b0dfb2ac38 in core::mem::drop::h1c3f8290e9a15dc0 $RUST_SRC/src/libcore/mem.rs:614
#7 0x55b0dfb2d9e3 in use_after_free::main::hd24e5b31a91cd260 $PWD/examples/use-after-free.rs:4
#8 0x55b0dfc22046 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0x103046)
previously allocated by thread T0 here:
#0 0x55b0dfbe0448 in malloc $RUST_SRC/src/compiler-rt/lib/asan/asan_malloc_linux.cc:64
#1 0x55b0dfb2d0af in alloc::heap::allocate::hada3930d4dfed51a $RUST_SRC/src/liballoc/heap.rs:59
#2 0x55b0dfb2c0b0 in alloc::heap::exchange_malloc::h1ae17faa3583b58c $RUST_SRC/src/liballoc/heap.rs:138
#3 0x55b0dfb2d816 in use_after_free::main::hd24e5b31a91cd260 $PWD/examples/use-after-free.rs:2
#4 0x55b0dfc22046 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/use-after-free+0x103046)
SUMMARY: AddressSanitizer: heap-use-after-free $PWD/examples/use-after-free.rs:5 in use_after_free::main::hd24e5b31a91cd260
Shadow bytes around the buggy address:
0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9df0: fa fa fa fa fa fa[fd]fd fa fa 05 fa fa fa fd fa
0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==8768==ABORTING
LeakSanitizer
This sanitizer can detect memory leaks.
Memory leak
lsan/examples/memory-leak.rs
use std::mem;
fn main() {
let xs = vec![0, 1, 2, 3];
mem::forget(xs);
}
$ ( cd lsan && \
RUSTFLAGS="-Z sanitizer=leak" cargo run --target x86_64-unknown-linux-gnu --example memory-leak )
Running `target/x86_64-unknown-linux-gnu/debug/examples/memory-leak`
=================================================================
==16341==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x56322c0acb1f in __interceptor_malloc $RUST_SRC/src/compiler-rt/lib/lsan/lsan_interceptors.cc:55
#1 0x56322c0a7aaa in alloc::heap::exchange_malloc::h1ae17faa3583b58c $RUST_SRC/src/liballoc/heap.rs:138
#2 0x56322c0a7afc in memory_leak::main::h0003a08cbe34b70c $PWD/examples/memory-leak.rs:4
#3 0x56322c0df896 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/memory-leak+0x3d896)
SUMMARY: LeakSanitizer: 16 byte(s) leaked in 1 allocation(s).
Rc cycle
lsan/examples/rc-cycle.rs
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Clone)]
struct Cycle {
cell: RefCell<Option<Rc<Cycle>>>,
}
impl Drop for Cycle {
fn drop(&mut self) {
println!("freed");
}
}
fn main() {
let cycle = Rc::new(Cycle { cell: RefCell::new(None)});
*cycle.cell.borrow_mut() = Some(cycle.clone());
}
$ ( cd lsan && \
RUSTFLAGS="-Z sanitizer=leak" cargo run --target x86_64-unknown-linux-gnu --example rc-cycle )
Finished dev [optimized + debuginfo] target(s) in 0.0 secs
Running `target/x86_64-unknown-linux-gnu/debug/examples/rc-cycle`
=================================================================
==16344==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x556812c577ca in __interceptor_malloc $RUST_SRC/src/compiler-rt/lib/lsan/lsan_interceptors.cc:55
#1 0x556812c52c3a in alloc::heap::exchange_malloc::h55adee8e9fba9338 $RUST_SRC/src/liballoc/heap.rs:138
#2 0x556812c5254e in _$LT$alloc..rc..Rc$LT$T$GT$$GT$::new::h63d403f2e66d1e71 $RUST_SRC/src/liballoc/rc.rs:293
#3 0x556812c52d44 in rc_cycle::main::hee2857f96ac2db92 $PWD/examples/rc-cycle.rs:16
#4 0x556812c8614a in __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98
#5 0x556812c7ed06 in std::panicking::try<(),fn()> $RUST_SRC/src/libstd/panicking.rs:436
#6 0x556812c7ed06 in std::panic::catch_unwind<fn(),()> $RUST_SRC/src/libstd/panic.rs:361
#7 0x556812c7ed06 in std::rt::lang_start::hb7fc7ec87b663023 $RUST_SRC/src/libstd/rt.rs:57
#8 0x7f9a53e0f290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
SUMMARY: LeakSanitizer: 32 byte(s) leaked in 1 allocation(s).
MemorySanitizer
This sanitizer can detect reads of uninitialized memory.
Uninitialized read
msan/examples/uninitialized-read.rs
use std::mem;
fn main() {
let xs: [u8; 4] = unsafe { mem::uninitialized() };
let y = xs[0] + xs[1];
}
$ ( cd msan && \
RUSTFLAGS="-Z sanitizer=memory" cargo run --target x86_64-unknown-linux-gnu --example uninitialized-read )
Running `target/x86_64-unknown-linux-gnu/debug/examples/uninitialized-read`
==21418==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x56107230e7da in uninitialized_read::main::h0c073cea3836efc1 $PWD/examples/uninitialized-read.rs:5
#1 0x56107238b446 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/uninitialized-read+0x87446)
#2 0x561072383df9 in std::rt::lang_start::h6954771f55df116b ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/uninitialized-read+0x7fdf9)
#3 0x56107230e8a9 in main ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/uninitialized-read+0xa8a9)
#4 0x7f32de0b7290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#5 0x56107230e4f9 in _start ($PWD/target/x86_64-unknown-linux-gnu/debug/examples/uninitialized-read+0xa4f9)
SUMMARY: MemorySanitizer: use-of-uninitialized-value $PWD/examples/uninitialized-read.rs:5 in uninitialized_read::main::h0c073cea3836efc1
Exiting
ThreadSanitizer
This sanitizer can detect data races.
Data race
tsan/examples/data-race.rs
use std::thread;
static mut ANSWER: i32 = 0;
fn main() {
let t1 = thread::spawn(|| unsafe { ANSWER = 42 });
unsafe {
ANSWER = 24;
}
t1.join().ok();
}
$ ( cd tsan && \
RUSTFLAGS="-Z sanitizer=thread" cargo run --target x86_64-unknown-linux-gnu --example data-race )
Running `target/x86_64-unknown-linux-gnu/debug/examples/data-race`
==================
WARNING: ThreadSanitizer: data race (pid=26481)
Write of size 4 at 0x55662b8b2bb4 by thread T1:
#0 data_race::main::_$u7b$$u7b$closure$u7d$$u7d$::hee96c0dbd110538f $PWD/examples/data-race.rs:6 (data-race+0x000000010e3f)
#1 _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h325b4408e33222b1 $RUST_SRC/src/libstd/panic.rs:296 (data-race+0x000000010cc5)
#2 std::panicking::try::do_call::hce66d861a72cf7ad $RUST_SRC/src/libstd/panicking.rs:460 (data-race+0x00000000c942)
#3 __rust_maybe_catch_panic <null> (data-race+0x0000000b4ee6)
#4 std::panic::catch_unwind::h8bcbba7f3956edf8 $RUST_SRC/src/libstd/panic.rs:361 (data-race+0x00000000b567)
#5 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::h59119aee2f2d06bf $RUST_SRC/src/libstd/thread/mod.rs:357 (data-race+0x00000000c276)
#6 _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::hd916ceba2ff03dbf $RUST_SRC/src/liballoc/boxed.rs:614 (data-race+0x00000000f2ce)
#7 std::sys::imp::thread::Thread::new::thread_start::h6a0d1a011a706f06 <null> (data-race+0x0000000abdd0)
Previous write of size 4 at 0x55662b8b2bb4 by main thread:
#0 data_race::main::h14a8ec63b6689873 $PWD/examples/data-race.rs:8 (data-race+0x000000010d7c)
#1 __rust_maybe_catch_panic <null> (data-race+0x0000000b4ee6)
#2 __libc_start_main <null> (libc.so.6+0x000000020290)
Location is global 'data_race::ANSWER::hcde8cae2a80d1e5d' of size 4 at 0x55662b8b2bb4 (data-race+0x0000002f8bb4)
Thread T1 (tid=26574, running) created by main thread at:
#0 pthread_create $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (data-race+0x00000001aedb)
#1 std::sys::imp::thread::Thread::new::h1a8b710ff34ac90e <null> (data-race+0x0000000aba3e)
#2 std::thread::spawn::hef27947e8b208e27 $RUST_SRC/src/libstd/thread/mod.rs:412 (data-race+0x00000000b5fa)
#3 data_race::main::h14a8ec63b6689873 $PWD/examples/data-race.rs:6 (data-race+0x000000010d5c)
#4 __rust_maybe_catch_panic <null> (data-race+0x0000000b4ee6)
#5 __libc_start_main <null> (libc.so.6+0x000000020290)
SUMMARY: ThreadSanitizer: data race $PWD/examples/data-race.rs:6 in data_race::main::_$u7b$$u7b$closure$u7d$$u7d$::hee96c0dbd110538f
==================
ThreadSanitizer: reported 1 warnings
Better backtraces
You can get even more complete backtraces if you recompile the std
facade with
-Z sanitizer
. To do that, you can use Xargo:
# install Xargo and its dependency, the rust-src component
$ cargo install xargo
$ rustup component add rust-src
# add this file to the root of your Cargo project
$ edit Xargo.toml && cat $_
[dependencies.std]
features = ["panic-unwind", "asan", "lsan", "msan", "tsan"]
# if using `cargo test`
[dependencies.test]
stage = 1
# Xargo has to rebuild the sanitizer runtimes and that requires `llvm-config`
# (in a future Xargo version, this will not be necessary)
$ export LLVM_CONFIG=$(which llvm-config)
# then you can `xargo test` or `xargo run`
$ RUSTFLAGS="-Z sanitizer=address" xargo test --target x86_64-unknown-linux-gnu
To make the above command work, you'll likely have to modify your rust-src
component, which should be in (rustc --print sysroot)/lib/rustlib/src/rust
,
like this:
diff --git a/src/libgetopts/Cargo.toml b/src/libgetopts/Cargo.toml
index 99e3b89285..07593229af 100644
--- a/src/libgetopts/Cargo.toml
+++ b/src/libgetopts/Cargo.toml
@@ -6,4 +6,4 @@ version = "0.0.0"
[lib]
name = "getopts"
path = "lib.rs"
-crate-type = ["dylib", "rlib"]
+# crate-type = ["dylib", "rlib"]
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 8146e7fb1e..c013995255 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -7,7 +7,7 @@ build = "build.rs"
[lib]
name = "std"
path = "lib.rs"
-crate-type = ["dylib", "rlib"]
+# crate-type = ["dylib", "rlib"]
[dependencies]
alloc = { path = "../liballoc" }
diff --git a/src/libterm/Cargo.toml b/src/libterm/Cargo.toml
index 8021e814c0..6891e0b912 100644
--- a/src/libterm/Cargo.toml
+++ b/src/libterm/Cargo.toml
@@ -6,4 +6,4 @@ version = "0.0.0"
[lib]
name = "term"
path = "lib.rs"
-crate-type = ["dylib", "rlib"]
+# crate-type = ["dylib", "rlib"]
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index ecbd5a9c0f..553150cdd1 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.0.0"
[lib]
name = "test"
path = "lib.rs"
-crate-type = ["dylib", "rlib"]
+# crate-type = ["dylib", "rlib"]
[dependencies]
getopts = { path = "../libgetopts" }
Caveats / known bugs
Unrealiable LeakSanitizer
I have found that LeakSanitizer not always catches memory leaks unless you
have compiled your code with -C opt-level=1
or better. You can change the
optimization level of the dev
profile in your Cargo.toml
like this:
# Cargo.toml
[profile.dev]
opt-level = 1
CARGO_INCREMENTAL
If you have set CARGO_INCREMENTAL=1
in your environment to use / test
incremental compilation then you'll have to remove it as incremental compilation
breaks sanitizer support.
MemorySanitizer: Use of uninitialized value in the test runner
This effectively means you can't really cargo test
your crate with
MemorySanitizer as you'll always get errors.
src/lib.rs
#[test]
fn foo() {}
$ RUSTFLAGS="-Z sanitizer=memory" cargo test --target x86_64-unknown-linux-gnu
Running target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235
Uninitialized bytes in __interceptor_memchr at offset 13 inside [0x70400000ef60, 23)
==6915==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x55aec536a8b5 in std::ffi::c_str::CString::_new::h1600b539eb5d8b8c ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xc58b5)
#1 0x55aec537399a in std::sys::imp::fs::stat::h72120555244bec39 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xce99a)
#2 0x55aec5355b18 in std::fs::metadata::h4ae9b0fd118f3836 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb0b18)
#3 0x55aec535bea8 in term::terminfo::searcher::get_dbpath_for_term::hc53288f466988180 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb6ea8)
#4 0x55aec535b3f1 in term::terminfo::TermInfo::from_name::hb95f189f4c99eccf ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb63f1)
#5 0x55aec535b1a2 in term::terminfo::TermInfo::from_env::h45b8e5476a2a09d7 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb61a2)
#6 0x55aec5365c70 in term::stdout::h84d7912730b73cf4 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xc0c70)
#7 0x55aec52d28bd in _$LT$test..ConsoleTestState$LT$T$GT$$GT$::new::h937954646ef1f1d9 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2d8bd)
#8 0x55aec52d481a in test::run_tests_console::h7b41f829f623d5c0 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2f81a)
#9 0x55aec52cfdb8 in test::test_main::hae140f91361b0544 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2adb8)
#10 0x55aec52d06ce in test::test_main_static::h9b2aae5d6f64eac6 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2b6ce)
#11 0x55aec52be9a3 in test_runner::__test::main::h164d7dfa966cbb3f $PWD/src/lib.rs:1
#12 0x55aec537d5d6 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xd85d6)
#13 0x55aec5376bc9 in std::rt::lang_start::h6954771f55df116b ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xd1bc9)
#14 0x55aec52bea19 in main ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x19a19)
#15 0x7fc24cf2f290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#16 0x55aec52be839 in _start ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x19839)
SUMMARY: MemorySanitizer: use-of-uninitialized-value ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xc58b5) in std::ffi::c_str::CString::_new::h1600b539eb5d8b8c
Exiting
error: test failed
ThreadSanitizer: Data race in the test runner
Using ThreadSanitizer to test any library crate with more that one unit test results in data race reports unrelated to the tests themselves.
src/lib.rs
#[test]
fn foo() {}
#[test]
fn bar() {}
$ RUSTFLAGS="-Z sanitizer=thread" cargo test --target x86_64-unknown-linux-gnu
Running target/x86_64-unknown-linux-gnu/debug/deps/foo-aacd724200d968b7
running 2 tests
==================
WARNING: ThreadSanitizer: data race (pid=3733)
Read of size 8 at 0x7c7800006f28 by main thread:
#0 memcpy $RUST_SRC/src/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:598 (foo-aacd724200d968b7+0x000000056009)
#1 memcpy $RUST_SRC/src/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:590 (foo-aacd724200d968b7+0x000000056009)
#2 core::mem::swap<core::option::Option<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)>> $RUST_SRC/src/libcore/mem.rs:454 (foo-aacd724200d968b7+0x00000001adfe)
#3 core::mem::replace<core::option::Option<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)>> $RUST_SRC/src/libcore/mem.rs:518 (foo-aacd724200d968b7+0x00000001adfe)
#4 core::option::{{impl}}::take<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libcore/option.rs:725 (foo-aacd724200d968b7+0x00000001adfe)
#5 _$LT$std..sync..mpsc..mpsc_queue..Queue$LT$T$GT$$GT$::pop::hd044437806ca7d86 $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:126 (foo-aacd724200d968b7+0x00000001adfe)
#6 __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98 (foo-aacd724200d968b7+0x0000000d8b0a)
#7 __libc_start_main <null> (libc.so.6+0x000000020290)
Previous write of size 8 at 0x7c7800006f28 by thread T1:
#0 malloc $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:591 (foo-aacd724200d968b7+0x000000061e1f)
#1 alloc::heap::allocate $RUST_SRC/src/liballoc/heap.rs:59 (foo-aacd724200d968b7+0x000000014bb2)
#2 alloc::heap::exchange_malloc $RUST_SRC/src/liballoc/heap.rs:138 (foo-aacd724200d968b7+0x000000014bb2)
#3 std::sync::mpsc::mpsc_queue::{{impl}}::new<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:80 (foo-aacd724200d968b7+0x000000014bb2)
#4 std::sync::mpsc::mpsc_queue::{{impl}}::push<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:101 (foo-aacd724200d968b7+0x000000014bb2)
#5 std::sync::mpsc::shared::{{impl}}::send<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/shared.rs:171 (foo-aacd724200d968b7+0x000000014bb2)
#6 _$LT$std..sync..mpsc..Sender$LT$T$GT$$GT$::send::h1f83562f10dffde2 $RUST_SRC/src/libstd/sync/mpsc/mod.rs:607 (foo-aacd724200d968b7+0x000000014bb2)
Location is heap block of size 224 at 0x7c7800006f20 allocated by thread T1:
#0 malloc $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:591 (foo-aacd724200d968b7+0x000000061e1f)
#1 alloc::heap::allocate $RUST_SRC/src/liballoc/heap.rs:59 (foo-aacd724200d968b7+0x000000014bb2)
#2 alloc::heap::exchange_malloc $RUST_SRC/src/liballoc/heap.rs:138 (foo-aacd724200d968b7+0x000000014bb2)
#3 std::sync::mpsc::mpsc_queue::{{impl}}::new<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:80 (foo-aacd724200d968b7+0x000000014bb2)
#4 std::sync::mpsc::mpsc_queue::{{impl}}::push<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:101 (foo-aacd724200d968b7+0x000000014bb2)
#5 std::sync::mpsc::shared::{{impl}}::send<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/shared.rs:171 (foo-aacd724200d968b7+0x000000014bb2)
#6 _$LT$std..sync..mpsc..Sender$LT$T$GT$$GT$::send::h1f83562f10dffde2 $RUST_SRC/src/libstd/sync/mpsc/mod.rs:607 (foo-aacd724200d968b7+0x000000014bb2)
Thread T1 'bar' (tid=3735, finished) created by main thread at:
#0 pthread_create $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (foo-aacd724200d968b7+0x00000003b9a7)
#1 std::sys::imp::thread::Thread::new::h13e24a45e97a3e79 $RUST_SRC/src/libstd/sys/unix/thread.rs:72 (foo-aacd724200d968b7+0x0000000d0765)
#2 __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98 (foo-aacd724200d968b7+0x0000000d8b0a)
#3 __libc_start_main <null> (libc.so.6+0x000000020290)
SUMMARY: ThreadSanitizer: data race $RUST_SRC/src/libcore/mem.rs:454 in core::mem::swap<core::option::Option<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)>>
==================
test bar ... ok
==================
WARNING: ThreadSanitizer: data race (pid=3733)
Write of size 8 at 0x7c7800006f20 by main thread:
#0 free $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:634 (foo-aacd724200d968b7+0x00000003cf06)
#1 free $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:628 (foo-aacd724200d968b7+0x00000003cf06)
#2 _$LT$std..sync..mpsc..mpsc_queue..Queue$LT$T$GT$$GT$::pop::hd044437806ca7d86 $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:127 (foo-aacd724200d968b7+0x00000001ae56)
#3 __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98 (foo-aacd724200d968b7+0x0000000d8b0a)
#4 __libc_start_main <null> (libc.so.6+0x000000020290)
Previous write of size 8 at 0x7c7800006f20 by thread T1:
#0 malloc $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:591 (foo-aacd724200d968b7+0x000000061e1f)
#1 alloc::heap::allocate $RUST_SRC/src/liballoc/heap.rs:59 (foo-aacd724200d968b7+0x000000014bb2)
#2 alloc::heap::exchange_malloc $RUST_SRC/src/liballoc/heap.rs:138 (foo-aacd724200d968b7+0x000000014bb2)
#3 std::sync::mpsc::mpsc_queue::{{impl}}::new<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:80 (foo-aacd724200d968b7+0x000000014bb2)
#4 std::sync::mpsc::mpsc_queue::{{impl}}::push<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:101 (foo-aacd724200d968b7+0x000000014bb2)
#5 std::sync::mpsc::shared::{{impl}}::send<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/shared.rs:171 (foo-aacd724200d968b7+0x000000014bb2)
#6 _$LT$std..sync..mpsc..Sender$LT$T$GT$$GT$::send::h1f83562f10dffde2 $RUST_SRC/src/libstd/sync/mpsc/mod.rs:607 (foo-aacd724200d968b7+0x000000014bb2)
Thread T1 'bar' (tid=3735, finished) created by main thread at:
#0 pthread_create $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (foo-aacd724200d968b7+0x00000003b9a7)
#1 std::sys::imp::thread::Thread::new::h13e24a45e97a3e79 $RUST_SRC/src/libstd/sys/unix/thread.rs:72 (foo-aacd724200d968b7+0x0000000d0765)
#2 __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98 (foo-aacd724200d968b7+0x0000000d8b0a)
#3 __libc_start_main <null> (libc.so.6+0x000000020290)
SUMMARY: ThreadSanitizer: data race $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:127 in _$LT$std..sync..mpsc..mpsc_queue..Queue$LT$T$GT$$GT$::pop::hd044437806ca7d86
==================
test foo ... ok
==================
WARNING: ThreadSanitizer: data race (pid=3733)
Write of size 8 at 0x7c7800006e40 by main thread:
#0 free $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:634 (foo-aacd724200d968b7+0x00000003cf06)
#1 free $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:628 (foo-aacd724200d968b7+0x00000003cf06)
#2 drop::hf0d57a221ac19123 <null> (foo-aacd724200d968b7+0x000000019fb1)
#3 __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98 (foo-aacd724200d968b7+0x0000000d8b0a)
#4 __libc_start_main <null> (libc.so.6+0x000000020290)
Previous write of size 8 at 0x7c7800006e40 by thread T2:
#0 malloc $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:591 (foo-aacd724200d968b7+0x000000061e1f)
#1 alloc::heap::allocate $RUST_SRC/src/liballoc/heap.rs:59 (foo-aacd724200d968b7+0x000000014bb2)
#2 alloc::heap::exchange_malloc $RUST_SRC/src/liballoc/heap.rs:138 (foo-aacd724200d968b7+0x000000014bb2)
#3 std::sync::mpsc::mpsc_queue::{{impl}}::new<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:80 (foo-aacd724200d968b7+0x000000014bb2)
#4 std::sync::mpsc::mpsc_queue::{{impl}}::push<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/mpsc_queue.rs:101 (foo-aacd724200d968b7+0x000000014bb2)
#5 std::sync::mpsc::shared::{{impl}}::send<(test::TestDesc, test::TestResult, collections::vec::Vec<u8>)> $RUST_SRC/src/libstd/sync/mpsc/shared.rs:171 (foo-aacd724200d968b7+0x000000014bb2)
#6 _$LT$std..sync..mpsc..Sender$LT$T$GT$$GT$::send::h1f83562f10dffde2 $RUST_SRC/src/libstd/sync/mpsc/mod.rs:607 (foo-aacd724200d968b7+0x000000014bb2)
Thread T2 'foo' (tid=3736, finished) created by main thread at:
#0 pthread_create $RUST_SRC/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (foo-aacd724200d968b7+0x00000003b9a7)
#1 std::sys::imp::thread::Thread::new::h13e24a45e97a3e79 $RUST_SRC/src/libstd/sys/unix/thread.rs:72 (foo-aacd724200d968b7+0x0000000d0765)
#2 __rust_maybe_catch_panic $RUST_SRC/src/libpanic_unwind/lib.rs:98 (foo-aacd724200d968b7+0x0000000d8b0a)
#3 __libc_start_main <null> (libc.so.6+0x000000020290)
SUMMARY: ThreadSanitizer: data race ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/foo-aacd724200d968b7+0x19fb1) in drop::hf0d57a221ac19123
==================
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
ThreadSanitizer: reported 3 warnings
error: test failed
Workaround: export RUST_TEST_THREADS=1
to run your test suite sequentially.
Suppression of False Positives
There are some cases where the sanitizers will generate false positives, such as reporting data races in code that uses std::sync::atomic::fence
, or unsafe pointer usage while relying on the ordering semantics of adjacent barriers. This can generate a ton of noise, as popular libraries like lazy_static
can trigger this.
WARNING: ThreadSanitizer: data race (pid=30975)
Read of size 8 at 0x55ddb40e5418 by thread T2:
#0 _$LT$lazy_static..lazy..Lazy$LT$T$GT$$GT$::get::hb947a249eaade5b0 /home/t/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-0.2.8/src/lazy.rs:26 (stress+0x279323)
#1 rayon_core::log::{{impl}}::deref::__stability /home/t/src/rsdb/<__lazy_static_internal macros>:20 (stress+0x2a8520)
#2 _$LT$rayon_core..log..LOG_ENV$u20$as$u20$core..ops..deref..Deref$GT$::deref::h995f5b423216fc8c /home/t/src/rsdb/<__lazy_static_internal macros>:21 (stress+0x2a8520)
#3 rayon_core::registry::WorkerThread::wait_until::h14e38df285736ca7 /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:434 (stress+0x2a0ac1)
#4 rayon_core::registry::WorkerThread::wait_until::h14e38df285736ca7 /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:434 (stress+0x2a0ac1)
#5 rayon_core::registry::main_loop::h120d26ee2b06f3e1 /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:559 (stress+0x2a2ba3)
#6 rayon_core::registry::Registry::new::_$u7b$$u7b$closure$u7d$$u7d$::h73e776a16b1aafcd /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:145 (stress+0x2a87fa)
#7 std::sys_common::backtrace::__rust_begin_short_backtrace::h70e0fa277eccaded /checkout/src/libstd/sys_common/backtrace.rs:136 (stress+0x274b63)
#8 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h73f1afe39e3f5d92 /checkout/src/libstd/thread/mod.rs:364 (stress+0x2772e9)
#9 _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h0fef211ea8e53025 /checkout/src/libstd/panic.rs:296 (stress+0x269582)
#10 std::panicking::try::do_call::h0164d0443475d14d /checkout/src/libstd/panicking.rs:479 (stress+0x277ab3)
#11 __rust_maybe_catch_panic /checkout/src/libpanic_unwind/lib.rs:98 (stress+0x30999c)
#12 std::panic::catch_unwind::h0f7a13324f48e132 /checkout/src/libstd/panic.rs:361 (stress+0x2761bb)
#13 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::h8fabb47bf4134341 /checkout/src/libstd/thread/mod.rs:363 (stress+0x277091)
#14 _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h34535139aa115aa0 /checkout/src/liballoc/boxed.rs:652 (stress+0x29081f)
#15 alloc::boxed::{{impl}}::call_once<(),()> /checkout/src/liballoc/boxed.rs:662 (stress+0x30169b)
#16 std::sys_common::thread::start_thread /checkout/src/libstd/sys_common/thread.rs:21 (stress+0x30169b)
#17 std::sys::imp::thread::Thread::new::thread_start::h3eac17b79d7b9487 /checkout/src/libstd/sys/unix/thread.rs:84 (stress+0x30169b)
Previous write of size 8 at 0x55ddb40e5418 by thread T1:
#0 _$LT$lazy_static..lazy..Lazy$LT$T$GT$$GT$::get::_$u7b$$u7b$closure$u7d$$u7d$::he4e15a492cb08e5f /home/t/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-0.2.8/src/lazy.rs:23 (stress+0x27946f)
#1 std::sync::once::Once::call_once::_$u7b$$u7b$closure$u7d$$u7d$::hecb03b941ecc49ae /checkout/src/libstd/sync/once.rs:227 (stress+0x2755f3)
#2 std::sync::once::Once::call_inner::h7a6867e4a5c8eee6 /checkout/src/libstd/sync/once.rs:307 (stress+0x2fbe2c)
#3 _$LT$lazy_static..lazy..Lazy$LT$T$GT$$GT$::get::hb947a249eaade5b0 /home/t/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-0.2.8/src/lazy.rs:22 (stress+0x27930e)
#4 rayon_core::log::{{impl}}::deref::__stability /home/t/src/rsdb/<__lazy_static_internal macros>:20 (stress+0x2a8520)
#5 _$LT$rayon_core..log..LOG_ENV$u20$as$u20$core..ops..deref..Deref$GT$::deref::h995f5b423216fc8c /home/t/src/rsdb/<__lazy_static_internal macros>:21 (stress+0x2a8520)
#6 rayon_core::registry::WorkerThread::wait_until::h14e38df285736ca7 /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:434 (stress+0x2a0ac1)
#7 rayon_core::registry::WorkerThread::wait_until::h14e38df285736ca7 /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:434 (stress+0x2a0ac1)
#8 rayon_core::registry::main_loop::h120d26ee2b06f3e1 /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:559 (stress+0x2a2ba3)
#9 rayon_core::registry::Registry::new::_$u7b$$u7b$closure$u7d$$u7d$::h73e776a16b1aafcd /home/t/src/rsdb/rayon/rayon-core/src/registry.rs:145 (stress+0x2a87fa)
#10 std::sys_common::backtrace::__rust_begin_short_backtrace::h70e0fa277eccaded /checkout/src/libstd/sys_common/backtrace.rs:136 (stress+0x274b63)
#11 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h73f1afe39e3f5d92 /checkout/src/libstd/thread/mod.rs:364 (stress+0x2772e9)
#12 _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h0fef211ea8e53025 /checkout/src/libstd/panic.rs:296 (stress+0x269582)
#13 std::panicking::try::do_call::h0164d0443475d14d /checkout/src/libstd/panicking.rs:479 (stress+0x277ab3)
#14 __rust_maybe_catch_panic /checkout/src/libpanic_unwind/lib.rs:98 (stress+0x30999c)
#15 std::panic::catch_unwind::h0f7a13324f48e132 /checkout/src/libstd/panic.rs:361 (stress+0x2761bb)
#16 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::h8fabb47bf4134341 /checkout/src/libstd/thread/mod.rs:363 (stress+0x277091)
#17 _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h34535139aa115aa0 /checkout/src/liballoc/boxed.rs:652 (stress+0x29081f)
#18 alloc::boxed::{{impl}}::call_once<(),()> /checkout/src/liballoc/boxed.rs:662 (stress+0x30169b)
#19 std::sys_common::thread::start_thread /checkout/src/libstd/sys_common/thread.rs:21 (stress+0x30169b)
#20 std::sys::imp::thread::Thread::new::thread_start::h3eac17b79d7b9487 /checkout/src/libstd/sys/unix/thread.rs:84 (stress+0x30169b)
Location is global '_$LT$rayon_core..log..LOG_ENV$u20$as$u20$core..ops..deref..Deref$GT$::deref::__stability::LAZY::h79a6f8f41963a1dd' of size 16 at 0x55ddb40e5418 (stress+0x0000013d5418)
These errors can be suppressed by setting the TSAN_OPTIONS
environment variable, and providing a suppressions configuration file:
export TSAN_OPTIONS="suppressions=blacklist.txt"
Where the configuration file looks something like this:
# Library foobar is full of races.
# Filed bug 123, but do not want to deal with it now.
race:foobar
# The function turns to be racy. Bug 345.
race:NuclearRocket::Launch
# The race is introduced in patch 456. Bug 567.
race:src/surgery/laser_scalpel.cc
# Global var global_var is racy. Bug 568.
race:global_var
# short() function is racy, but not match any other functions containing "short". Bug 569.
race:^short$
# The following thread leaks. Bug 678.
thread:MonitoringThread
# Uninstrumented library.
called_from_lib:libzmq.so
You can find additional documentation for the LLVM suppression file here.
License
Licensed under either of
-
Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.