From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/sanitize/thread.rs | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/test/ui/sanitize/thread.rs (limited to 'src/test/ui/sanitize/thread.rs') diff --git a/src/test/ui/sanitize/thread.rs b/src/test/ui/sanitize/thread.rs new file mode 100644 index 000000000..c70cf5acc --- /dev/null +++ b/src/test/ui/sanitize/thread.rs @@ -0,0 +1,57 @@ +// Verifies that ThreadSanitizer is able to detect a data race in heap allocated +// memory block. +// +// Test case minimizes the use of the standard library to avoid its ambiguous +// status with respect to instrumentation (it could vary depending on whatever +// a function call is inlined or not). +// +// The conflicting data access is de-facto synchronized with a special TSAN +// barrier, which does not introduce synchronization from TSAN perspective, but +// is necessary to make the test robust. Without the barrier data race detection +// would occasionally fail, making test flaky. +// +// needs-sanitizer-support +// needs-sanitizer-thread +// +// compile-flags: -Z sanitizer=thread -O +// +// run-fail +// error-pattern: WARNING: ThreadSanitizer: data race +// error-pattern: Location is heap block of size 4 +// error-pattern: allocated by main thread + +#![feature(raw_ref_op)] +#![feature(rustc_private)] +extern crate libc; + +use std::mem; +use std::ptr; + +static mut BARRIER: u64 = 0; + +extern "C" { + fn __tsan_testonly_barrier_init(barrier: *mut u64, count: u32); + fn __tsan_testonly_barrier_wait(barrier: *mut u64); +} + +extern "C" fn start(c: *mut libc::c_void) -> *mut libc::c_void { + unsafe { + let c: *mut u32 = c.cast(); + *c += 1; + __tsan_testonly_barrier_wait(&raw mut BARRIER); + ptr::null_mut() + } +} + +fn main() { + unsafe { + __tsan_testonly_barrier_init(&raw mut BARRIER, 2); + let c: *mut u32 = Box::into_raw(Box::new(1)); + let mut t: libc::pthread_t = mem::zeroed(); + libc::pthread_create(&mut t, ptr::null(), start, c.cast()); + __tsan_testonly_barrier_wait(&raw mut BARRIER); + *c += 1; + libc::pthread_join(t, ptr::null_mut()); + Box::from_raw(c); + } +} -- cgit v1.2.3