1
Fork 0

Auto merge of #2880 - RalfJung:sync, r=RalfJung

increase timing slack for sync tests; port tests to 2021 edition
This commit is contained in:
bors 2023-05-08 11:19:01 +00:00
commit a477b81c7e
48 changed files with 115 additions and 35 deletions

View file

@ -52,7 +52,7 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
mode,
program: miri_path(),
quiet: false,
edition: Some("2018".into()),
edition: Some("2021".into()),
..Config::default()
};

View file

@ -7,8 +7,8 @@ LL | panic!()
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `thread_start` at RUSTLIB/std/src/panic.rs:LL:CC
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error

View file

@ -7,8 +7,8 @@ LL | panic!()
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `thread_start` at RUSTLIB/std/src/panic.rs:LL:CC
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error

View file

@ -26,6 +26,7 @@ pub fn main() {
// 2. write
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@ -34,6 +35,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
// Note: could also error due to reading uninitialized memory, but the data-race detector triggers first.

View file

@ -25,6 +25,7 @@ pub fn main() {
// 2. write
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@ -34,6 +35,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});

View file

@ -16,10 +16,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*(c.0 as *mut usize) = 32;
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
(&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>`
});

View file

@ -17,11 +17,13 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
atomic_ref.load(Ordering::SeqCst)
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});

View file

@ -17,11 +17,13 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
atomic_ref.store(32, Ordering::SeqCst)
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
*atomic_ref.get_mut() //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Read on thread `<unnamed>`
});

View file

@ -16,10 +16,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
let _val = *(c.0 as *mut usize);
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
(&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>`
});

View file

