Auto merge of #2646 - saethlin:data-race-spans, r=RalfJung
Data race spans Fixes https://github.com/rust-lang/miri/issues/2205 This adds output to data race errors very similar to the spans we emit for Stacked Borrows errors. For example, from our test suite: ``` help: The Atomic Load on thread `<unnamed>` is here --> tests/fail/data_race/atomic_read_na_write_race1.rs:23:13 | 23 | ... (&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between Atomic Load on thread `<unnamed>` and Write o... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: The Write on thread `<unnamed>` is here --> tests/fail/data_race/atomic_read_na_write_race1.rs:19:13 | 19 | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^``` ``` Because of https://github.com/rust-lang/miri/pull/2647 this comes without a perf regression, according to our benchmarks.
This commit is contained in:
commit
245357f619
126 changed files with 554 additions and 272 deletions
|
@ -50,8 +50,10 @@ use rustc_ast::Mutability;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{Align, Size};
|
use rustc_target::abi::{Align, Size};
|
||||||
|
|
||||||
|
use crate::diagnostics::RacingOp;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -144,8 +146,8 @@ impl ThreadClockSet {
|
||||||
/// Increment the happens-before clock at a
|
/// Increment the happens-before clock at a
|
||||||
/// known index.
|
/// known index.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn increment_clock(&mut self, index: VectorIdx) {
|
fn increment_clock(&mut self, index: VectorIdx, current_span: Span) {
|
||||||
self.clock.increment_index(index);
|
self.clock.increment_index(index, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join the happens-before clock with that of
|
/// Join the happens-before clock with that of
|
||||||
|
@ -356,13 +358,9 @@ impl MemoryCellClocks {
|
||||||
index: VectorIdx,
|
index: VectorIdx,
|
||||||
) -> Result<(), DataRace> {
|
) -> Result<(), DataRace> {
|
||||||
log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, clocks);
|
log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, clocks);
|
||||||
if self.write <= clocks.clock[self.write_index] {
|
let atomic = self.atomic_mut();
|
||||||
let atomic = self.atomic_mut();
|
atomic.read_vector.set_at_index(&clocks.clock, index);
|
||||||
atomic.read_vector.set_at_index(&clocks.clock, index);
|
if self.write <= clocks.clock[self.write_index] { Ok(()) } else { Err(DataRace) }
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(DataRace)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detect data-races with an atomic write, either with a non-atomic read or with
|
/// Detect data-races with an atomic write, either with a non-atomic read or with
|
||||||
|
@ -373,9 +371,9 @@ impl MemoryCellClocks {
|
||||||
index: VectorIdx,
|
index: VectorIdx,
|
||||||
) -> Result<(), DataRace> {
|
) -> Result<(), DataRace> {
|
||||||
log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, clocks);
|
log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, clocks);
|
||||||
|
let atomic = self.atomic_mut();
|
||||||
|
atomic.write_vector.set_at_index(&clocks.clock, index);
|
||||||
if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock {
|
if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock {
|
||||||
let atomic = self.atomic_mut();
|
|
||||||
atomic.write_vector.set_at_index(&clocks.clock, index);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(DataRace)
|
Err(DataRace)
|
||||||
|
@ -386,22 +384,22 @@ impl MemoryCellClocks {
|
||||||
/// returns true if a data-race is detected.
|
/// returns true if a data-race is detected.
|
||||||
fn read_race_detect(
|
fn read_race_detect(
|
||||||
&mut self,
|
&mut self,
|
||||||
clocks: &ThreadClockSet,
|
clocks: &mut ThreadClockSet,
|
||||||
index: VectorIdx,
|
index: VectorIdx,
|
||||||
|
current_span: Span,
|
||||||
) -> Result<(), DataRace> {
|
) -> Result<(), DataRace> {
|
||||||
log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, clocks);
|
log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, clocks);
|
||||||
|
if !current_span.is_dummy() {
|
||||||
|
clocks.clock[index].span = current_span;
|
||||||
|
}
|
||||||
if self.write <= clocks.clock[self.write_index] {
|
if self.write <= clocks.clock[self.write_index] {
|
||||||
let race_free = if let Some(atomic) = self.atomic() {
|
let race_free = if let Some(atomic) = self.atomic() {
|
||||||
atomic.write_vector <= clocks.clock
|
atomic.write_vector <= clocks.clock
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
if race_free {
|
self.read.set_at_index(&clocks.clock, index);
|
||||||
self.read.set_at_index(&clocks.clock, index);
|
if race_free { Ok(()) } else { Err(DataRace) }
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(DataRace)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Err(DataRace)
|
Err(DataRace)
|
||||||
}
|
}
|
||||||
|
@ -411,21 +409,25 @@ impl MemoryCellClocks {
|
||||||
/// returns true if a data-race is detected.
|
/// returns true if a data-race is detected.
|
||||||
fn write_race_detect(
|
fn write_race_detect(
|
||||||
&mut self,
|
&mut self,
|
||||||
clocks: &ThreadClockSet,
|
clocks: &mut ThreadClockSet,
|
||||||
index: VectorIdx,
|
index: VectorIdx,
|
||||||
write_type: WriteType,
|
write_type: WriteType,
|
||||||
|
current_span: Span,
|
||||||
) -> Result<(), DataRace> {
|
) -> Result<(), DataRace> {
|
||||||
log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, clocks);
|
log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, clocks);
|
||||||
|
if !current_span.is_dummy() {
|
||||||
|
clocks.clock[index].span = current_span;
|
||||||
|
}
|
||||||
if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock {
|
if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock {
|
||||||
let race_free = if let Some(atomic) = self.atomic() {
|
let race_free = if let Some(atomic) = self.atomic() {
|
||||||
atomic.write_vector <= clocks.clock && atomic.read_vector <= clocks.clock
|
atomic.write_vector <= clocks.clock && atomic.read_vector <= clocks.clock
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
|
self.write = clocks.clock[index];
|
||||||
|
self.write_index = index;
|
||||||
|
self.write_type = write_type;
|
||||||
if race_free {
|
if race_free {
|
||||||
self.write = clocks.clock[index];
|
|
||||||
self.write_index = index;
|
|
||||||
self.write_type = write_type;
|
|
||||||
self.read.set_zero_vector();
|
self.read.set_zero_vector();
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -621,30 +623,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
/// Update the data-race detector for an atomic fence on the current thread.
|
/// Update the data-race detector for an atomic fence on the current thread.
|
||||||
fn atomic_fence(&mut self, atomic: AtomicFenceOrd) -> InterpResult<'tcx> {
|
fn atomic_fence(&mut self, atomic: AtomicFenceOrd) -> InterpResult<'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
if let Some(data_race) = &mut this.machine.data_race {
|
if let Some(data_race) = &mut this.machine.data_race {
|
||||||
data_race.maybe_perform_sync_operation(&this.machine.threads, |index, mut clocks| {
|
data_race.maybe_perform_sync_operation(
|
||||||
log::trace!("Atomic fence on {:?} with ordering {:?}", index, atomic);
|
&this.machine.threads,
|
||||||
|
current_span,
|
||||||
|
|index, mut clocks| {
|
||||||
|
log::trace!("Atomic fence on {:?} with ordering {:?}", index, atomic);
|
||||||
|
|
||||||
// Apply data-race detection for the current fences
|
// Apply data-race detection for the current fences
|
||||||
// this treats AcqRel and SeqCst as the same as an acquire
|
// this treats AcqRel and SeqCst as the same as an acquire
|
||||||
// and release fence applied in the same timestamp.
|
// and release fence applied in the same timestamp.
|
||||||
if atomic != AtomicFenceOrd::Release {
|
if atomic != AtomicFenceOrd::Release {
|
||||||
// Either Acquire | AcqRel | SeqCst
|
// Either Acquire | AcqRel | SeqCst
|
||||||
clocks.apply_acquire_fence();
|
clocks.apply_acquire_fence();
|
||||||
}
|
}
|
||||||
if atomic != AtomicFenceOrd::Acquire {
|
if atomic != AtomicFenceOrd::Acquire {
|
||||||
// Either Release | AcqRel | SeqCst
|
// Either Release | AcqRel | SeqCst
|
||||||
clocks.apply_release_fence();
|
clocks.apply_release_fence();
|
||||||
}
|
}
|
||||||
if atomic == AtomicFenceOrd::SeqCst {
|
if atomic == AtomicFenceOrd::SeqCst {
|
||||||
data_race.last_sc_fence.borrow_mut().set_at_index(&clocks.clock, index);
|
data_race.last_sc_fence.borrow_mut().set_at_index(&clocks.clock, index);
|
||||||
clocks.fence_seqcst.join(&data_race.last_sc_fence.borrow());
|
clocks.fence_seqcst.join(&data_race.last_sc_fence.borrow());
|
||||||
clocks.write_seqcst.join(&data_race.last_sc_write.borrow());
|
clocks.write_seqcst.join(&data_race.last_sc_write.borrow());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment timestamp in case of release semantics.
|
// Increment timestamp in case of release semantics.
|
||||||
Ok(atomic != AtomicFenceOrd::Acquire)
|
Ok(atomic != AtomicFenceOrd::Acquire)
|
||||||
})
|
},
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -682,6 +689,7 @@ impl VClockAlloc {
|
||||||
thread_mgr: &ThreadManager<'_, '_>,
|
thread_mgr: &ThreadManager<'_, '_>,
|
||||||
len: Size,
|
len: Size,
|
||||||
kind: MemoryKind<MiriMemoryKind>,
|
kind: MemoryKind<MiriMemoryKind>,
|
||||||
|
current_span: Span,
|
||||||
) -> VClockAlloc {
|
) -> VClockAlloc {
|
||||||
let (alloc_timestamp, alloc_index) = match kind {
|
let (alloc_timestamp, alloc_index) = match kind {
|
||||||
// User allocated and stack memory should track allocation.
|
// User allocated and stack memory should track allocation.
|
||||||
|
@ -693,7 +701,8 @@ impl VClockAlloc {
|
||||||
)
|
)
|
||||||
| MemoryKind::Stack => {
|
| MemoryKind::Stack => {
|
||||||
let (alloc_index, clocks) = global.current_thread_state(thread_mgr);
|
let (alloc_index, clocks) = global.current_thread_state(thread_mgr);
|
||||||
let alloc_timestamp = clocks.clock[alloc_index];
|
let mut alloc_timestamp = clocks.clock[alloc_index];
|
||||||
|
alloc_timestamp.span = current_span;
|
||||||
(alloc_timestamp, alloc_index)
|
(alloc_timestamp, alloc_index)
|
||||||
}
|
}
|
||||||
// Other global memory should trace races but be allocated at the 0 timestamp.
|
// Other global memory should trace races but be allocated at the 0 timestamp.
|
||||||
|
@ -704,7 +713,7 @@ impl VClockAlloc {
|
||||||
| MiriMemoryKind::ExternStatic
|
| MiriMemoryKind::ExternStatic
|
||||||
| MiriMemoryKind::Tls,
|
| MiriMemoryKind::Tls,
|
||||||
)
|
)
|
||||||
| MemoryKind::CallerLocation => (0, VectorIdx::MAX_INDEX),
|
| MemoryKind::CallerLocation => (VTimestamp::ZERO, VectorIdx::MAX_INDEX),
|
||||||
};
|
};
|
||||||
VClockAlloc {
|
VClockAlloc {
|
||||||
alloc_ranges: RefCell::new(RangeMap::new(
|
alloc_ranges: RefCell::new(RangeMap::new(
|
||||||
|
@ -735,7 +744,7 @@ impl VClockAlloc {
|
||||||
let idx = l_remainder_slice
|
let idx = l_remainder_slice
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find_map(|(idx, &r)| if r == 0 { None } else { Some(idx) })
|
.find_map(|(idx, &r)| if r == VTimestamp::ZERO { None } else { Some(idx) })
|
||||||
.expect("Invalid VClock Invariant");
|
.expect("Invalid VClock Invariant");
|
||||||
Some(idx + r_slice.len())
|
Some(idx + r_slice.len())
|
||||||
} else {
|
} else {
|
||||||
|
@ -762,7 +771,7 @@ impl VClockAlloc {
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let (current_index, current_clocks) = global.current_thread_state(thread_mgr);
|
let (current_index, current_clocks) = global.current_thread_state(thread_mgr);
|
||||||
let write_clock;
|
let write_clock;
|
||||||
let (other_action, other_thread, _other_clock) = if range.write
|
let (other_action, other_thread, other_clock) = if range.write
|
||||||
> current_clocks.clock[range.write_index]
|
> current_clocks.clock[range.write_index]
|
||||||
{
|
{
|
||||||
// Convert the write action into the vector clock it
|
// Convert the write action into the vector clock it
|
||||||
|
@ -799,14 +808,19 @@ impl VClockAlloc {
|
||||||
let other_thread_info = global.print_thread_metadata(thread_mgr, other_thread);
|
let other_thread_info = global.print_thread_metadata(thread_mgr, other_thread);
|
||||||
|
|
||||||
// Throw the data-race detection.
|
// Throw the data-race detection.
|
||||||
throw_ub_format!(
|
Err(err_machine_stop!(TerminationInfo::DataRace {
|
||||||
"Data race detected between {} on {} and {} on {} at {:?}",
|
ptr: ptr_dbg,
|
||||||
action,
|
op1: RacingOp {
|
||||||
current_thread_info,
|
action: other_action.to_string(),
|
||||||
other_action,
|
thread_info: other_thread_info,
|
||||||
other_thread_info,
|
span: other_clock.as_slice()[other_thread.index()].span_data(),
|
||||||
ptr_dbg,
|
},
|
||||||
)
|
op2: RacingOp {
|
||||||
|
action: action.to_string(),
|
||||||
|
thread_info: current_thread_info,
|
||||||
|
span: current_clocks.clock.as_slice()[current_index.index()].span_data(),
|
||||||
|
},
|
||||||
|
}))?
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detect racing atomic read and writes (not data races)
|
/// Detect racing atomic read and writes (not data races)
|
||||||
|
@ -840,12 +854,14 @@ impl VClockAlloc {
|
||||||
range: AllocRange,
|
range: AllocRange,
|
||||||
machine: &MiriMachine<'_, '_>,
|
machine: &MiriMachine<'_, '_>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
let current_span = machine.current_span();
|
||||||
let global = machine.data_race.as_ref().unwrap();
|
let global = machine.data_race.as_ref().unwrap();
|
||||||
if global.race_detecting() {
|
if global.race_detecting() {
|
||||||
let (index, clocks) = global.current_thread_state(&machine.threads);
|
let (index, mut clocks) = global.current_thread_state_mut(&machine.threads);
|
||||||
let mut alloc_ranges = self.alloc_ranges.borrow_mut();
|
let mut alloc_ranges = self.alloc_ranges.borrow_mut();
|
||||||
for (offset, range) in alloc_ranges.iter_mut(range.start, range.size) {
|
for (offset, range) in alloc_ranges.iter_mut(range.start, range.size) {
|
||||||
if let Err(DataRace) = range.read_race_detect(&clocks, index) {
|
if let Err(DataRace) = range.read_race_detect(&mut clocks, index, current_span) {
|
||||||
|
drop(clocks);
|
||||||
// Report data-race.
|
// Report data-race.
|
||||||
return Self::report_data_race(
|
return Self::report_data_race(
|
||||||
global,
|
global,
|
||||||
|
@ -871,11 +887,15 @@ impl VClockAlloc {
|
||||||
write_type: WriteType,
|
write_type: WriteType,
|
||||||
machine: &mut MiriMachine<'_, '_>,
|
machine: &mut MiriMachine<'_, '_>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
let current_span = machine.current_span();
|
||||||
let global = machine.data_race.as_mut().unwrap();
|
let global = machine.data_race.as_mut().unwrap();
|
||||||
if global.race_detecting() {
|
if global.race_detecting() {
|
||||||
let (index, clocks) = global.current_thread_state(&machine.threads);
|
let (index, mut clocks) = global.current_thread_state_mut(&machine.threads);
|
||||||
for (offset, range) in self.alloc_ranges.get_mut().iter_mut(range.start, range.size) {
|
for (offset, range) in self.alloc_ranges.get_mut().iter_mut(range.start, range.size) {
|
||||||
if let Err(DataRace) = range.write_race_detect(&clocks, index, write_type) {
|
if let Err(DataRace) =
|
||||||
|
range.write_race_detect(&mut clocks, index, write_type, current_span)
|
||||||
|
{
|
||||||
|
drop(clocks);
|
||||||
// Report data-race
|
// Report data-race
|
||||||
return Self::report_data_race(
|
return Self::report_data_race(
|
||||||
global,
|
global,
|
||||||
|
@ -1100,9 +1120,11 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
|
||||||
size.bytes()
|
size.bytes()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
// Perform the atomic operation.
|
// Perform the atomic operation.
|
||||||
data_race.maybe_perform_sync_operation(
|
data_race.maybe_perform_sync_operation(
|
||||||
&this.machine.threads,
|
&this.machine.threads,
|
||||||
|
current_span,
|
||||||
|index, mut clocks| {
|
|index, mut clocks| {
|
||||||
for (offset, range) in
|
for (offset, range) in
|
||||||
alloc_meta.alloc_ranges.borrow_mut().iter_mut(base_offset, size)
|
alloc_meta.alloc_ranges.borrow_mut().iter_mut(base_offset, size)
|
||||||
|
@ -1303,7 +1325,12 @@ impl GlobalState {
|
||||||
// Hook for thread creation, enabled multi-threaded execution and marks
|
// Hook for thread creation, enabled multi-threaded execution and marks
|
||||||
// the current thread timestamp as happening-before the current thread.
|
// the current thread timestamp as happening-before the current thread.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn thread_created(&mut self, thread_mgr: &ThreadManager<'_, '_>, thread: ThreadId) {
|
pub fn thread_created(
|
||||||
|
&mut self,
|
||||||
|
thread_mgr: &ThreadManager<'_, '_>,
|
||||||
|
thread: ThreadId,
|
||||||
|
current_span: Span,
|
||||||
|
) {
|
||||||
let current_index = self.current_index(thread_mgr);
|
let current_index = self.current_index(thread_mgr);
|
||||||
|
|
||||||
// Enable multi-threaded execution, there are now at least two threads
|
// Enable multi-threaded execution, there are now at least two threads
|
||||||
|
@ -1320,7 +1347,7 @@ impl GlobalState {
|
||||||
// Now re-configure the re-use candidate, increment the clock
|
// Now re-configure the re-use candidate, increment the clock
|
||||||
// for the new sync use of the vector.
|
// for the new sync use of the vector.
|
||||||
let vector_clocks = self.vector_clocks.get_mut();
|
let vector_clocks = self.vector_clocks.get_mut();
|
||||||
vector_clocks[reuse_index].increment_clock(reuse_index);
|
vector_clocks[reuse_index].increment_clock(reuse_index, current_span);
|
||||||
|
|
||||||
// Locate the old thread the vector was associated with and update
|
// Locate the old thread the vector was associated with and update
|
||||||
// it to represent the new thread instead.
|
// it to represent the new thread instead.
|
||||||
|
@ -1360,8 +1387,8 @@ impl GlobalState {
|
||||||
|
|
||||||
// Advance both threads after the synchronized operation.
|
// Advance both threads after the synchronized operation.
|
||||||
// Both operations are considered to have release semantics.
|
// Both operations are considered to have release semantics.
|
||||||
current.increment_clock(current_index);
|
current.increment_clock(current_index, current_span);
|
||||||
created.increment_clock(created_index);
|
created.increment_clock(created_index, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hook on a thread join to update the implicit happens-before relation between the joined
|
/// Hook on a thread join to update the implicit happens-before relation between the joined
|
||||||
|
@ -1427,13 +1454,13 @@ impl GlobalState {
|
||||||
/// This should be called strictly before any calls to
|
/// This should be called strictly before any calls to
|
||||||
/// `thread_joined`.
|
/// `thread_joined`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn thread_terminated(&mut self, thread_mgr: &ThreadManager<'_, '_>) {
|
pub fn thread_terminated(&mut self, thread_mgr: &ThreadManager<'_, '_>, current_span: Span) {
|
||||||
let current_index = self.current_index(thread_mgr);
|
let current_index = self.current_index(thread_mgr);
|
||||||
|
|
||||||
// Increment the clock to a unique termination timestamp.
|
// Increment the clock to a unique termination timestamp.
|
||||||
let vector_clocks = self.vector_clocks.get_mut();
|
let vector_clocks = self.vector_clocks.get_mut();
|
||||||
let current_clocks = &mut vector_clocks[current_index];
|
let current_clocks = &mut vector_clocks[current_index];
|
||||||
current_clocks.increment_clock(current_index);
|
current_clocks.increment_clock(current_index, current_span);
|
||||||
|
|
||||||
// Load the current thread id for the executing vector.
|
// Load the current thread id for the executing vector.
|
||||||
let vector_info = self.vector_info.get_mut();
|
let vector_info = self.vector_info.get_mut();
|
||||||
|
@ -1462,13 +1489,14 @@ impl GlobalState {
|
||||||
fn maybe_perform_sync_operation<'tcx>(
|
fn maybe_perform_sync_operation<'tcx>(
|
||||||
&self,
|
&self,
|
||||||
thread_mgr: &ThreadManager<'_, '_>,
|
thread_mgr: &ThreadManager<'_, '_>,
|
||||||
|
current_span: Span,
|
||||||
op: impl FnOnce(VectorIdx, RefMut<'_, ThreadClockSet>) -> InterpResult<'tcx, bool>,
|
op: impl FnOnce(VectorIdx, RefMut<'_, ThreadClockSet>) -> InterpResult<'tcx, bool>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
if self.multi_threaded.get() {
|
if self.multi_threaded.get() {
|
||||||
let (index, clocks) = self.current_thread_state_mut(thread_mgr);
|
let (index, clocks) = self.current_thread_state_mut(thread_mgr);
|
||||||
if op(index, clocks)? {
|
if op(index, clocks)? {
|
||||||
let (_, mut clocks) = self.current_thread_state_mut(thread_mgr);
|
let (_, mut clocks) = self.current_thread_state_mut(thread_mgr);
|
||||||
clocks.increment_clock(index);
|
clocks.increment_clock(index, current_span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1501,10 +1529,10 @@ impl GlobalState {
|
||||||
/// since an acquire operation should have occurred before, however
|
/// since an acquire operation should have occurred before, however
|
||||||
/// for futex & condvar operations this is not the case and this
|
/// for futex & condvar operations this is not the case and this
|
||||||
/// operation must be used.
|
/// operation must be used.
|
||||||
pub fn validate_lock_release(&self, lock: &mut VClock, thread: ThreadId) {
|
pub fn validate_lock_release(&self, lock: &mut VClock, thread: ThreadId, current_span: Span) {
|
||||||
let (index, mut clocks) = self.load_thread_state_mut(thread);
|
let (index, mut clocks) = self.load_thread_state_mut(thread);
|
||||||
lock.clone_from(&clocks.clock);
|
lock.clone_from(&clocks.clock);
|
||||||
clocks.increment_clock(index);
|
clocks.increment_clock(index, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release a lock handle, express that this happens-before
|
/// Release a lock handle, express that this happens-before
|
||||||
|
@ -1514,10 +1542,15 @@ impl GlobalState {
|
||||||
/// For normal locks this should be equivalent to `validate_lock_release`.
|
/// For normal locks this should be equivalent to `validate_lock_release`.
|
||||||
/// This function only exists for joining over the set of concurrent readers
|
/// This function only exists for joining over the set of concurrent readers
|
||||||
/// in a read-write lock and should not be used for anything else.
|
/// in a read-write lock and should not be used for anything else.
|
||||||
pub fn validate_lock_release_shared(&self, lock: &mut VClock, thread: ThreadId) {
|
pub fn validate_lock_release_shared(
|
||||||
|
&self,
|
||||||
|
lock: &mut VClock,
|
||||||
|
thread: ThreadId,
|
||||||
|
current_span: Span,
|
||||||
|
) {
|
||||||
let (index, mut clocks) = self.load_thread_state_mut(thread);
|
let (index, mut clocks) = self.load_thread_state_mut(thread);
|
||||||
lock.join(&clocks.clock);
|
lock.join(&clocks.clock);
|
||||||
clocks.increment_clock(index);
|
clocks.increment_clock(index, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the vector index used by the given thread as well as the set of vector clocks
|
/// Load the vector index used by the given thread as well as the set of vector clocks
|
||||||
|
|
|
@ -160,6 +160,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
fn init_once_complete(&mut self, id: InitOnceId) -> InterpResult<'tcx> {
|
fn init_once_complete(&mut self, id: InitOnceId) -> InterpResult<'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
let current_thread = this.get_active_thread();
|
let current_thread = this.get_active_thread();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let init_once = &mut this.machine.threads.sync.init_onces[id];
|
let init_once = &mut this.machine.threads.sync.init_onces[id];
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -172,7 +173,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
// Each complete happens-before the end of the wait
|
// Each complete happens-before the end of the wait
|
||||||
if let Some(data_race) = &this.machine.data_race {
|
if let Some(data_race) = &this.machine.data_race {
|
||||||
data_race.validate_lock_release(&mut init_once.data_race, current_thread);
|
data_race.validate_lock_release(&mut init_once.data_race, current_thread, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wake up everyone.
|
// Wake up everyone.
|
||||||
|
@ -188,6 +189,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
fn init_once_fail(&mut self, id: InitOnceId) -> InterpResult<'tcx> {
|
fn init_once_fail(&mut self, id: InitOnceId) -> InterpResult<'tcx> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
let current_thread = this.get_active_thread();
|
let current_thread = this.get_active_thread();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let init_once = &mut this.machine.threads.sync.init_onces[id];
|
let init_once = &mut this.machine.threads.sync.init_onces[id];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
init_once.status,
|
init_once.status,
|
||||||
|
@ -197,7 +199,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
|
|
||||||
// Each complete happens-before the end of the wait
|
// Each complete happens-before the end of the wait
|
||||||
if let Some(data_race) = &this.machine.data_race {
|
if let Some(data_race) = &this.machine.data_race {
|
||||||
data_race.validate_lock_release(&mut init_once.data_race, current_thread);
|
data_race.validate_lock_release(&mut init_once.data_race, current_thread, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wake up one waiting thread, so they can go ahead and try to init this.
|
// Wake up one waiting thread, so they can go ahead and try to init this.
|
||||||
|
|
|
@ -359,6 +359,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
/// return `None`.
|
/// return `None`.
|
||||||
fn mutex_unlock(&mut self, id: MutexId, expected_owner: ThreadId) -> Option<usize> {
|
fn mutex_unlock(&mut self, id: MutexId, expected_owner: ThreadId) -> Option<usize> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let mutex = &mut this.machine.threads.sync.mutexes[id];
|
let mutex = &mut this.machine.threads.sync.mutexes[id];
|
||||||
if let Some(current_owner) = mutex.owner {
|
if let Some(current_owner) = mutex.owner {
|
||||||
// Mutex is locked.
|
// Mutex is locked.
|
||||||
|
@ -375,7 +376,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// The mutex is completely unlocked. Try transfering ownership
|
// The mutex is completely unlocked. Try transfering ownership
|
||||||
// to another thread.
|
// to another thread.
|
||||||
if let Some(data_race) = &this.machine.data_race {
|
if let Some(data_race) = &this.machine.data_race {
|
||||||
data_race.validate_lock_release(&mut mutex.data_race, current_owner);
|
data_race.validate_lock_release(
|
||||||
|
&mut mutex.data_race,
|
||||||
|
current_owner,
|
||||||
|
current_span,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.mutex_dequeue_and_lock(id);
|
this.mutex_dequeue_and_lock(id);
|
||||||
}
|
}
|
||||||
|
@ -454,6 +459,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
/// Returns `true` if succeeded, `false` if this `reader` did not hold the lock.
|
/// Returns `true` if succeeded, `false` if this `reader` did not hold the lock.
|
||||||
fn rwlock_reader_unlock(&mut self, id: RwLockId, reader: ThreadId) -> bool {
|
fn rwlock_reader_unlock(&mut self, id: RwLockId, reader: ThreadId) -> bool {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let rwlock = &mut this.machine.threads.sync.rwlocks[id];
|
let rwlock = &mut this.machine.threads.sync.rwlocks[id];
|
||||||
match rwlock.readers.entry(reader) {
|
match rwlock.readers.entry(reader) {
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
|
@ -470,7 +476,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
Entry::Vacant(_) => return false, // we did not even own this lock
|
Entry::Vacant(_) => return false, // we did not even own this lock
|
||||||
}
|
}
|
||||||
if let Some(data_race) = &this.machine.data_race {
|
if let Some(data_race) = &this.machine.data_race {
|
||||||
data_race.validate_lock_release_shared(&mut rwlock.data_race_reader, reader);
|
data_race.validate_lock_release_shared(
|
||||||
|
&mut rwlock.data_race_reader,
|
||||||
|
reader,
|
||||||
|
current_span,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The thread was a reader. If the lock is not held any more, give it to a writer.
|
// The thread was a reader. If the lock is not held any more, give it to a writer.
|
||||||
|
@ -511,6 +521,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rwlock_writer_unlock(&mut self, id: RwLockId, expected_writer: ThreadId) -> bool {
|
fn rwlock_writer_unlock(&mut self, id: RwLockId, expected_writer: ThreadId) -> bool {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let rwlock = &mut this.machine.threads.sync.rwlocks[id];
|
let rwlock = &mut this.machine.threads.sync.rwlocks[id];
|
||||||
if let Some(current_writer) = rwlock.writer {
|
if let Some(current_writer) = rwlock.writer {
|
||||||
if current_writer != expected_writer {
|
if current_writer != expected_writer {
|
||||||
|
@ -523,8 +534,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
// since this writer happens-before both the union of readers once they are finished
|
// since this writer happens-before both the union of readers once they are finished
|
||||||
// and the next writer
|
// and the next writer
|
||||||
if let Some(data_race) = &this.machine.data_race {
|
if let Some(data_race) = &this.machine.data_race {
|
||||||
data_race.validate_lock_release(&mut rwlock.data_race, current_writer);
|
data_race.validate_lock_release(
|
||||||
data_race.validate_lock_release(&mut rwlock.data_race_reader, current_writer);
|
&mut rwlock.data_race,
|
||||||
|
current_writer,
|
||||||
|
current_span,
|
||||||
|
);
|
||||||
|
data_race.validate_lock_release(
|
||||||
|
&mut rwlock.data_race_reader,
|
||||||
|
current_writer,
|
||||||
|
current_span,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// The thread was a writer.
|
// The thread was a writer.
|
||||||
//
|
//
|
||||||
|
@ -595,12 +614,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
fn condvar_signal(&mut self, id: CondvarId) -> Option<(ThreadId, CondvarLock)> {
|
fn condvar_signal(&mut self, id: CondvarId) -> Option<(ThreadId, CondvarLock)> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
let current_thread = this.get_active_thread();
|
let current_thread = this.get_active_thread();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let condvar = &mut this.machine.threads.sync.condvars[id];
|
let condvar = &mut this.machine.threads.sync.condvars[id];
|
||||||
let data_race = &this.machine.data_race;
|
let data_race = &this.machine.data_race;
|
||||||
|
|
||||||
// Each condvar signal happens-before the end of the condvar wake
|
// Each condvar signal happens-before the end of the condvar wake
|
||||||
if let Some(data_race) = data_race {
|
if let Some(data_race) = data_race {
|
||||||
data_race.validate_lock_release(&mut condvar.data_race, current_thread);
|
data_race.validate_lock_release(&mut condvar.data_race, current_thread, current_span);
|
||||||
}
|
}
|
||||||
condvar.waiters.pop_front().map(|waiter| {
|
condvar.waiters.pop_front().map(|waiter| {
|
||||||
if let Some(data_race) = data_race {
|
if let Some(data_race) = data_race {
|
||||||
|
@ -628,12 +648,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
fn futex_wake(&mut self, addr: u64, bitset: u32) -> Option<ThreadId> {
|
fn futex_wake(&mut self, addr: u64, bitset: u32) -> Option<ThreadId> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
let current_thread = this.get_active_thread();
|
let current_thread = this.get_active_thread();
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
let futex = &mut this.machine.threads.sync.futexes.get_mut(&addr)?;
|
let futex = &mut this.machine.threads.sync.futexes.get_mut(&addr)?;
|
||||||
let data_race = &this.machine.data_race;
|
let data_race = &this.machine.data_race;
|
||||||
|
|
||||||
// Each futex-wake happens-before the end of the futex wait
|
// Each futex-wake happens-before the end of the futex wait
|
||||||
if let Some(data_race) = data_race {
|
if let Some(data_race) = data_race {
|
||||||
data_race.validate_lock_release(&mut futex.data_race, current_thread);
|
data_race.validate_lock_release(&mut futex.data_race, current_thread, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wake up the first thread in the queue that matches any of the bits in the bitset.
|
// Wake up the first thread in the queue that matches any of the bits in the bitset.
|
||||||
|
|
|
@ -13,6 +13,7 @@ use rustc_hir::def_id::DefId;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_middle::mir::Mutability;
|
use rustc_middle::mir::Mutability;
|
||||||
use rustc_middle::ty::layout::TyAndLayout;
|
use rustc_middle::ty::layout::TyAndLayout;
|
||||||
|
use rustc_span::Span;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use crate::concurrency::data_race;
|
use crate::concurrency::data_race;
|
||||||
|
@ -617,6 +618,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
|
||||||
fn thread_terminated(
|
fn thread_terminated(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut data_race: Option<&mut data_race::GlobalState>,
|
mut data_race: Option<&mut data_race::GlobalState>,
|
||||||
|
current_span: Span,
|
||||||
) -> Vec<Pointer<Provenance>> {
|
) -> Vec<Pointer<Provenance>> {
|
||||||
let mut free_tls_statics = Vec::new();
|
let mut free_tls_statics = Vec::new();
|
||||||
{
|
{
|
||||||
|
@ -634,7 +636,7 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
// Set the thread into a terminated state in the data-race detector.
|
// Set the thread into a terminated state in the data-race detector.
|
||||||
if let Some(ref mut data_race) = data_race {
|
if let Some(ref mut data_race) = data_race {
|
||||||
data_race.thread_terminated(self);
|
data_race.thread_terminated(self, current_span);
|
||||||
}
|
}
|
||||||
// Check if we need to unblock any threads.
|
// Check if we need to unblock any threads.
|
||||||
let mut joined_threads = vec![]; // store which threads joined, we'll need it
|
let mut joined_threads = vec![]; // store which threads joined, we'll need it
|
||||||
|
@ -813,8 +815,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let mut state = tls::TlsDtorsState::default();
|
let mut state = tls::TlsDtorsState::default();
|
||||||
Box::new(move |m| state.on_stack_empty(m))
|
Box::new(move |m| state.on_stack_empty(m))
|
||||||
});
|
});
|
||||||
|
let current_span = this.machine.current_span();
|
||||||
if let Some(data_race) = &mut this.machine.data_race {
|
if let Some(data_race) = &mut this.machine.data_race {
|
||||||
data_race.thread_created(&this.machine.threads, new_thread_id);
|
data_race.thread_created(&this.machine.threads, new_thread_id, current_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the current thread-id, switch to the next thread later
|
// Write the current thread-id, switch to the next thread later
|
||||||
|
@ -1041,7 +1044,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
assert!(thread.stack.is_empty(), "only threads with an empty stack can be terminated");
|
assert!(thread.stack.is_empty(), "only threads with an empty stack can be terminated");
|
||||||
thread.state = ThreadState::Terminated;
|
thread.state = ThreadState::Terminated;
|
||||||
|
|
||||||
for ptr in this.machine.threads.thread_terminated(this.machine.data_race.as_mut()) {
|
let current_span = this.machine.current_span();
|
||||||
|
for ptr in
|
||||||
|
this.machine.threads.thread_terminated(this.machine.data_race.as_mut(), current_span)
|
||||||
|
{
|
||||||
this.deallocate_ptr(ptr.into(), None, MiriMemoryKind::Tls.into())?;
|
this.deallocate_ptr(ptr.into(), None, MiriMemoryKind::Tls.into())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
use rustc_span::{Span, SpanData, DUMMY_SP};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{cmp::Ordering, fmt::Debug, ops::Index};
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
|
fmt::Debug,
|
||||||
|
ops::{Index, IndexMut},
|
||||||
|
};
|
||||||
|
|
||||||
/// A vector clock index, this is associated with a thread id
|
/// A vector clock index, this is associated with a thread id
|
||||||
/// but in some cases one vector index may be shared with
|
/// but in some cases one vector index may be shared with
|
||||||
|
@ -40,9 +45,42 @@ impl From<u32> for VectorIdx {
|
||||||
/// clock vectors larger than this will be stored on the heap
|
/// clock vectors larger than this will be stored on the heap
|
||||||
const SMALL_VECTOR: usize = 4;
|
const SMALL_VECTOR: usize = 4;
|
||||||
|
|
||||||
/// The type of the time-stamps recorded in the data-race detector
|
/// The time-stamps recorded in the data-race detector consist of both
|
||||||
/// set to a type of unsigned integer
|
/// a 32-bit unsigned integer which is the actual timestamp, and a `Span`
|
||||||
pub type VTimestamp = u32;
|
/// so that diagnostics can report what code was responsible for an operation.
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct VTimestamp {
|
||||||
|
time: u32,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VTimestamp {
|
||||||
|
pub const ZERO: VTimestamp = VTimestamp { time: 0, span: DUMMY_SP };
|
||||||
|
|
||||||
|
pub fn span_data(&self) -> SpanData {
|
||||||
|
self.span.data()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for VTimestamp {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.time == other.time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for VTimestamp {}
|
||||||
|
|
||||||
|
impl PartialOrd for VTimestamp {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for VTimestamp {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.time.cmp(&other.time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A vector clock for detecting data-races, this is conceptually
|
/// A vector clock for detecting data-races, this is conceptually
|
||||||
/// a map from a vector index (and thus a thread id) to a timestamp.
|
/// a map from a vector index (and thus a thread id) to a timestamp.
|
||||||
|
@ -62,7 +100,7 @@ impl VClock {
|
||||||
/// for a value at the given index
|
/// for a value at the given index
|
||||||
pub fn new_with_index(index: VectorIdx, timestamp: VTimestamp) -> VClock {
|
pub fn new_with_index(index: VectorIdx, timestamp: VTimestamp) -> VClock {
|
||||||
let len = index.index() + 1;
|
let len = index.index() + 1;
|
||||||
let mut vec = smallvec::smallvec![0; len];
|
let mut vec = smallvec::smallvec![VTimestamp::ZERO; len];
|
||||||
vec[index.index()] = timestamp;
|
vec[index.index()] = timestamp;
|
||||||
VClock(vec)
|
VClock(vec)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +117,7 @@ impl VClock {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut_with_min_len(&mut self, min_len: usize) -> &mut [VTimestamp] {
|
fn get_mut_with_min_len(&mut self, min_len: usize) -> &mut [VTimestamp] {
|
||||||
if self.0.len() < min_len {
|
if self.0.len() < min_len {
|
||||||
self.0.resize(min_len, 0);
|
self.0.resize(min_len, VTimestamp::ZERO);
|
||||||
}
|
}
|
||||||
assert!(self.0.len() >= min_len);
|
assert!(self.0.len() >= min_len);
|
||||||
self.0.as_mut_slice()
|
self.0.as_mut_slice()
|
||||||
|
@ -88,11 +126,14 @@ impl VClock {
|
||||||
/// Increment the vector clock at a known index
|
/// Increment the vector clock at a known index
|
||||||
/// this will panic if the vector index overflows
|
/// this will panic if the vector index overflows
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn increment_index(&mut self, idx: VectorIdx) {
|
pub fn increment_index(&mut self, idx: VectorIdx, current_span: Span) {
|
||||||
let idx = idx.index();
|
let idx = idx.index();
|
||||||
let mut_slice = self.get_mut_with_min_len(idx + 1);
|
let mut_slice = self.get_mut_with_min_len(idx + 1);
|
||||||
let idx_ref = &mut mut_slice[idx];
|
let idx_ref = &mut mut_slice[idx];
|
||||||
*idx_ref = idx_ref.checked_add(1).expect("Vector clock overflow")
|
idx_ref.time = idx_ref.time.checked_add(1).expect("Vector clock overflow");
|
||||||
|
if !current_span.is_dummy() {
|
||||||
|
idx_ref.span = current_span;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join the two vector-clocks together, this
|
// Join the two vector-clocks together, this
|
||||||
|
@ -102,14 +143,23 @@ impl VClock {
|
||||||
let rhs_slice = other.as_slice();
|
let rhs_slice = other.as_slice();
|
||||||
let lhs_slice = self.get_mut_with_min_len(rhs_slice.len());
|
let lhs_slice = self.get_mut_with_min_len(rhs_slice.len());
|
||||||
for (l, &r) in lhs_slice.iter_mut().zip(rhs_slice.iter()) {
|
for (l, &r) in lhs_slice.iter_mut().zip(rhs_slice.iter()) {
|
||||||
|
let l_span = l.span;
|
||||||
|
let r_span = r.span;
|
||||||
*l = r.max(*l);
|
*l = r.max(*l);
|
||||||
|
l.span = l.span.substitute_dummy(r_span).substitute_dummy(l_span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the element at the current index of the vector
|
/// Set the element at the current index of the vector
|
||||||
pub fn set_at_index(&mut self, other: &Self, idx: VectorIdx) {
|
pub fn set_at_index(&mut self, other: &Self, idx: VectorIdx) {
|
||||||
let mut_slice = self.get_mut_with_min_len(idx.index() + 1);
|
let mut_slice = self.get_mut_with_min_len(idx.index() + 1);
|
||||||
|
|
||||||
|
let prev_span = mut_slice[idx.index()].span;
|
||||||
|
|
||||||
mut_slice[idx.index()] = other[idx];
|
mut_slice[idx.index()] = other[idx];
|
||||||
|
|
||||||
|
let span = &mut mut_slice[idx.index()].span;
|
||||||
|
*span = span.substitute_dummy(prev_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the vector to the all-zero vector
|
/// Set the vector to the all-zero vector
|
||||||
|
@ -313,7 +363,14 @@ impl Index<VectorIdx> for VClock {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, index: VectorIdx) -> &VTimestamp {
|
fn index(&self, index: VectorIdx) -> &VTimestamp {
|
||||||
self.as_slice().get(index.to_u32() as usize).unwrap_or(&0)
|
self.as_slice().get(index.to_u32() as usize).unwrap_or(&VTimestamp::ZERO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexMut<VectorIdx> for VClock {
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(&mut self, index: VectorIdx) -> &mut VTimestamp {
|
||||||
|
self.0.as_mut_slice().get_mut(index.to_u32() as usize).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,6 +381,7 @@ impl Index<VectorIdx> for VClock {
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::{VClock, VTimestamp, VectorIdx};
|
use super::{VClock, VTimestamp, VectorIdx};
|
||||||
|
use rustc_span::DUMMY_SP;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -331,13 +389,13 @@ mod tests {
|
||||||
let mut c1 = VClock::default();
|
let mut c1 = VClock::default();
|
||||||
let mut c2 = VClock::default();
|
let mut c2 = VClock::default();
|
||||||
assert_eq!(c1, c2);
|
assert_eq!(c1, c2);
|
||||||
c1.increment_index(VectorIdx(5));
|
c1.increment_index(VectorIdx(5), DUMMY_SP);
|
||||||
assert_ne!(c1, c2);
|
assert_ne!(c1, c2);
|
||||||
c2.increment_index(VectorIdx(53));
|
c2.increment_index(VectorIdx(53), DUMMY_SP);
|
||||||
assert_ne!(c1, c2);
|
assert_ne!(c1, c2);
|
||||||
c1.increment_index(VectorIdx(53));
|
c1.increment_index(VectorIdx(53), DUMMY_SP);
|
||||||
assert_ne!(c1, c2);
|
assert_ne!(c1, c2);
|
||||||
c2.increment_index(VectorIdx(5));
|
c2.increment_index(VectorIdx(5), DUMMY_SP);
|
||||||
assert_eq!(c1, c2);
|
assert_eq!(c1, c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,14 +444,14 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_slice(mut slice: &[VTimestamp]) -> VClock {
|
fn from_slice(mut slice: &[u32]) -> VClock {
|
||||||
while let Some(0) = slice.last() {
|
while let Some(0) = slice.last() {
|
||||||
slice = &slice[..slice.len() - 1]
|
slice = &slice[..slice.len() - 1]
|
||||||
}
|
}
|
||||||
VClock(smallvec::SmallVec::from_slice(slice))
|
VClock(slice.iter().copied().map(|time| VTimestamp { time, span: DUMMY_SP }).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_order(l: &[VTimestamp], r: &[VTimestamp], o: Option<Ordering>) {
|
fn assert_order(l: &[u32], r: &[u32], o: Option<Ordering>) {
|
||||||
let l = from_slice(l);
|
let l = from_slice(l);
|
||||||
let r = from_slice(r);
|
let r = from_slice(r);
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
|
||||||
// The thread index and timestamp of the initialisation write
|
// The thread index and timestamp of the initialisation write
|
||||||
// are never meaningfully used, so it's fine to leave them as 0
|
// are never meaningfully used, so it's fine to leave them as 0
|
||||||
store_index: VectorIdx::from(0),
|
store_index: VectorIdx::from(0),
|
||||||
timestamp: 0,
|
timestamp: VTimestamp::ZERO,
|
||||||
val: init,
|
val: init,
|
||||||
is_seqcst: false,
|
is_seqcst: false,
|
||||||
load_info: RefCell::new(LoadInfo::default()),
|
load_info: RefCell::new(LoadInfo::default()),
|
||||||
|
|
|
@ -35,6 +35,17 @@ pub enum TerminationInfo {
|
||||||
link_name: Symbol,
|
link_name: Symbol,
|
||||||
span: SpanData,
|
span: SpanData,
|
||||||
},
|
},
|
||||||
|
DataRace {
|
||||||
|
op1: RacingOp,
|
||||||
|
op2: RacingOp,
|
||||||
|
ptr: Pointer,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RacingOp {
|
||||||
|
pub action: String,
|
||||||
|
pub thread_info: String,
|
||||||
|
pub span: SpanData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TerminationInfo {
|
impl fmt::Display for TerminationInfo {
|
||||||
|
@ -55,6 +66,12 @@ impl fmt::Display for TerminationInfo {
|
||||||
write!(f, "multiple definitions of symbol `{link_name}`"),
|
write!(f, "multiple definitions of symbol `{link_name}`"),
|
||||||
SymbolShimClashing { link_name, .. } =>
|
SymbolShimClashing { link_name, .. } =>
|
||||||
write!(f, "found `{link_name}` symbol definition that clashes with a built-in shim",),
|
write!(f, "found `{link_name}` symbol definition that clashes with a built-in shim",),
|
||||||
|
DataRace { ptr, op1, op2 } =>
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Data race detected between (1) {} on {} and (2) {} on {} at {ptr:?}. (2) just happened here",
|
||||||
|
op1.action, op1.thread_info, op2.action, op2.thread_info
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +184,7 @@ pub fn report_error<'tcx, 'mir>(
|
||||||
Abort(_) => Some("abnormal termination"),
|
Abort(_) => Some("abnormal termination"),
|
||||||
UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance =>
|
UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance =>
|
||||||
Some("unsupported operation"),
|
Some("unsupported operation"),
|
||||||
StackedBorrowsUb { .. } => Some("Undefined Behavior"),
|
StackedBorrowsUb { .. } | DataRace { .. } => Some("Undefined Behavior"),
|
||||||
Deadlock => Some("deadlock"),
|
Deadlock => Some("deadlock"),
|
||||||
MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None,
|
MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None,
|
||||||
};
|
};
|
||||||
|
@ -205,6 +222,12 @@ pub fn report_error<'tcx, 'mir>(
|
||||||
vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))],
|
vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))],
|
||||||
Int2PtrWithStrictProvenance =>
|
Int2PtrWithStrictProvenance =>
|
||||||
vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))],
|
vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))],
|
||||||
|
DataRace { op1, .. } =>
|
||||||
|
vec![
|
||||||
|
(Some(op1.span), format!("and (1) occurred earlier here")),
|
||||||
|
(None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")),
|
||||||
|
(None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
|
||||||
|
],
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
};
|
};
|
||||||
(title, helps)
|
(title, helps)
|
||||||
|
@ -339,9 +362,11 @@ fn report_msg<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show note and help messages.
|
// Show note and help messages.
|
||||||
|
let mut extra_span = false;
|
||||||
for (span_data, note) in ¬es {
|
for (span_data, note) in ¬es {
|
||||||
if let Some(span_data) = span_data {
|
if let Some(span_data) = span_data {
|
||||||
err.span_note(span_data.span(), note);
|
err.span_note(span_data.span(), note);
|
||||||
|
extra_span = true;
|
||||||
} else {
|
} else {
|
||||||
err.note(note);
|
err.note(note);
|
||||||
}
|
}
|
||||||
|
@ -349,13 +374,14 @@ fn report_msg<'tcx>(
|
||||||
for (span_data, help) in &helps {
|
for (span_data, help) in &helps {
|
||||||
if let Some(span_data) = span_data {
|
if let Some(span_data) = span_data {
|
||||||
err.span_help(span_data.span(), help);
|
err.span_help(span_data.span(), help);
|
||||||
|
extra_span = true;
|
||||||
} else {
|
} else {
|
||||||
err.help(help);
|
err.help(help);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if notes.len() + helps.len() > 0 {
|
if notes.len() + helps.len() > 0 {
|
||||||
// Add visual separator before backtrace.
|
// Add visual separator before backtrace.
|
||||||
err.note("BACKTRACE:");
|
err.note(if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" });
|
||||||
}
|
}
|
||||||
// Add backtrace
|
// Add backtrace
|
||||||
for (idx, frame_info) in stacktrace.iter().enumerate() {
|
for (idx, frame_info) in stacktrace.iter().enumerate() {
|
||||||
|
|
|
@ -956,6 +956,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||||
&ecx.machine.threads,
|
&ecx.machine.threads,
|
||||||
alloc.size(),
|
alloc.size(),
|
||||||
kind,
|
kind,
|
||||||
|
ecx.machine.current_span(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
|
let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x1] by a Unique retag
|
||||||
|
|
|
|
||||||
LL | let res = helper(val, ptr);
|
LL | let res = helper(val, ptr);
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `helper` at $DIR/box-cell-alias.rs:LL:CC
|
= note: inside `helper` at $DIR/box-cell-alias.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/box-cell-alias.rs:LL:CC
|
--> $DIR/box-cell-alias.rs:LL:CC
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub fn main() {
|
||||||
let pointer = &*ptr.0;
|
let pointer = &*ptr.0;
|
||||||
|
|
||||||
// Note: could also error due to reading uninitialized memory, but the data-race detector triggers first.
|
// Note: could also error due to reading uninitialized memory, but the data-race detector triggers first.
|
||||||
*pointer.load(Ordering::Relaxed) //~ ERROR: Data race detected between Read on thread `<unnamed>` and Allocate on thread `<unnamed>`
|
*pointer.load(Ordering::Relaxed) //~ ERROR: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Allocate on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/alloc_read_race.rs:LL:CC
|
--> $DIR/alloc_read_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *pointer.load(Ordering::Relaxed)
|
LL | *pointer.load(Ordering::Relaxed)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Read on thread `<unnamed>` and Allocate on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Allocate on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/alloc_read_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | pointer.store(Box::into_raw(Box::new_uninit()), Ordering::Relaxed);
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/alloc_read_race.rs:LL:CC
|
= note: inside closure at $DIR/alloc_read_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let pointer = &*ptr.0;
|
let pointer = &*ptr.0;
|
||||||
*pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Allocate on thread `<unnamed>`
|
*pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Allocate on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/alloc_write_race.rs:LL:CC
|
--> $DIR/alloc_write_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *pointer.load(Ordering::Relaxed) = 2;
|
LL | *pointer.load(Ordering::Relaxed) = 2;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Allocate on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Allocate on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/alloc_write_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | .store(Box::into_raw(Box::<usize>::new_uninit()) as *mut usize, Ordering::Relaxed);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/alloc_write_race.rs:LL:CC
|
= note: inside closure at $DIR/alloc_write_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
(&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between Atomic Load on thread `<unnamed>` and Write on thread `<unnamed>`
|
(&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Atomic Load on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/atomic_read_na_write_race1.rs:LL:CC
|
--> $DIR/atomic_read_na_write_race1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | (&*c.0).load(Ordering::SeqCst)
|
LL | (&*c.0).load(Ordering::SeqCst)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Atomic Load on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/atomic_read_na_write_race1.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *(c.0 as *mut usize) = 32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/atomic_read_na_write_race1.rs:LL:CC
|
= note: inside closure at $DIR/atomic_read_na_write_race1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let atomic_ref = &mut *c.0;
|
let atomic_ref = &mut *c.0;
|
||||||
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Atomic Load on thread `<unnamed>`
|
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Atomic Load on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/atomic_read_na_write_race2.rs:LL:CC
|
--> $DIR/atomic_read_na_write_race2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *atomic_ref.get_mut() = 32;
|
LL | *atomic_ref.get_mut() = 32;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Atomic Load on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/atomic_read_na_write_race2.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | atomic_ref.load(Ordering::SeqCst)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/atomic_read_na_write_race2.rs:LL:CC
|
= note: inside closure at $DIR/atomic_read_na_write_race2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let atomic_ref = &mut *c.0;
|
let atomic_ref = &mut *c.0;
|
||||||
*atomic_ref.get_mut() //~ ERROR: Data race detected between Read on thread `<unnamed>` and Atomic Store on thread `<unnamed>`
|
*atomic_ref.get_mut() //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Atomic Store on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/atomic_write_na_read_race1.rs:LL:CC
|
--> $DIR/atomic_write_na_read_race1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *atomic_ref.get_mut()
|
LL | *atomic_ref.get_mut()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ Data race detected between Read on thread `<unnamed>` and Atomic Store on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/atomic_write_na_read_race1.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | atomic_ref.store(32, Ordering::SeqCst)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/atomic_write_na_read_race1.rs:LL:CC
|
= note: inside closure at $DIR/atomic_write_na_read_race1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
(&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between Atomic Store on thread `<unnamed>` and Read on thread `<unnamed>`
|
(&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Atomic Store on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/atomic_write_na_read_race2.rs:LL:CC
|
--> $DIR/atomic_write_na_read_race2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | (&*c.0).store(32, Ordering::SeqCst);
|
LL | (&*c.0).store(32, Ordering::SeqCst);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Atomic Store on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/atomic_write_na_read_race2.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | let _val = *(c.0 as *mut usize);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/atomic_write_na_read_race2.rs:LL:CC
|
= note: inside closure at $DIR/atomic_write_na_read_race2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
(&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between Atomic Store on thread `<unnamed>` and Write on thread `<unnamed>`
|
(&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Atomic Store on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/atomic_write_na_write_race1.rs:LL:CC
|
--> $DIR/atomic_write_na_write_race1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | (&*c.0).store(64, Ordering::SeqCst);
|
LL | (&*c.0).store(64, Ordering::SeqCst);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Atomic Store on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/atomic_write_na_write_race1.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *(c.0 as *mut usize) = 32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/atomic_write_na_write_race1.rs:LL:CC
|
= note: inside closure at $DIR/atomic_write_na_write_race1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let atomic_ref = &mut *c.0;
|
let atomic_ref = &mut *c.0;
|
||||||
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Atomic Store on thread `<unnamed>`
|
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Atomic Store on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/atomic_write_na_write_race2.rs:LL:CC
|
--> $DIR/atomic_write_na_write_race2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *atomic_ref.get_mut() = 32;
|
LL | *atomic_ref.get_mut() = 32;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Atomic Store on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/atomic_write_na_write_race2.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | atomic_ref.store(64, Ordering::SeqCst);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/atomic_write_na_write_race2.rs:LL:CC
|
= note: inside closure at $DIR/atomic_write_na_write_race2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -34,7 +34,7 @@ fn main() {
|
||||||
|
|
||||||
let join2 = unsafe {
|
let join2 = unsafe {
|
||||||
spawn(move || {
|
spawn(move || {
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/dangling_thread_async_race.rs:LL:CC
|
--> $DIR/dangling_thread_async_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0 = 64;
|
LL | *c.0 = 64;
|
||||||
| ^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/dangling_thread_async_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 32;
|
||||||
|
| ^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/dangling_thread_async_race.rs:LL:CC
|
= note: inside closure at $DIR/dangling_thread_async_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -33,6 +33,6 @@ fn main() {
|
||||||
spawn(|| ()).join().unwrap();
|
spawn(|| ()).join().unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between Write on thread `main` and Write on thread `<unnamed>`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `main`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `main` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `main` at ALLOC. (2) just happened here
|
||||||
--> $DIR/dangling_thread_race.rs:LL:CC
|
--> $DIR/dangling_thread_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0 = 64;
|
LL | *c.0 = 64;
|
||||||
| ^^^^^^^^^ Data race detected between Write on thread `main` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `main` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/dangling_thread_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 32;
|
||||||
|
| ^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/dangling_thread_race.rs:LL:CC
|
= note: inside `main` at $DIR/dangling_thread_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
__rust_dealloc(
|
__rust_dealloc(
|
||||||
//~^ ERROR: Data race detected between Deallocate on thread `<unnamed>` and Read on thread `<unnamed>`
|
//~^ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
|
||||||
ptr.0 as *mut _,
|
ptr.0 as *mut _,
|
||||||
std::mem::size_of::<usize>(),
|
std::mem::size_of::<usize>(),
|
||||||
std::mem::align_of::<usize>(),
|
std::mem::align_of::<usize>(),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: Undefined Behavior: Data race detected between Deallocate on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/dealloc_read_race1.rs:LL:CC
|
--> $DIR/dealloc_read_race1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | / __rust_dealloc(
|
LL | / __rust_dealloc(
|
||||||
|
@ -7,11 +7,16 @@ LL | | ptr.0 as *mut _,
|
||||||
LL | | std::mem::size_of::<usize>(),
|
LL | | std::mem::size_of::<usize>(),
|
||||||
LL | | std::mem::align_of::<usize>(),
|
LL | | std::mem::align_of::<usize>(),
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_____________^ Data race detected between Deallocate on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
| |_____________^ Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/dealloc_read_race1.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | let _val = *ptr.0;
|
||||||
|
| ^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/dealloc_read_race1.rs:LL:CC
|
= note: inside closure at $DIR/dealloc_read_race1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
// Also an error of the form: Data race detected between Read on thread `<unnamed>` and Deallocate on thread `<unnamed>`
|
// 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.
|
// but the invalid allocation is detected first.
|
||||||
*ptr.0 //~ ERROR: dereferenced after this allocation got freed
|
*ptr.0 //~ ERROR: dereferenced after this allocation got freed
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn main() {
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
// Now `stack_var` gets deallocated.
|
// Now `stack_var` gets deallocated.
|
||||||
} //~ ERROR: Data race detected between Deallocate on thread `<unnamed>` and Read on thread `<unnamed>`
|
} //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Deallocate on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/dealloc_read_race_stack.rs:LL:CC
|
--> $DIR/dealloc_read_race_stack.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | }
|
LL | }
|
||||||
| ^ Data race detected between Deallocate on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
| ^ Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/dealloc_read_race_stack.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *pointer.load(Ordering::Acquire)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/dealloc_read_race_stack.rs:LL:CC
|
= note: inside closure at $DIR/dealloc_read_race_stack.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
__rust_dealloc(
|
__rust_dealloc(
|
||||||
//~^ ERROR: Data race detected between Deallocate on thread `<unnamed>` and Write on thread `<unnamed>`
|
//~^ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
|
||||||
ptr.0 as *mut _,
|
ptr.0 as *mut _,
|
||||||
std::mem::size_of::<usize>(),
|
std::mem::size_of::<usize>(),
|
||||||
std::mem::align_of::<usize>(),
|
std::mem::align_of::<usize>(),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: Undefined Behavior: Data race detected between Deallocate on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/dealloc_write_race1.rs:LL:CC
|
--> $DIR/dealloc_write_race1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | / __rust_dealloc(
|
LL | / __rust_dealloc(
|
||||||
|
@ -7,11 +7,16 @@ LL | | ptr.0 as *mut _,
|
||||||
LL | | std::mem::size_of::<usize>(),
|
LL | | std::mem::size_of::<usize>(),
|
||||||
LL | | std::mem::align_of::<usize>(),
|
LL | | std::mem::align_of::<usize>(),
|
||||||
LL | | );
|
LL | | );
|
||||||
| |_____________^ Data race detected between Deallocate on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| |_____________^ Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/dealloc_write_race1.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *ptr.0 = 2;
|
||||||
|
| ^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/dealloc_write_race1.rs:LL:CC
|
= note: inside closure at $DIR/dealloc_write_race1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
// Also an error of the form: Data race detected between Write on thread `<unnamed>` and Deallocate on thread `<unnamed>`
|
// 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.
|
// but the invalid allocation is detected first.
|
||||||
*ptr.0 = 2; //~ ERROR: dereferenced after this allocation got freed
|
*ptr.0 = 2; //~ ERROR: dereferenced after this allocation got freed
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn main() {
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
// Now `stack_var` gets deallocated.
|
// Now `stack_var` gets deallocated.
|
||||||
} //~ ERROR: Data race detected between Deallocate on thread `<unnamed>` and Write on thread `<unnamed>`
|
} //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Deallocate on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/dealloc_write_race_stack.rs:LL:CC
|
--> $DIR/dealloc_write_race_stack.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | }
|
LL | }
|
||||||
| ^ Data race detected between Deallocate on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^ Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/dealloc_write_race_stack.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *pointer.load(Ordering::Acquire) = 3;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/dealloc_write_race_stack.rs:LL:CC
|
= note: inside closure at $DIR/dealloc_write_race_stack.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/enable_after_join_to_main.rs:LL:CC
|
--> $DIR/enable_after_join_to_main.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0 = 64;
|
LL | *c.0 = 64;
|
||||||
| ^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/enable_after_join_to_main.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 32;
|
||||||
|
| ^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/enable_after_join_to_main.rs:LL:CC
|
= note: inside closure at $DIR/enable_after_join_to_main.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -20,5 +20,5 @@ fn main() {
|
||||||
// The fence is useless, since it did not happen-after the `store` in the other thread.
|
// The fence is useless, since it did not happen-after the `store` in the other thread.
|
||||||
// Hence this is a data race.
|
// Hence this is a data race.
|
||||||
// Also see https://github.com/rust-lang/miri/issues/2192.
|
// Also see https://github.com/rust-lang/miri/issues/2192.
|
||||||
unsafe { V = 2 } //~ERROR: Data race detected between Write on thread `main` and Write on thread `<unnamed>`
|
unsafe { V = 2 } //~ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `main`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `main` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `main` at ALLOC. (2) just happened here
|
||||||
--> $DIR/fence_after_load.rs:LL:CC
|
--> $DIR/fence_after_load.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { V = 2 }
|
LL | unsafe { V = 2 }
|
||||||
| ^^^^^ Data race detected between Write on thread `main` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `main` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/fence_after_load.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | unsafe { V = 1 }
|
||||||
|
| ^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/fence_after_load.rs:LL:CC
|
= note: inside `main` at $DIR/fence_after_load.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Read on thread `<unnamed>`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/read_write_race.rs:LL:CC
|
--> $DIR/read_write_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0 = 64;
|
LL | *c.0 = 64;
|
||||||
| ^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Read on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^ Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/read_write_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | let _val = *c.0;
|
||||||
|
| ^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/read_write_race.rs:LL:CC
|
= note: inside closure at $DIR/read_write_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub fn main() {
|
||||||
|
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
stack_var //~ ERROR: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>`
|
stack_var //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/read_write_race_stack.rs:LL:CC
|
--> $DIR/read_write_race_stack.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | stack_var
|
LL | stack_var
|
||||||
| ^^^^^^^^^ Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/read_write_race_stack.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *pointer.load(Ordering::Acquire) = 3;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/read_write_race_stack.rs:LL:CC
|
= note: inside closure at $DIR/read_write_race_stack.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j3 = spawn(move || {
|
let j3 = spawn(move || {
|
||||||
if SYNC.load(Ordering::Acquire) == 2 {
|
if SYNC.load(Ordering::Acquire) == 2 {
|
||||||
*c.0 //~ ERROR: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/relax_acquire_race.rs:LL:CC
|
--> $DIR/relax_acquire_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0
|
LL | *c.0
|
||||||
| ^^^^ Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/relax_acquire_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 1;
|
||||||
|
| ^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/relax_acquire_race.rs:LL:CC
|
= note: inside closure at $DIR/relax_acquire_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub fn main() {
|
||||||
let j3 = spawn(move || {
|
let j3 = spawn(move || {
|
||||||
sleep(Duration::from_millis(500));
|
sleep(Duration::from_millis(500));
|
||||||
if SYNC.load(Ordering::Acquire) == 3 {
|
if SYNC.load(Ordering::Acquire) == 3 {
|
||||||
*c.0 //~ ERROR: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/release_seq_race.rs:LL:CC
|
--> $DIR/release_seq_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0
|
LL | *c.0
|
||||||
| ^^^^ Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/release_seq_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 1;
|
||||||
|
| ^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/release_seq_race.rs:LL:CC
|
= note: inside closure at $DIR/release_seq_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
if SYNC.load(Ordering::Acquire) == 2 {
|
if SYNC.load(Ordering::Acquire) == 2 {
|
||||||
*c.0 //~ ERROR: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/release_seq_race_same_thread.rs:LL:CC
|
--> $DIR/release_seq_race_same_thread.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0
|
LL | *c.0
|
||||||
| ^^^^ Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/release_seq_race_same_thread.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 1;
|
||||||
|
| ^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/release_seq_race_same_thread.rs:LL:CC
|
= note: inside closure at $DIR/release_seq_race_same_thread.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j3 = spawn(move || {
|
let j3 = spawn(move || {
|
||||||
if SYNC.load(Ordering::Acquire) == 3 {
|
if SYNC.load(Ordering::Acquire) == 3 {
|
||||||
*c.0 //~ ERROR: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>`
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/rmw_race.rs:LL:CC
|
--> $DIR/rmw_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0
|
LL | *c.0
|
||||||
| ^^^^ Data race detected between Read on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/rmw_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 1;
|
||||||
|
| ^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/rmw_race.rs:LL:CC
|
= note: inside closure at $DIR/rmw_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -21,4 +21,4 @@ fn race(local: i32) {
|
||||||
// Deallocating the local (when `main` returns)
|
// Deallocating the local (when `main` returns)
|
||||||
// races with the read in the other thread.
|
// races with the read in the other thread.
|
||||||
// Make sure the error points at this function's end, not just the call site.
|
// Make sure the error points at this function's end, not just the call site.
|
||||||
} //~ERROR: Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>`
|
} //~ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `main`
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `main` at ALLOC. (2) just happened here
|
||||||
--> $DIR/stack_pop_race.rs:LL:CC
|
--> $DIR/stack_pop_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | }
|
LL | }
|
||||||
| ^ Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>` at ALLOC
|
| ^ Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `main` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/stack_pop_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | let _val = unsafe { *ptr.0 };
|
||||||
|
| ^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `race` at $DIR/stack_pop_race.rs:LL:CC
|
= note: inside `race` at $DIR/stack_pop_race.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/stack_pop_race.rs:LL:CC
|
--> $DIR/stack_pop_race.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/write_write_race.rs:LL:CC
|
--> $DIR/write_write_race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *c.0 = 64;
|
LL | *c.0 = 64;
|
||||||
| ^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/write_write_race.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *c.0 = 32;
|
||||||
|
| ^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/write_write_race.rs:LL:CC
|
= note: inside closure at $DIR/write_write_race.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn main() {
|
||||||
|
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
stack_var = 1usize; //~ ERROR: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>`
|
stack_var = 1usize; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
|
||||||
|
|
||||||
// read to silence errors
|
// read to silence errors
|
||||||
stack_var
|
stack_var
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
error: Undefined Behavior: Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
error: Undefined Behavior: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
--> $DIR/write_write_race_stack.rs:LL:CC
|
--> $DIR/write_write_race_stack.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | stack_var = 1usize;
|
LL | stack_var = 1usize;
|
||||||
| ^^^^^^^^^^^^^^^^^^ Data race detected between Write on thread `<unnamed>` and Write on thread `<unnamed>` at ALLOC
|
| ^^^^^^^^^^^^^^^^^^ Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
|
help: and (1) occurred earlier here
|
||||||
|
--> $DIR/write_write_race_stack.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | *pointer.load(Ordering::Acquire) = 3;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= 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
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside closure at $DIR/write_write_race_stack.rs:LL:CC
|
= note: inside closure at $DIR/write_write_race_stack.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -14,7 +14,7 @@ help: then it's defined here again, in crate `exported_symbol_clashing`
|
||||||
|
|
|
|
||||||
LL | fn bar() {}
|
LL | fn bar() {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/exported_symbol_clashing.rs:LL:CC
|
= note: inside `main` at $DIR/exported_symbol_clashing.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -12,7 +12,7 @@ LL | |
|
||||||
LL | | unreachable!()
|
LL | | unreachable!()
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/exported_symbol_shim_clashing.rs:LL:CC
|
= note: inside `main` at $DIR/exported_symbol_shim_clashing.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *target = 13;
|
LL | *target = 13;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/alias_through_mutation.rs:LL:CC
|
= note: inside `main` at $DIR/alias_through_mutation.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | pub fn safe(_x: &mut i32, _y: &mut i32) {}
|
LL | pub fn safe(_x: &mut i32, _y: &mut i32) {}
|
||||||
| ^^
|
| ^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC
|
= note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/aliasing_mut1.rs:LL:CC
|
--> $DIR/aliasing_mut1.rs:LL:CC
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | pub fn safe(_x: &i32, _y: &mut i32) {}
|
LL | pub fn safe(_x: &i32, _y: &mut i32) {}
|
||||||
| ^^
|
| ^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC
|
= note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/aliasing_mut2.rs:LL:CC
|
--> $DIR/aliasing_mut2.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique FnEntry reta
|
||||||
|
|
|
|
||||||
LL | safe_raw(xraw, xshr);
|
LL | safe_raw(xraw, xshr);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `safe` at $DIR/aliasing_mut3.rs:LL:CC
|
= note: inside `safe` at $DIR/aliasing_mut3.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/aliasing_mut3.rs:LL:CC
|
--> $DIR/aliasing_mut3.rs:LL:CC
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | pub fn safe(_x: &i32, _y: &mut Cell<i32>) {}
|
LL | pub fn safe(_x: &i32, _y: &mut Cell<i32>) {}
|
||||||
| ^^
|
| ^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `safe` at $DIR/aliasing_mut4.rs:LL:CC
|
= note: inside `safe` at $DIR/aliasing_mut4.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/aliasing_mut4.rs:LL:CC
|
--> $DIR/aliasing_mut4.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *our = 5;
|
LL | *our = 5;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `unknown_code_2` at $DIR/box_exclusive_violation1.rs:LL:CC
|
= note: inside `unknown_code_2` at $DIR/box_exclusive_violation1.rs:LL:CC
|
||||||
note: inside `demo_box_advanced_unique`
|
note: inside `demo_box_advanced_unique`
|
||||||
--> $DIR/box_exclusive_violation1.rs:LL:CC
|
--> $DIR/box_exclusive_violation1.rs:LL:CC
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | unsafe fn test(mut x: Box<i32>, y: *const i32) -> i32 {
|
LL | unsafe fn test(mut x: Box<i32>, y: *const i32) -> i32 {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `test` at $DIR/box_noalias_violation.rs:LL:CC
|
= note: inside `test` at $DIR/box_noalias_violation.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/box_noalias_violation.rs:LL:CC
|
--> $DIR/box_noalias_violation.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0xc] by a Unique retag
|
||||||
|
|
|
|
||||||
LL | unsafe { from_raw_parts_mut(self_.as_ptr() as *mut T, self_.len()) }
|
LL | unsafe { from_raw_parts_mut(self_.as_ptr() as *mut T, self_.len()) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/buggy_as_mut_slice.rs:LL:CC
|
= note: inside `main` at $DIR/buggy_as_mut_slice.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x10] by a Unique retag
|
||||||
|
|
|
|
||||||
LL | from_raw_parts_mut(ptr.offset(mid as isize), len - mid),
|
LL | from_raw_parts_mut(ptr.offset(mid as isize), len - mid),
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/buggy_split_at_mut.rs:LL:CC
|
= note: inside `main` at $DIR/buggy_split_at_mut.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *base = 1;
|
LL | *base = 1;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/disable_mut_does_not_merge_srw.rs:LL:CC
|
= note: inside `main` at $DIR/disable_mut_does_not_merge_srw.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique FnEntry reta
|
||||||
|
|
|
|
||||||
LL | x.do_bad();
|
LL | x.do_bad();
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/fnentry_invalidation.rs:LL:CC
|
= note: inside `main` at $DIR/fnentry_invalidation.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0xc] by a Unique FnEntry reta
|
||||||
|
|
|
|
||||||
LL | let _ = t.sli.as_mut_ptr();
|
LL | let _ = t.sli.as_mut_ptr();
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/fnentry_invalidation2.rs:LL:CC
|
= note: inside `main` at $DIR/fnentry_invalidation2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x1] by a write access
|
||||||
|
|
|
|
||||||
LL | ptr1.write(0);
|
LL | ptr1.write(0);
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
= note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/illegal_deALLOC.rs:LL:CC
|
--> $DIR/illegal_deALLOC.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a read access
|
||||||
|
|
|
|
||||||
LL | let _val = unsafe { *xraw };
|
LL | let _val = unsafe { *xraw };
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read1.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a SharedReadOnly reta
|
||||||
|
|
|
|
||||||
LL | let shr = unsafe { &*xraw };
|
LL | let shr = unsafe { &*xraw };
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read2.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a read access
|
||||||
|
|
|
|
||||||
LL | let _val = unsafe { *xref1.r };
|
LL | let _val = unsafe { *xref1.r };
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read3.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read3.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a read access
|
||||||
|
|
|
|
||||||
LL | let _val = unsafe { *xraw }; // use the raw again, this invalidates xref2 *even* with the special read except for uniq refs
|
LL | let _val = unsafe { *xraw }; // use the raw again, this invalidates xref2 *even* with the special read except for uniq refs
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read4.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read4.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [$HEX..$HEX] by a read access
|
||||||
|
|
|
|
||||||
LL | mem::forget(unsafe { ptr::read(xshr) }); // but after reading through the shared ref
|
LL | mem::forget(unsafe { ptr::read(xshr) }); // but after reading through the shared ref
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read5.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read5.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique retag
|
||||||
|
|
|
|
||||||
LL | let x = &mut *x; // kill `raw`
|
LL | let x = &mut *x; // kill `raw`
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read6.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read6.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a read access
|
||||||
|
|
|
|
||||||
LL | let _val = ptr::read(raw);
|
LL | let _val = ptr::read(raw);
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read7.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read7.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *y2 += 1;
|
LL | *y2 += 1;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read8.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read8.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *exposed_ptr = 0;
|
LL | *exposed_ptr = 0;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read_despite_exposed1.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read_despite_exposed1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a read access
|
||||||
|
|
|
|
||||||
LL | let _val = *exposed_ptr;
|
LL | let _val = *exposed_ptr;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_read_despite_exposed2.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_read_despite_exposed2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -14,7 +14,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x0..0x4]
|
||||||
|
|
|
|
||||||
LL | let x: *mut u32 = xref as *const _ as *mut _;
|
LL | let x: *mut u32 = xref as *const _ as *mut _;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_write1.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_write1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique retag
|
||||||
|
|
|
|
||||||
LL | drop(&mut *target); // reborrow
|
LL | drop(&mut *target); // reborrow
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_write2.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_write2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -14,7 +14,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x0..0x4]
|
||||||
|
|
|
|
||||||
LL | let ptr = r#ref as *const _ as *mut _; // raw ptr, with raw tag
|
LL | let ptr = r#ref as *const _ as *mut _; // raw ptr, with raw tag
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_write3.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_write3.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique retag
|
||||||
|
|
|
|
||||||
LL | let _mut_ref: &mut i32 = unsafe { mem::transmute(raw) }; // &mut, with raw tag
|
LL | let _mut_ref: &mut i32 = unsafe { mem::transmute(raw) }; // &mut, with raw tag
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_write4.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_write4.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | unsafe { *xraw = 15 };
|
LL | unsafe { *xraw = 15 };
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_write5.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_write5.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | fn foo(a: &mut u32, y: *mut u32) -> u32 {
|
LL | fn foo(a: &mut u32, y: *mut u32) -> u32 {
|
||||||
| ^
|
| ^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `foo` at $DIR/illegal_write6.rs:LL:CC
|
= note: inside `foo` at $DIR/illegal_write6.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/illegal_write6.rs:LL:CC
|
--> $DIR/illegal_write6.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *exposed_ptr = 0;
|
LL | *exposed_ptr = 0;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/illegal_write_despite_exposed1.rs:LL:CC
|
= note: inside `main` at $DIR/illegal_write_despite_exposed1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *c.get() = UnsafeCell::new(1); // invalidates inner_shr
|
LL | *c.get() = UnsafeCell::new(1); // invalidates inner_shr
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/interior_mut1.rs:LL:CC
|
= note: inside `main` at $DIR/interior_mut1.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | *c.get() = UnsafeCell::new(0); // now inner_shr gets invalidated
|
LL | *c.get() = UnsafeCell::new(0); // now inner_shr gets invalidated
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/interior_mut2.rs:LL:CC
|
= note: inside `main` at $DIR/interior_mut2.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | fn inner(x: *mut i32, _y: &mut i32) {
|
LL | fn inner(x: *mut i32, _y: &mut i32) {
|
||||||
| ^^
|
| ^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `inner` at $DIR/invalidate_against_protector1.rs:LL:CC
|
= note: inside `inner` at $DIR/invalidate_against_protector1.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
--> $DIR/invalidate_against_protector1.rs:LL:CC
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | fn inner(x: *mut i32, _y: &i32) {
|
LL | fn inner(x: *mut i32, _y: &i32) {
|
||||||
| ^^
|
| ^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `inner` at $DIR/invalidate_against_protector2.rs:LL:CC
|
= note: inside `inner` at $DIR/invalidate_against_protector2.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: <TAG> is this argument
|
||||||
|
|
|
|
||||||
LL | fn inner(x: *mut i32, _y: &i32) {
|
LL | fn inner(x: *mut i32, _y: &i32) {
|
||||||
| ^^
|
| ^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `inner` at $DIR/invalidate_against_protector3.rs:LL:CC
|
= note: inside `inner` at $DIR/invalidate_against_protector3.rs:LL:CC
|
||||||
note: inside `main`
|
note: inside `main`
|
||||||
--> $DIR/invalidate_against_protector3.rs:LL:CC
|
--> $DIR/invalidate_against_protector3.rs:LL:CC
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a read access
|
||||||
|
|
|
|
||||||
LL | let _val = unsafe { *xraw }; // invalidate xref
|
LL | let _val = unsafe { *xraw }; // invalidate xref
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/load_invalid_mut.rs:LL:CC
|
= note: inside `main` at $DIR/load_invalid_mut.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
|
@ -19,7 +19,7 @@ help: <TAG> was later invalidated at offsets [0x0..0x4] by a write access
|
||||||
|
|
|
|
||||||
LL | unsafe { *xraw = 42 }; // unfreeze
|
LL | unsafe { *xraw = 42 }; // unfreeze
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE (of the first span):
|
||||||
= note: inside `main` at $DIR/load_invalid_shr.rs:LL:CC
|
= note: inside `main` at $DIR/load_invalid_shr.rs:LL:CC
|
||||||
|
|
||||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue