Skip to content

Commit 6b2df46

Browse files
authored
Rollup merge of rust-lang#70938 - tmiasko:thread-test-case, r=hanna-kruppe
Add ThreadSanitizer test case
2 parents 1fe86f4 + 688697d commit 6b2df46

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/test/ui/sanitize/thread.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Verifies that ThreadSanitizer is able to detect a data race in heap allocated
2+
// memory block.
3+
//
4+
// Test case minimizes the use of the standard library to avoid its ambiguous
5+
// status with respect to instrumentation (it could vary depending on whatever
6+
// a function call is inlined or not).
7+
//
8+
// The conflicting data access is de-facto synchronized with a special TSAN
9+
// barrier, which does not introduce synchronization from TSAN perspective, but
10+
// is necessary to make the test robust. Without the barrier data race detection
11+
// would occasionally fail, making test flaky.
12+
//
13+
// needs-sanitizer-support
14+
// only-x86_64
15+
//
16+
// compile-flags: -Z sanitizer=thread -O
17+
//
18+
// run-fail
19+
// error-pattern: WARNING: ThreadSanitizer: data race
20+
// error-pattern: Location is heap block of size 4
21+
// error-pattern: allocated by main thread
22+
23+
#![feature(raw_ref_op)]
24+
#![feature(rustc_private)]
25+
extern crate libc;
26+
27+
use std::mem;
28+
use std::ptr;
29+
30+
static mut BARRIER: u64 = 0;
31+
32+
extern "C" {
33+
fn __tsan_testonly_barrier_init(barrier: *mut u64, count: u32);
34+
fn __tsan_testonly_barrier_wait(barrier: *mut u64);
35+
}
36+
37+
extern "C" fn start(c: *mut libc::c_void) -> *mut libc::c_void {
38+
unsafe {
39+
let c: *mut u32 = c.cast();
40+
*c += 1;
41+
__tsan_testonly_barrier_wait(&raw mut BARRIER);
42+
ptr::null_mut()
43+
}
44+
}
45+
46+
fn main() {
47+
unsafe {
48+
__tsan_testonly_barrier_init(&raw mut BARRIER, 2);
49+
let c: *mut u32 = Box::into_raw(Box::new(1));
50+
let mut t: libc::pthread_t = mem::zeroed();
51+
libc::pthread_create(&mut t, ptr::null(), start, c.cast());
52+
__tsan_testonly_barrier_wait(&raw mut BARRIER);
53+
*c += 1;
54+
libc::pthread_join(t, ptr::null_mut());
55+
Box::from_raw(c);
56+
}
57+
}

0 commit comments

Comments
 (0)