@ -16,10 +16,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*(c.0 as *mut usize) = 32;
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
(&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>`
});

View file

@ -17,11 +17,13 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
atomic_ref.store(64, Ordering::SeqCst);
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
let atomic_ref = &mut *c.0;
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});

View file

@ -18,6 +18,7 @@ fn main() {
let join = unsafe {
spawn(move || {
let c = c; // capture `c`, not just its field.
*c.0 = 32;
})
};
@ -34,6 +35,7 @@ fn main() {
let join2 = unsafe {
spawn(move || {
let c = c; // capture `c`, not just its field.
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
})
};

View file

@ -18,6 +18,7 @@ fn main() {
let join = unsafe {
spawn(move || {
let c = c; // avoid field capturing
*c.0 = 32;
})
};

View file

@ -20,10 +20,12 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
let _val = *ptr.0;
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
__rust_dealloc(
//~^ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
ptr.0 as *mut _,

View file

@ -20,6 +20,7 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
__rust_dealloc(
ptr.0 as *mut _,
std::mem::size_of::<usize>(),
@ -28,6 +29,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
// Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Read on thread `<unnamed>`
// but the invalid allocation is detected first.
*ptr.0 //~ ERROR: dereferenced after this allocation got freed

View file

@ -26,6 +26,7 @@ pub fn main() {
// 3. stack-deallocate
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
{
let mut stack_var = 0usize;
@ -39,6 +40,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire)
});

View file

@ -19,10 +19,12 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
*ptr.0 = 2;
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
__rust_dealloc(
//~^ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
ptr.0 as *mut _,

View file

@ -19,6 +19,7 @@ pub fn main() {
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
__rust_dealloc(
ptr.0 as *mut _,
std::mem::size_of::<usize>(),
@ -27,6 +28,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
// Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Write on thread `<unnamed>`
// but the invalid allocation is detected first.
*ptr.0 = 2; //~ ERROR: dereferenced after this allocation got freed

View file

@ -26,6 +26,7 @@ pub fn main() {
// 3. stack-deallocate
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
{
let mut stack_var = 0usize;
@ -39,6 +40,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire) = 3;
});

View file

@ -26,10 +26,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 32;
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});

View file

@ -15,10 +15,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
let _val = *c.0;
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 64; //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});

View file

@ -31,6 +31,7 @@ pub fn main() {
// 5. read-value
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@ -46,6 +47,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire) = 3;
});

View file

@ -25,6 +25,7 @@ pub fn main() {
// 4. load acquire : 2
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
@ -36,6 +37,7 @@ pub fn main() {
});
let j3 = spawn(move || {
let c = c; // avoid field capturing
if SYNC.load(Ordering::Acquire) == 2 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
} else {

View file

@ -27,6 +27,7 @@ pub fn main() {
// 4. load acquire : 3
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
sleep(Duration::from_millis(200));
@ -39,6 +40,7 @@ pub fn main() {
});
let j3 = spawn(move || {
let c = c; // avoid field capturing
sleep(Duration::from_millis(500));
if SYNC.load(Ordering::Acquire) == 3 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`

View file

@ -25,6 +25,7 @@ pub fn main() {
// 3. load acquire : 2
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
@ -36,6 +37,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
if SYNC.load(Ordering::Acquire) == 2 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
} else {

View file

@ -25,6 +25,7 @@ pub fn main() {
// 4. load acquire : 3
unsafe {
let j1 = spawn(move || {
let c = c; // capture `c`, not just its field.
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
@ -37,6 +38,7 @@ pub fn main() {
});
let j3 = spawn(move || {
let c = c; // capture `c`, not just its field.
if SYNC.load(Ordering::Acquire) == 3 {
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
} else {

View file

@ -13,7 +13,7 @@ fn main() {
fn race(local: i32) {
let ptr = MakeSend(&local as *const i32);
thread::spawn(move || {
let ptr = ptr;
let ptr = ptr; // avoid field capturing
let _val = unsafe { *ptr.0 };
});
// Make the other thread go first so that it does not UAF.

View file

@ -15,10 +15,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 32;
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
});

View file

@ -28,6 +28,7 @@ pub fn main() {
// 5. write-value
unsafe {
let j1 = spawn(move || {
let ptr = ptr; // avoid field capturing
// Concurrent allocate the memory.
// Uses relaxed semantics to not generate
// a release sequence.
@ -46,6 +47,7 @@ pub fn main() {
});
let j2 = spawn(move || {
let ptr = ptr; // avoid field capturing
let pointer = &*ptr.0;
*pointer.load(Ordering::Acquire) = 3;
});

View file

@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
LL | const VOID: ! = panic!();
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/erroneous_const.rs:LL:CC
|
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: erroneous constant used
--> $DIR/erroneous_const.rs:LL:CC

View file

@ -12,7 +12,8 @@ LL | ABORT();
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
note: inside `<Foo as std::ops::Drop>::drop`
--> $DIR/double_panic.rs:LL:CC
|
@ -24,7 +25,7 @@ note: inside `main`
|
LL | }
| ^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

View file

@ -11,7 +11,7 @@ note: inside `start`
|
LL | panic!("blarg I am dead")
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

View file

@ -11,13 +11,14 @@ LL | ABORT();
= note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
note: inside `main`
--> $DIR/panic_abort1.rs:LL:CC
|
LL | std::panic!("panicking from libstd");
| ^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

View file

@ -18,7 +18,7 @@ note: inside `main`
|
LL | std::panic!("{}-panicking from libstd", 42);
| ^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

View file

@ -18,7 +18,7 @@ note: inside `main`
|
LL | core::panic!("panicking from libcore");
| ^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

View file

@ -18,7 +18,7 @@ note: inside `main`
|
LL | core::panic!("{}-panicking from libcore", 42);
| ^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

View file

@ -1,9 +1,11 @@
thread 'main' panicked at 'panicking from libstd', $DIR/panic1.rs:LL:CC
stack backtrace:
0: std::rt::begin_panic
0: std::panicking::begin_panic_handler
at RUSTLIB/std/src/panicking.rs:LL:CC
1: main
1: std::rt::panic_fmt
at RUSTLIB/core/src/panicking.rs:LL:CC
2: main
at $DIR/panic1.rs:LL:CC
2: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
3: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
at RUSTLIB/core/src/ops/function.rs:LL:CC
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

View file

@ -101,7 +101,6 @@ fn test_posix_realpath_errors() {
#[cfg(target_os = "linux")]
fn test_posix_fadvise() {
use std::convert::TryInto;
use std::io::Write;
let path = tmp().join("miri_test_libc_posix_fadvise.txt");

View file

@ -116,11 +116,13 @@ fn test_message_passing() {
#[rustfmt::skip]
let j1 = spawn(move || {
let x = x; // avoid field capturing
unsafe { *x.0 = 1 }; // -----------------------------------------+
y.store(1, Release); // ---------------------+ |
}); // | |
#[rustfmt::skip] // |synchronizes-with | happens-before
let j2 = spawn(move || { // | |
let x = x; // avoid field capturing | |
acquires_value(&y, 1); // <------------------+ |
unsafe { *x.0 } // <---------------------------------------------+
});

View file

@ -17,12 +17,14 @@ fn test_fence_sync() {
let evil_ptr = EvilSend(ptr);
let j1 = spawn(move || {
let evil_ptr = evil_ptr; // avoid field capturing
unsafe { *evil_ptr.0 = 1 };
fence(Ordering::Release);
SYNC.store(1, Ordering::Relaxed)
});
let j2 = spawn(move || {
let evil_ptr = evil_ptr; // avoid field capturing
if SYNC.load(Ordering::Relaxed) == 1 {
fence(Ordering::Acquire);
unsafe { *evil_ptr.0 }
@ -40,10 +42,10 @@ fn test_multiple_reads() {
let ptr = &mut var as *mut u32;
let evil_ptr = EvilSend(ptr);
let j1 = spawn(move || unsafe { *evil_ptr.0 });
let j2 = spawn(move || unsafe { *evil_ptr.0 });
let j3 = spawn(move || unsafe { *evil_ptr.0 });
let j4 = spawn(move || unsafe { *evil_ptr.0 });
let j1 = spawn(move || unsafe { *{ evil_ptr }.0 });
let j2 = spawn(move || unsafe { *{ evil_ptr }.0 });
let j3 = spawn(move || unsafe { *{ evil_ptr }.0 });
let j4 = spawn(move || unsafe { *{ evil_ptr }.0 });
assert_eq!(j1.join().unwrap(), 42);
assert_eq!(j2.join().unwrap(), 42);
@ -63,6 +65,7 @@ pub fn test_rmw_no_block() {
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
@ -73,7 +76,10 @@ pub fn test_rmw_no_block() {
}
});
let j3 = spawn(move || if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 });
let j3 = spawn(move || {
let c = c; // avoid field capturing
if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 }
});
j1.join().unwrap();
j2.join().unwrap();
@ -91,11 +97,15 @@ pub fn test_simple_release() {
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 1;
SYNC.store(1, Ordering::Release);
});
let j2 = spawn(move || if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 });
let j2 = spawn(move || {
let c = c; // avoid field capturing
if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 }
});
j1.join().unwrap();
assert_eq!(j2.join().unwrap(), 1); // relies on thread 2 going last

View file

@ -14,10 +14,12 @@ pub fn main() {
let c = EvilSend(b);
unsafe {
let j1 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 32;
});
let j2 = spawn(move || {
let c = c; // avoid field capturing
*c.0 = 64; // Data race (but not detected as the detector is disabled)
});

View file

@ -201,8 +201,10 @@ fn park_timeout() {
thread::park_timeout(Duration::from_millis(200));
// Normally, waiting in park/park_timeout may spuriously wake up early, but we
// know Miri's timed synchronization primitives do not do that.
assert!((200..1000).contains(&start.elapsed().as_millis()));
// We allow much longer sleeps as well since the macOS GHA runners seem very oversubscribed
// and sometimes just pause for 1 second or more.
let elapsed = start.elapsed();
assert!((200..2000).contains(&elapsed.as_millis()), "bad sleep time: {elapsed:?}");
}
fn park_unpark() {
@ -219,8 +221,10 @@ fn park_unpark() {
thread::park();
// Normally, waiting in park/park_timeout may spuriously wake up early, but we
// know Miri's timed synchronization primitives do not do that.
assert!((200..1000).contains(&start.elapsed().as_millis()));
// We allow much longer sleeps as well since the macOS GHA runners seem very oversubscribed
// and sometimes just pause for 1 second or more.
let elapsed = start.elapsed();
assert!((200..2000).contains(&elapsed.as_millis()), "bad sleep time: {elapsed:?}");
t2.join().unwrap();
}

View file

@ -42,6 +42,7 @@ fn main() {
};
thread::spawn(move || unsafe {
let ptr = ptr; // avoid field capturing
assert_eq!(*ptr.0, 5);
assert_eq!(A, 0);
assert_eq!(B, 0);

View file

@ -44,6 +44,8 @@ fn all_shared() {
// waiters
for i in 0..5 {
handles.push(thread::spawn(move || {
let condvar_ptr = condvar_ptr; // avoid field capture
let lock_ptr = lock_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
@ -71,6 +73,7 @@ fn all_shared() {
// readers
for i in 0..5 {
handles.push(thread::spawn(move || {
let lock_ptr = lock_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
@ -111,6 +114,8 @@ fn shared_sleep_and_exclusive_lock() {
let mut waiters = Vec::with_capacity(5);
for i in 0..5 {
waiters.push(thread::spawn(move || {
let lock_ptr = lock_ptr; // avoid field capture
let condvar_ptr = condvar_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}
@ -170,6 +175,8 @@ fn exclusive_sleep_and_shared_lock() {
let mut handles = Vec::with_capacity(10);
for i in 0..5 {
handles.push(thread::spawn(move || {
let lock_ptr = lock_ptr; // avoid field capture
let condvar_ptr = condvar_ptr; // avoid field capture
unsafe {
AcquireSRWLockExclusive(lock_ptr.0);
}
@ -193,6 +200,7 @@ fn exclusive_sleep_and_shared_lock() {
for i in 0..5 {
handles.push(thread::spawn(move || {
let lock_ptr = lock_ptr; // avoid field capture
unsafe {
AcquireSRWLockShared(lock_ptr.0);
}

View file

@ -66,6 +66,7 @@ fn block_until_complete() {
let init_once_ptr = SendPtr(&mut init_once);
let waiter = move || unsafe {
let init_once_ptr = init_once_ptr; // avoid field capture
let mut pending = 0;
assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE);
@ -102,6 +103,7 @@ fn retry_on_fail() {
let init_once_ptr = SendPtr(&mut init_once);
let waiter = move || unsafe {
let init_once_ptr = init_once_ptr; // avoid field capture
let mut pending = 0;
assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE);
@ -146,6 +148,8 @@ fn no_data_race_after_complete() {
let place_ptr = SendPtr(&mut place);
let reader = thread::spawn(move || unsafe {
let init_once_ptr = init_once_ptr; // avoid field capture
let place_ptr = place_ptr; // avoid field capture
let mut pending = 0;
// this doesn't block because reader only executes after `InitOnceComplete` is called

View file

@ -49,13 +49,12 @@ fn main() {
// Std panics
test(None, |_old_val| std::panic!("Hello from panic: std"));
test(None, |old_val| std::panic!(format!("Hello from panic: {:?}", old_val)));
test(None, |old_val| std::panic::panic_any(format!("Hello from panic: {:?}", old_val)));
test(None, |old_val| std::panic!("Hello from panic: {:?}", old_val));
test(None, |_old_val| std::panic!(1337));
test(None, |_old_val| std::panic::panic_any(1337));
// Core panics
test(None, |_old_val| core::panic!("Hello from panic: core"));
test(None, |old_val| core::panic!(&format!("Hello from panic: {:?}", old_val)));
test(None, |old_val| core::panic!("Hello from panic: {:?}", old_val));
// Built-in panics; also make sure the message is right.

View file

@ -11,8 +11,6 @@ thread 'main' panicked at 'Hello from panic: core', $DIR/catch_panic.rs:LL:CC
Caught panic message (&str): Hello from panic: core
thread 'main' panicked at 'Hello from panic: 5', $DIR/catch_panic.rs:LL:CC
Caught panic message (String): Hello from panic: 5
thread 'main' panicked at 'Hello from panic: 6', $DIR/catch_panic.rs:LL:CC
Caught panic message (String): Hello from panic: 6
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4', $DIR/catch_panic.rs:LL:CC
Caught panic message (String): index out of bounds: the len is 3 but the index is 4
thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:LL:CC

View file

@ -57,7 +57,7 @@ fn main() {
let t2_started_pair = t2_started_pair.clone();
let block_on_drop = BlockOnDrop::new(t1);
spawn(move || {
let _ = block_on_drop;
let _capture = block_on_drop;
let (mutex, condvar) = &*t2_started_pair;
*mutex.lock().unwrap() = true;