From 7acf80d2bb7c50c2f60807cb3f543955e7fef677 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Mar 2021 10:44:06 +0100 Subject: [PATCH 1/2] rustup; fix tests for new MIR optimization --- rust-version | 2 +- .../data_race/dealloc_read_race_stack.rs | 8 +-- .../data_race/dealloc_read_race_stack_drop.rs | 52 ------------------ .../data_race/dealloc_write_race_stack.rs | 8 +-- .../dealloc_write_race_stack_drop.rs | 53 ------------------- ...lock_read_write_deadlock_single_thread.rs} | 3 +- ...wlock_write_read_deadlock_single_thread.rs | 3 +- ...lock_write_write_deadlock_single_thread.rs | 3 +- 8 files changed, 15 insertions(+), 117 deletions(-) delete mode 100644 tests/compile-fail/data_race/dealloc_read_race_stack_drop.rs delete mode 100644 tests/compile-fail/data_race/dealloc_write_race_stack_drop.rs rename tests/compile-fail/sync/{libc_pthread_rwlock_read_write_deadlock.rs => libc_pthread_rwlock_read_write_deadlock_single_thread.rs} (77%) diff --git a/rust-version b/rust-version index 059dfeb2e6..65644e75d9 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -d2731d8e9338d8fe844e19d3fbb39617753e65f4 +09db05762b283bed62d4f92729cfee4646519833 diff --git a/tests/compile-fail/data_race/dealloc_read_race_stack.rs b/tests/compile-fail/data_race/dealloc_read_race_stack.rs index 31960fb216..281aff8631 100644 --- a/tests/compile-fail/data_race/dealloc_read_race_stack.rs +++ b/tests/compile-fail/data_race/dealloc_read_race_stack.rs @@ -1,5 +1,6 @@ // ignore-windows: Concurrency on Windows is not supported yet. -// compile-flags: -Zmiri-disable-isolation +// compile-flags: -Zmiri-disable-isolation -Zmir-opt-level=0 +// With optimizations (in particular #78360), the span becomes much worse, so we disable them. use std::thread::{spawn, sleep}; use std::ptr::null_mut; @@ -27,9 +28,6 @@ pub fn main() { // 3. stack-deallocate unsafe { let j1 = spawn(move || { - // Concurrent allocate the memory. - // Uses relaxed semantics to not generate - // a release sequence. let pointer = &*ptr.0; { let mut stack_var = 0usize; @@ -38,6 +36,8 @@ pub fn main() { sleep(Duration::from_millis(200)); + // Now `stack_var` gets deallocated. + } //~ ERROR Data race detected between Deallocate on Thread(id = 1) and Read on Thread(id = 2) }); diff --git a/tests/compile-fail/data_race/dealloc_read_race_stack_drop.rs b/tests/compile-fail/data_race/dealloc_read_race_stack_drop.rs deleted file mode 100644 index 44950a34db..0000000000 --- a/tests/compile-fail/data_race/dealloc_read_race_stack_drop.rs +++ /dev/null @@ -1,52 +0,0 @@ -// ignore-windows: Concurrency on Windows is not supported yet. -// compile-flags: -Zmiri-disable-isolation - -use std::thread::{spawn, sleep}; -use std::ptr::null_mut; -use std::sync::atomic::{Ordering, AtomicPtr}; -use std::time::Duration; - -#[derive(Copy, Clone)] -struct EvilSend(pub T); - -unsafe impl Send for EvilSend {} -unsafe impl Sync for EvilSend {} - -pub fn main() { - // Shared atomic pointer - let pointer = AtomicPtr::new(null_mut::()); - let ptr = EvilSend(&pointer as *const AtomicPtr); - - // Note: this is scheduler-dependent - // the operations need to occur in - // order, otherwise the allocation is - // not visible to the other-thread to - // detect the race: - // 1. stack-allocate - // 2. read - // 3. stack-deallocate - unsafe { - let j1 = spawn(move || { - // Concurrent allocate the memory. - // Uses relaxed semantics to not generate - // a release sequence. - let pointer = &*ptr.0; - - let mut stack_var = 0usize; - - pointer.store(&mut stack_var as *mut _, Ordering::Release); - - sleep(Duration::from_millis(200)); - - drop(stack_var); - }); //~ ERROR Data race detected between Deallocate on Thread(id = 1) and Read on Thread(id = 2) - - let j2 = spawn(move || { - let pointer = &*ptr.0; - *pointer.load(Ordering::Acquire) - }); - - j1.join().unwrap(); - j2.join().unwrap(); - } -} diff --git a/tests/compile-fail/data_race/dealloc_write_race_stack.rs b/tests/compile-fail/data_race/dealloc_write_race_stack.rs index 25dea65fe7..55aaa0c163 100644 --- a/tests/compile-fail/data_race/dealloc_write_race_stack.rs +++ b/tests/compile-fail/data_race/dealloc_write_race_stack.rs @@ -1,5 +1,6 @@ // ignore-windows: Concurrency on Windows is not supported yet. -// compile-flags: -Zmiri-disable-isolation +// compile-flags: -Zmiri-disable-isolation -Zmir-opt-level=0 +// With optimizations (in particular #78360), the span becomes much worse, so we disable them. use std::thread::{spawn, sleep}; use std::ptr::null_mut; @@ -27,9 +28,6 @@ pub fn main() { // 3. stack-deallocate unsafe { let j1 = spawn(move || { - // Concurrent allocate the memory. - // Uses relaxed semantics to not generate - // a release sequence. let pointer = &*ptr.0; { let mut stack_var = 0usize; @@ -38,6 +36,8 @@ pub fn main() { sleep(Duration::from_millis(200)); + // Now `stack_var` gets deallocated. + } //~ ERROR Data race detected between Deallocate on Thread(id = 1) and Write on Thread(id = 2) }); diff --git a/tests/compile-fail/data_race/dealloc_write_race_stack_drop.rs b/tests/compile-fail/data_race/dealloc_write_race_stack_drop.rs deleted file mode 100644 index 1d239e9eb7..0000000000 --- a/tests/compile-fail/data_race/dealloc_write_race_stack_drop.rs +++ /dev/null @@ -1,53 +0,0 @@ -// ignore-windows: Concurrency on Windows is not supported yet. -// compile-flags: -Zmiri-disable-isolation - -use std::thread::{spawn, sleep}; -use std::ptr::null_mut; -use std::sync::atomic::{Ordering, AtomicPtr}; -use std::time::Duration; - -#[derive(Copy, Clone)] -struct EvilSend(pub T); - -unsafe impl Send for EvilSend {} -unsafe impl Sync for EvilSend {} - -pub fn main() { - // Shared atomic pointer - let pointer = AtomicPtr::new(null_mut::()); - let ptr = EvilSend(&pointer as *const AtomicPtr); - - // Note: this is scheduler-dependent - // the operations need to occur in - // order, otherwise the allocation is - // not visible to the other-thread to - // detect the race: - // 1. stack-allocate - // 2. read - // 3. stack-deallocate - unsafe { - let j1 = spawn(move || { - // Concurrent allocate the memory. - // Uses relaxed semantics to not generate - // a release sequence. - let pointer = &*ptr.0; - - let mut stack_var = 0usize; - - pointer.store(&mut stack_var as *mut _, Ordering::Release); - - sleep(Duration::from_millis(200)); - - // Note: Implicit read for drop(_) races with write, would detect race with deallocate after. - drop(stack_var); //~ ERROR Data race detected between Read on Thread(id = 1) and Write on Thread(id = 2) - }); - - let j2 = spawn(move || { - let pointer = &*ptr.0; - *pointer.load(Ordering::Acquire) = 3; - }); - - j1.join().unwrap(); - j2.join().unwrap(); - } -} diff --git a/tests/compile-fail/sync/libc_pthread_rwlock_read_write_deadlock.rs b/tests/compile-fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs similarity index 77% rename from tests/compile-fail/sync/libc_pthread_rwlock_read_write_deadlock.rs rename to tests/compile-fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs index dd4707d60e..da45d062d0 100644 --- a/tests/compile-fail/sync/libc_pthread_rwlock_read_write_deadlock.rs +++ b/tests/compile-fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs @@ -1,4 +1,5 @@ // ignore-windows: No libc on Windows +// error-pattern: deadlock #![feature(rustc_private)] @@ -8,6 +9,6 @@ fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); - libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock + libc::pthread_rwlock_wrlock(rw.get()); } } diff --git a/tests/compile-fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs b/tests/compile-fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs index 1b460e7174..ee2e57a9ab 100644 --- a/tests/compile-fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs +++ b/tests/compile-fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs @@ -1,4 +1,5 @@ // ignore-windows: No libc on Windows +// error-pattern: deadlock #![feature(rustc_private)] @@ -8,6 +9,6 @@ fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); - libc::pthread_rwlock_rdlock(rw.get()); //~ ERROR: deadlock + libc::pthread_rwlock_rdlock(rw.get()); } } diff --git a/tests/compile-fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs b/tests/compile-fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs index cc327ec46b..f0404f202e 100644 --- a/tests/compile-fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs +++ b/tests/compile-fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs @@ -1,4 +1,5 @@ // ignore-windows: No libc on Windows +// error-pattern: deadlock #![feature(rustc_private)] @@ -8,6 +9,6 @@ fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); - libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock + libc::pthread_rwlock_wrlock(rw.get()); } } From 97e45e0699e2fc8397b1e2cfb55743365d749b6e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Mar 2021 11:04:35 +0100 Subject: [PATCH 2/2] make optimized-test-run a bit more like what cargo does --- ci.sh | 5 +++-- tests/compile-fail/data_race/dealloc_read_race_stack.rs | 3 +-- tests/compile-fail/data_race/dealloc_write_race_stack.rs | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ci.sh b/ci.sh index a1f4a00139..3484040119 100755 --- a/ci.sh +++ b/ci.sh @@ -24,8 +24,9 @@ function run_tests { ./miri test --locked if [ -z "${MIRI_TEST_TARGET+exists}" ]; then - # Only for host architecture: tests with MIR optimizations - MIRIFLAGS="-Z mir-opt-level=3" ./miri test --locked + # Only for host architecture: tests with optimizations (`-O` is what cargo passes, but crank MIR + # optimizations up all the way). + MIRIFLAGS="-O -Zmir-opt-level=3" ./miri test --locked fi # On Windows, there is always "python", not "python3" or "python2". diff --git a/tests/compile-fail/data_race/dealloc_read_race_stack.rs b/tests/compile-fail/data_race/dealloc_read_race_stack.rs index 281aff8631..6b573121e5 100644 --- a/tests/compile-fail/data_race/dealloc_read_race_stack.rs +++ b/tests/compile-fail/data_race/dealloc_read_race_stack.rs @@ -1,6 +1,5 @@ // ignore-windows: Concurrency on Windows is not supported yet. -// compile-flags: -Zmiri-disable-isolation -Zmir-opt-level=0 -// With optimizations (in particular #78360), the span becomes much worse, so we disable them. +// compile-flags: -Zmiri-disable-isolation use std::thread::{spawn, sleep}; use std::ptr::null_mut; diff --git a/tests/compile-fail/data_race/dealloc_write_race_stack.rs b/tests/compile-fail/data_race/dealloc_write_race_stack.rs index 55aaa0c163..34a16b00b8 100644 --- a/tests/compile-fail/data_race/dealloc_write_race_stack.rs +++ b/tests/compile-fail/data_race/dealloc_write_race_stack.rs @@ -1,6 +1,5 @@ // ignore-windows: Concurrency on Windows is not supported yet. -// compile-flags: -Zmiri-disable-isolation -Zmir-opt-level=0 -// With optimizations (in particular #78360), the span becomes much worse, so we disable them. +// compile-flags: -Zmiri-disable-isolation use std::thread::{spawn, sleep}; use std::ptr::null_mut;