mirror of https://github.com/rust-lang/rust.git
Auto merge of #121936 - RalfJung:miri, r=RalfJung
Miri subtree update r? `@ghost`
This commit is contained in:
commit
279c9ba260
|
@ -412,6 +412,8 @@ to Miri failing to detect cases of undefined behavior in a program.
|
||||||
The default is to search for and remove unreachable provenance once every `10000` basic blocks. Setting
|
The default is to search for and remove unreachable provenance once every `10000` basic blocks. Setting
|
||||||
this to `0` disables the garbage collector, which causes some programs to have explosive memory
|
this to `0` disables the garbage collector, which causes some programs to have explosive memory
|
||||||
usage and/or super-linear runtime.
|
usage and/or super-linear runtime.
|
||||||
|
* `-Zmiri-track-alloc-accesses` show not only allocation and free events for tracked allocations,
|
||||||
|
but also reads and writes.
|
||||||
* `-Zmiri-track-alloc-id=<id1>,<id2>,...` shows a backtrace when the given allocations are
|
* `-Zmiri-track-alloc-id=<id1>,<id2>,...` shows a backtrace when the given allocations are
|
||||||
being allocated or freed. This helps in debugging memory leaks and
|
being allocated or freed. This helps in debugging memory leaks and
|
||||||
use after free bugs. Specifying this argument multiple times does not overwrite the previous
|
use after free bugs. Specifying this argument multiple times does not overwrite the previous
|
||||||
|
@ -588,6 +590,7 @@ Definite bugs found:
|
||||||
* [Dropping with unaligned pointers in `vec::IntoIter`](https://github.com/rust-lang/rust/pull/106084)
|
* [Dropping with unaligned pointers in `vec::IntoIter`](https://github.com/rust-lang/rust/pull/106084)
|
||||||
* [Deallocating with the wrong layout in new specializations for in-place `Iterator::collect`](https://github.com/rust-lang/rust/pull/118460)
|
* [Deallocating with the wrong layout in new specializations for in-place `Iterator::collect`](https://github.com/rust-lang/rust/pull/118460)
|
||||||
* [Incorrect offset computation for highly-aligned types in `portable-atomic-util`](https://github.com/taiki-e/portable-atomic/pull/138)
|
* [Incorrect offset computation for highly-aligned types in `portable-atomic-util`](https://github.com/taiki-e/portable-atomic/pull/138)
|
||||||
|
* [Occasional memory leak in `std::mpsc` channels](https://github.com/rust-lang/rust/issues/121582) (original code in [crossbeam](https://github.com/crossbeam-rs/crossbeam/pull/1084))
|
||||||
|
|
||||||
Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
|
Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
|
||||||
|
|
||||||
|
|
|
@ -356,11 +356,17 @@ impl Command {
|
||||||
.unwrap_or_else(|_| "0".into())
|
.unwrap_or_else(|_| "0".into())
|
||||||
.parse()
|
.parse()
|
||||||
.context("failed to parse MIRI_SEED_START")?;
|
.context("failed to parse MIRI_SEED_START")?;
|
||||||
let seed_count: u64 = env::var("MIRI_SEEDS")
|
let seed_end: u64 = match (env::var("MIRI_SEEDS"), env::var("MIRI_SEED_END")) {
|
||||||
.unwrap_or_else(|_| "256".into())
|
(Ok(_), Ok(_)) => bail!("Only one of MIRI_SEEDS and MIRI_SEED_END may be set"),
|
||||||
.parse()
|
(Ok(seeds), Err(_)) =>
|
||||||
.context("failed to parse MIRI_SEEDS")?;
|
seed_start + seeds.parse::<u64>().context("failed to parse MIRI_SEEDS")?,
|
||||||
let seed_end = seed_start + seed_count;
|
(Err(_), Ok(seed_end)) => seed_end.parse().context("failed to parse MIRI_SEED_END")?,
|
||||||
|
(Err(_), Err(_)) => seed_start + 256,
|
||||||
|
};
|
||||||
|
if seed_end <= seed_start {
|
||||||
|
bail!("the end of the seed range must be larger than the start.");
|
||||||
|
}
|
||||||
|
|
||||||
let Some((command_name, trailing_args)) = command.split_first() else {
|
let Some((command_name, trailing_args)) = command.split_first() else {
|
||||||
bail!("expected many-seeds command to be non-empty");
|
bail!("expected many-seeds command to be non-empty");
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,8 +113,9 @@ sysroot, to prevent conflicts with other toolchains.
|
||||||
./miri many-seeds <command>:
|
./miri many-seeds <command>:
|
||||||
Runs <command> over and over again with different seeds for Miri. The MIRIFLAGS
|
Runs <command> over and over again with different seeds for Miri. The MIRIFLAGS
|
||||||
variable is set to its original value appended with ` -Zmiri-seed=$SEED` for
|
variable is set to its original value appended with ` -Zmiri-seed=$SEED` for
|
||||||
many different seeds. The MIRI_SEEDS variable controls how many seeds are being
|
many different seeds. MIRI_SEED_START controls the first seed to try (default: 0).
|
||||||
tried; MIRI_SEED_START controls the first seed to try.
|
MIRI_SEEDS controls how many seeds are being tried (default: 256);
|
||||||
|
alternatively, MIRI_SEED_END controls the end of the (exclusive) seed range to try.
|
||||||
|
|
||||||
./miri bench <benches>:
|
./miri bench <benches>:
|
||||||
Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed.
|
Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed.
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
:: Windows will not execute the bash script, and select this.
|
:: Windows will not execute the bash script, and select this.
|
||||||
@echo off
|
@echo off
|
||||||
set MIRI_SCRIPT_TARGET_DIR=%0\..\miri-script\target
|
set MIRI_SCRIPT_TARGET_DIR=%0\..\miri-script\target
|
||||||
cargo build %CARGO_EXTRA_FLAGS% -q --target-dir %MIRI_SCRIPT_TARGET_DIR% --manifest-path %0\..\miri-script\Cargo.toml
|
|
||||||
|
:: If any other steps are added, the "|| exit /b" must be appended to early
|
||||||
|
:: return from the script. If not, it will continue execution.
|
||||||
|
cargo build %CARGO_EXTRA_FLAGS% -q --target-dir %MIRI_SCRIPT_TARGET_DIR% --manifest-path %0\..\miri-script\Cargo.toml || exit /b
|
||||||
|
|
||||||
:: Forwards all arguments to this file to the executable.
|
:: Forwards all arguments to this file to the executable.
|
||||||
:: We invoke the binary directly to avoid going through rustup, which would set some extra
|
:: We invoke the binary directly to avoid going through rustup, which would set some extra
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
c5f69bdd5173a948e0131f934fa7c4cbf5e0b55f
|
1a1876c9790f168fb51afa335a7ba3e6fc267d75
|
||||||
|
|
|
@ -534,6 +534,8 @@ fn main() {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
miri_config.tracked_alloc_ids.extend(ids);
|
miri_config.tracked_alloc_ids.extend(ids);
|
||||||
|
} else if arg == "-Zmiri-track-alloc-accesses" {
|
||||||
|
miri_config.track_alloc_accesses = true;
|
||||||
} else if let Some(param) = arg.strip_prefix("-Zmiri-compare-exchange-weak-failure-rate=") {
|
} else if let Some(param) = arg.strip_prefix("-Zmiri-compare-exchange-weak-failure-rate=") {
|
||||||
let rate = match param.parse::<f64>() {
|
let rate = match param.parse::<f64>() {
|
||||||
Ok(rate) if rate >= 0.0 && rate <= 1.0 => rate,
|
Ok(rate) if rate >= 0.0 && rate <= 1.0 => rate,
|
||||||
|
|
|
@ -122,13 +122,6 @@ impl VisitProvenance for GlobalStateInner {
|
||||||
/// We need interior mutable access to the global state.
|
/// We need interior mutable access to the global state.
|
||||||
pub type GlobalState = RefCell<GlobalStateInner>;
|
pub type GlobalState = RefCell<GlobalStateInner>;
|
||||||
|
|
||||||
/// Indicates which kind of access is being performed.
|
|
||||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
|
||||||
pub enum AccessKind {
|
|
||||||
Read,
|
|
||||||
Write,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for AccessKind {
|
impl fmt::Display for AccessKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -384,7 +377,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
if matches!(kind, AllocKind::LiveData) {
|
if matches!(kind, AllocKind::LiveData) {
|
||||||
let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
|
let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
|
||||||
let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
|
let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
|
||||||
alloc_borrow_tracker.release_protector(&this.machine, borrow_tracker, *tag)?;
|
alloc_borrow_tracker.release_protector(
|
||||||
|
&this.machine,
|
||||||
|
borrow_tracker,
|
||||||
|
*tag,
|
||||||
|
*alloc_id,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
borrow_tracker.borrow_mut().end_call(&frame.extra);
|
borrow_tracker.borrow_mut().end_call(&frame.extra);
|
||||||
|
@ -498,10 +496,12 @@ impl AllocState {
|
||||||
machine: &MiriMachine<'_, 'tcx>,
|
machine: &MiriMachine<'_, 'tcx>,
|
||||||
global: &GlobalState,
|
global: &GlobalState,
|
||||||
tag: BorTag,
|
tag: BorTag,
|
||||||
|
alloc_id: AllocId, // diagnostics
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
AllocState::StackedBorrows(_sb) => Ok(()),
|
AllocState::StackedBorrows(_sb) => Ok(()),
|
||||||
AllocState::TreeBorrows(tb) => tb.borrow_mut().release_protector(machine, global, tag),
|
AllocState::TreeBorrows(tb) =>
|
||||||
|
tb.borrow_mut().release_protector(machine, global, tag, alloc_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_span::{Span, SpanData};
|
use rustc_span::{Span, SpanData};
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
|
|
||||||
use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind};
|
use crate::borrow_tracker::{GlobalStateInner, ProtectorKind};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// Error reporting
|
/// Error reporting
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_target::abi::{Abi, Size};
|
||||||
|
|
||||||
use crate::borrow_tracker::{
|
use crate::borrow_tracker::{
|
||||||
stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder},
|
stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder},
|
||||||
AccessKind, GlobalStateInner, ProtectorKind,
|
GlobalStateInner, ProtectorKind,
|
||||||
};
|
};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::borrow_tracker::tree_borrows::{
|
||||||
tree::LocationState,
|
tree::LocationState,
|
||||||
unimap::UniIndex,
|
unimap::UniIndex,
|
||||||
};
|
};
|
||||||
use crate::borrow_tracker::{AccessKind, ProtectorKind};
|
use crate::borrow_tracker::ProtectorKind;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// Cause of an access: either a real access or one
|
/// Cause of an access: either a real access or one
|
||||||
|
@ -278,6 +278,8 @@ impl History {
|
||||||
pub(super) struct TbError<'node> {
|
pub(super) struct TbError<'node> {
|
||||||
/// What failure occurred.
|
/// What failure occurred.
|
||||||
pub error_kind: TransitionError,
|
pub error_kind: TransitionError,
|
||||||
|
/// The allocation in which the error is happening.
|
||||||
|
pub alloc_id: AllocId,
|
||||||
/// The offset (into the allocation) at which the conflict occurred.
|
/// The offset (into the allocation) at which the conflict occurred.
|
||||||
pub error_offset: u64,
|
pub error_offset: u64,
|
||||||
/// The tag on which the error was triggered.
|
/// The tag on which the error was triggered.
|
||||||
|
@ -300,7 +302,11 @@ impl TbError<'_> {
|
||||||
let accessed = self.accessed_info;
|
let accessed = self.accessed_info;
|
||||||
let conflicting = self.conflicting_info;
|
let conflicting = self.conflicting_info;
|
||||||
let accessed_is_conflicting = accessed.tag == conflicting.tag;
|
let accessed_is_conflicting = accessed.tag == conflicting.tag;
|
||||||
let title = format!("{cause} through {accessed} is forbidden");
|
let title = format!(
|
||||||
|
"{cause} through {accessed} at {alloc_id:?}[{offset:#x}] is forbidden",
|
||||||
|
alloc_id = self.alloc_id,
|
||||||
|
offset = self.error_offset
|
||||||
|
);
|
||||||
let (title, details, conflicting_tag_name) = match self.error_kind {
|
let (title, details, conflicting_tag_name) = match self.error_kind {
|
||||||
ChildAccessForbidden(perm) => {
|
ChildAccessForbidden(perm) => {
|
||||||
let conflicting_tag_name =
|
let conflicting_tag_name =
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
use rustc_target::abi::{Abi, Size};
|
|
||||||
|
|
||||||
use crate::borrow_tracker::{AccessKind, GlobalState, GlobalStateInner, ProtectorKind};
|
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
mir::{Mutability, RetagKind},
|
mir::{Mutability, RetagKind},
|
||||||
ty::{
|
ty::{
|
||||||
|
@ -10,7 +7,9 @@ use rustc_middle::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
|
use rustc_target::abi::{Abi, Size};
|
||||||
|
|
||||||
|
use crate::borrow_tracker::{GlobalState, GlobalStateInner, ProtectorKind};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub mod diagnostics;
|
pub mod diagnostics;
|
||||||
|
@ -70,6 +69,7 @@ impl<'tcx> Tree {
|
||||||
tag,
|
tag,
|
||||||
Some(range),
|
Some(range),
|
||||||
global,
|
global,
|
||||||
|
alloc_id,
|
||||||
span,
|
span,
|
||||||
diagnostics::AccessCause::Explicit(access_kind),
|
diagnostics::AccessCause::Explicit(access_kind),
|
||||||
)
|
)
|
||||||
|
@ -78,7 +78,7 @@ impl<'tcx> Tree {
|
||||||
/// Check that this pointer has permission to deallocate this range.
|
/// Check that this pointer has permission to deallocate this range.
|
||||||
pub fn before_memory_deallocation(
|
pub fn before_memory_deallocation(
|
||||||
&mut self,
|
&mut self,
|
||||||
_alloc_id: AllocId,
|
alloc_id: AllocId,
|
||||||
prov: ProvenanceExtra,
|
prov: ProvenanceExtra,
|
||||||
range: AllocRange,
|
range: AllocRange,
|
||||||
machine: &MiriMachine<'_, 'tcx>,
|
machine: &MiriMachine<'_, 'tcx>,
|
||||||
|
@ -91,7 +91,7 @@ impl<'tcx> Tree {
|
||||||
};
|
};
|
||||||
let global = machine.borrow_tracker.as_ref().unwrap();
|
let global = machine.borrow_tracker.as_ref().unwrap();
|
||||||
let span = machine.current_span();
|
let span = machine.current_span();
|
||||||
self.dealloc(tag, range, global, span)
|
self.dealloc(tag, range, global, alloc_id, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expose_tag(&mut self, _tag: BorTag) {
|
pub fn expose_tag(&mut self, _tag: BorTag) {
|
||||||
|
@ -109,6 +109,7 @@ impl<'tcx> Tree {
|
||||||
machine: &MiriMachine<'_, 'tcx>,
|
machine: &MiriMachine<'_, 'tcx>,
|
||||||
global: &GlobalState,
|
global: &GlobalState,
|
||||||
tag: BorTag,
|
tag: BorTag,
|
||||||
|
alloc_id: AllocId, // diagnostics
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let span = machine.current_span();
|
let span = machine.current_span();
|
||||||
self.perform_access(
|
self.perform_access(
|
||||||
|
@ -116,6 +117,7 @@ impl<'tcx> Tree {
|
||||||
tag,
|
tag,
|
||||||
None, // no specified range because it occurs on the entire allocation
|
None, // no specified range because it occurs on the entire allocation
|
||||||
global,
|
global,
|
||||||
|
alloc_id,
|
||||||
span,
|
span,
|
||||||
diagnostics::AccessCause::FnExit,
|
diagnostics::AccessCause::FnExit,
|
||||||
)
|
)
|
||||||
|
@ -211,7 +213,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
||||||
let global = this.machine.borrow_tracker.as_ref().unwrap().borrow();
|
let global = this.machine.borrow_tracker.as_ref().unwrap().borrow();
|
||||||
let ty = place.layout.ty;
|
let ty = place.layout.ty;
|
||||||
if global.tracked_pointer_tags.contains(&new_tag) {
|
if global.tracked_pointer_tags.contains(&new_tag) {
|
||||||
let kind_str = format!("{new_perm:?} (pointee type {ty})");
|
let kind_str = format!("initial state {} (pointee type {ty})", new_perm.initial_state);
|
||||||
this.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
|
this.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
|
||||||
new_tag.inner(),
|
new_tag.inner(),
|
||||||
Some(kind_str),
|
Some(kind_str),
|
||||||
|
@ -299,6 +301,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
||||||
orig_tag,
|
orig_tag,
|
||||||
Some(range),
|
Some(range),
|
||||||
this.machine.borrow_tracker.as_ref().unwrap(),
|
this.machine.borrow_tracker.as_ref().unwrap(),
|
||||||
|
alloc_id,
|
||||||
this.machine.current_span(),
|
this.machine.current_span(),
|
||||||
diagnostics::AccessCause::Reborrow,
|
diagnostics::AccessCause::Reborrow,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
||||||
|
|
||||||
use crate::borrow_tracker::tree_borrows::diagnostics::TransitionError;
|
use crate::borrow_tracker::tree_borrows::diagnostics::TransitionError;
|
||||||
use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness;
|
use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness;
|
||||||
use crate::borrow_tracker::AccessKind;
|
use crate::AccessKind;
|
||||||
|
|
||||||
/// The activation states of a pointer.
|
/// The activation states of a pointer.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::borrow_tracker::tree_borrows::{
|
||||||
unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap},
|
unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap},
|
||||||
Permission,
|
Permission,
|
||||||
};
|
};
|
||||||
use crate::borrow_tracker::{AccessKind, GlobalState, ProtectorKind};
|
use crate::borrow_tracker::{GlobalState, ProtectorKind};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -516,6 +516,7 @@ impl<'tcx> Tree {
|
||||||
tag: BorTag,
|
tag: BorTag,
|
||||||
access_range: AllocRange,
|
access_range: AllocRange,
|
||||||
global: &GlobalState,
|
global: &GlobalState,
|
||||||
|
alloc_id: AllocId, // diagnostics
|
||||||
span: Span, // diagnostics
|
span: Span, // diagnostics
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
self.perform_access(
|
self.perform_access(
|
||||||
|
@ -523,6 +524,7 @@ impl<'tcx> Tree {
|
||||||
tag,
|
tag,
|
||||||
Some(access_range),
|
Some(access_range),
|
||||||
global,
|
global,
|
||||||
|
alloc_id,
|
||||||
span,
|
span,
|
||||||
diagnostics::AccessCause::Dealloc,
|
diagnostics::AccessCause::Dealloc,
|
||||||
)?;
|
)?;
|
||||||
|
@ -545,6 +547,7 @@ impl<'tcx> Tree {
|
||||||
TbError {
|
TbError {
|
||||||
conflicting_info,
|
conflicting_info,
|
||||||
access_cause: diagnostics::AccessCause::Dealloc,
|
access_cause: diagnostics::AccessCause::Dealloc,
|
||||||
|
alloc_id,
|
||||||
error_offset: perms_range.start,
|
error_offset: perms_range.start,
|
||||||
error_kind,
|
error_kind,
|
||||||
accessed_info,
|
accessed_info,
|
||||||
|
@ -576,6 +579,7 @@ impl<'tcx> Tree {
|
||||||
tag: BorTag,
|
tag: BorTag,
|
||||||
access_range: Option<AllocRange>,
|
access_range: Option<AllocRange>,
|
||||||
global: &GlobalState,
|
global: &GlobalState,
|
||||||
|
alloc_id: AllocId, // diagnostics
|
||||||
span: Span, // diagnostics
|
span: Span, // diagnostics
|
||||||
access_cause: diagnostics::AccessCause, // diagnostics
|
access_cause: diagnostics::AccessCause, // diagnostics
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
@ -628,6 +632,7 @@ impl<'tcx> Tree {
|
||||||
TbError {
|
TbError {
|
||||||
conflicting_info,
|
conflicting_info,
|
||||||
access_cause,
|
access_cause,
|
||||||
|
alloc_id,
|
||||||
error_offset: perms_range.start,
|
error_offset: perms_range.start,
|
||||||
error_kind,
|
error_kind,
|
||||||
accessed_info,
|
accessed_info,
|
||||||
|
|
|
@ -812,6 +812,7 @@ impl VClockAlloc {
|
||||||
| MiriMemoryKind::Miri
|
| MiriMemoryKind::Miri
|
||||||
| MiriMemoryKind::C
|
| MiriMemoryKind::C
|
||||||
| MiriMemoryKind::WinHeap
|
| MiriMemoryKind::WinHeap
|
||||||
|
| MiriMemoryKind::WinLocal
|
||||||
| MiriMemoryKind::Mmap,
|
| MiriMemoryKind::Mmap,
|
||||||
)
|
)
|
||||||
| MemoryKind::Stack => {
|
| MemoryKind::Stack => {
|
||||||
|
@ -820,7 +821,8 @@ impl VClockAlloc {
|
||||||
alloc_timestamp.span = current_span;
|
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
|
||||||
|
// (conceptually they are allocated before everything).
|
||||||
MemoryKind::Machine(
|
MemoryKind::Machine(
|
||||||
MiriMemoryKind::Global
|
MiriMemoryKind::Global
|
||||||
| MiriMemoryKind::Machine
|
| MiriMemoryKind::Machine
|
||||||
|
@ -1673,8 +1675,8 @@ impl GlobalState {
|
||||||
vector: VectorIdx,
|
vector: VectorIdx,
|
||||||
) -> String {
|
) -> String {
|
||||||
let thread = self.vector_info.borrow()[vector];
|
let thread = self.vector_info.borrow()[vector];
|
||||||
let thread_name = thread_mgr.get_thread_name(thread);
|
let thread_name = thread_mgr.get_thread_display_name(thread);
|
||||||
format!("thread `{}`", String::from_utf8_lossy(thread_name))
|
format!("thread `{thread_name}`")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acquire a lock, express that the previous call of
|
/// Acquire a lock, express that the previous call of
|
||||||
|
|
|
@ -160,9 +160,18 @@ pub type StackEmptyCallback<'mir, 'tcx> =
|
||||||
Box<dyn FnMut(&mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, Poll<()>>>;
|
Box<dyn FnMut(&mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, Poll<()>>>;
|
||||||
|
|
||||||
impl<'mir, 'tcx> Thread<'mir, 'tcx> {
|
impl<'mir, 'tcx> Thread<'mir, 'tcx> {
|
||||||
/// Get the name of the current thread, or `<unnamed>` if it was not set.
|
/// Get the name of the current thread if it was set.
|
||||||
fn thread_name(&self) -> &[u8] {
|
fn thread_name(&self) -> Option<&[u8]> {
|
||||||
if let Some(ref thread_name) = self.thread_name { thread_name } else { b"<unnamed>" }
|
self.thread_name.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the name of the current thread for display purposes; will include thread ID if not set.
|
||||||
|
fn thread_display_name(&self, id: ThreadId) -> String {
|
||||||
|
if let Some(ref thread_name) = self.thread_name {
|
||||||
|
String::from_utf8_lossy(thread_name).into_owned()
|
||||||
|
} else {
|
||||||
|
format!("unnamed-{}", id.index())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the top user-relevant frame, if there is one.
|
/// Return the top user-relevant frame, if there is one.
|
||||||
|
@ -205,7 +214,7 @@ impl<'mir, 'tcx> std::fmt::Debug for Thread<'mir, 'tcx> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}({:?}, {:?})",
|
"{}({:?}, {:?})",
|
||||||
String::from_utf8_lossy(self.thread_name()),
|
String::from_utf8_lossy(self.thread_name().unwrap_or(b"<unnamed>")),
|
||||||
self.state,
|
self.state,
|
||||||
self.join_status
|
self.join_status
|
||||||
)
|
)
|
||||||
|
@ -572,10 +581,14 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the name of the given thread.
|
/// Get the name of the given thread.
|
||||||
pub fn get_thread_name(&self, thread: ThreadId) -> &[u8] {
|
pub fn get_thread_name(&self, thread: ThreadId) -> Option<&[u8]> {
|
||||||
self.threads[thread].thread_name()
|
self.threads[thread].thread_name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_thread_display_name(&self, thread: ThreadId) -> String {
|
||||||
|
self.threads[thread].thread_display_name(thread)
|
||||||
|
}
|
||||||
|
|
||||||
/// Put the thread into the blocked state.
|
/// Put the thread into the blocked state.
|
||||||
fn block_thread(&mut self, thread: ThreadId) {
|
fn block_thread(&mut self, thread: ThreadId) {
|
||||||
let state = &mut self.threads[thread].state;
|
let state = &mut self.threads[thread].state;
|
||||||
|
@ -969,18 +982,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_thread_name_wide(&mut self, thread: ThreadId, new_thread_name: &[u16]) {
|
fn get_thread_name<'c>(&'c self, thread: ThreadId) -> Option<&[u8]>
|
||||||
let this = self.eval_context_mut();
|
|
||||||
|
|
||||||
// The Windows `GetThreadDescription` shim to get the thread name isn't implemented, so being lossy is okay.
|
|
||||||
// This is only read by diagnostics, which already use `from_utf8_lossy`.
|
|
||||||
this.machine
|
|
||||||
.threads
|
|
||||||
.set_thread_name(thread, String::from_utf16_lossy(new_thread_name).into_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_thread_name<'c>(&'c self, thread: ThreadId) -> &'c [u8]
|
|
||||||
where
|
where
|
||||||
'mir: 'c,
|
'mir: 'c,
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,6 +116,7 @@ pub enum NonHaltingDiagnostic {
|
||||||
CreatedCallId(CallId),
|
CreatedCallId(CallId),
|
||||||
CreatedAlloc(AllocId, Size, Align, MemoryKind<MiriMemoryKind>),
|
CreatedAlloc(AllocId, Size, Align, MemoryKind<MiriMemoryKind>),
|
||||||
FreedAlloc(AllocId),
|
FreedAlloc(AllocId),
|
||||||
|
AccessedAlloc(AllocId, AccessKind),
|
||||||
RejectedIsolatedOp(String),
|
RejectedIsolatedOp(String),
|
||||||
ProgressReport {
|
ProgressReport {
|
||||||
block_count: u64, // how many basic blocks have been run so far
|
block_count: u64, // how many basic blocks have been run so far
|
||||||
|
@ -477,7 +478,6 @@ pub fn report_msg<'tcx>(
|
||||||
|
|
||||||
// Show note and help messages.
|
// Show note and help messages.
|
||||||
let mut extra_span = false;
|
let mut extra_span = false;
|
||||||
let notes_len = notes.len();
|
|
||||||
for (span_data, note) in notes {
|
for (span_data, note) in notes {
|
||||||
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);
|
||||||
|
@ -486,7 +486,6 @@ pub fn report_msg<'tcx>(
|
||||||
err.note(note);
|
err.note(note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let helps_len = helps.len();
|
|
||||||
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);
|
||||||
|
@ -495,12 +494,20 @@ pub fn report_msg<'tcx>(
|
||||||
err.help(help);
|
err.help(help);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if notes_len + helps_len > 0 {
|
|
||||||
// Add visual separator before backtrace.
|
|
||||||
err.note(if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add backtrace
|
// Add backtrace
|
||||||
|
let mut backtrace_title = String::from("BACKTRACE");
|
||||||
|
if extra_span {
|
||||||
|
write!(backtrace_title, " (of the first span)").unwrap();
|
||||||
|
}
|
||||||
|
let thread_name =
|
||||||
|
machine.threads.get_thread_display_name(machine.threads.get_active_thread_id());
|
||||||
|
if thread_name != "main" {
|
||||||
|
// Only print thread name if it is not `main`.
|
||||||
|
write!(backtrace_title, " on thread `{thread_name}`").unwrap();
|
||||||
|
};
|
||||||
|
write!(backtrace_title, ":").unwrap();
|
||||||
|
err.note(backtrace_title);
|
||||||
for (idx, frame_info) in stacktrace.iter().enumerate() {
|
for (idx, frame_info) in stacktrace.iter().enumerate() {
|
||||||
let is_local = machine.is_local(frame_info);
|
let is_local = machine.is_local(frame_info);
|
||||||
// No span for non-local frames and the first frame (which is the error site).
|
// No span for non-local frames and the first frame (which is the error site).
|
||||||
|
@ -532,6 +539,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||||
| PoppedPointerTag(..)
|
| PoppedPointerTag(..)
|
||||||
| CreatedCallId(..)
|
| CreatedCallId(..)
|
||||||
| CreatedAlloc(..)
|
| CreatedAlloc(..)
|
||||||
|
| AccessedAlloc(..)
|
||||||
| FreedAlloc(..)
|
| FreedAlloc(..)
|
||||||
| ProgressReport { .. }
|
| ProgressReport { .. }
|
||||||
| WeakMemoryOutdatedLoad => ("tracking was triggered".to_string(), DiagLevel::Note),
|
| WeakMemoryOutdatedLoad => ("tracking was triggered".to_string(), DiagLevel::Note),
|
||||||
|
@ -553,6 +561,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||||
size = size.bytes(),
|
size = size.bytes(),
|
||||||
align = align.bytes(),
|
align = align.bytes(),
|
||||||
),
|
),
|
||||||
|
AccessedAlloc(AllocId(id), access_kind) =>
|
||||||
|
format!("{access_kind} to allocation with id {id}"),
|
||||||
FreedAlloc(AllocId(id)) => format!("freed allocation with id {id}"),
|
FreedAlloc(AllocId(id)) => format!("freed allocation with id {id}"),
|
||||||
RejectedIsolatedOp(ref op) =>
|
RejectedIsolatedOp(ref op) =>
|
||||||
format!("{op} was made to return an error due to isolation"),
|
format!("{op} was made to return an error due to isolation"),
|
||||||
|
|
|
@ -112,6 +112,8 @@ pub struct MiriConfig {
|
||||||
pub tracked_call_ids: FxHashSet<CallId>,
|
pub tracked_call_ids: FxHashSet<CallId>,
|
||||||
/// The allocation ids to report about.
|
/// The allocation ids to report about.
|
||||||
pub tracked_alloc_ids: FxHashSet<AllocId>,
|
pub tracked_alloc_ids: FxHashSet<AllocId>,
|
||||||
|
/// For the tracked alloc ids, also report read/write accesses.
|
||||||
|
pub track_alloc_accesses: bool,
|
||||||
/// Determine if data race detection should be enabled
|
/// Determine if data race detection should be enabled
|
||||||
pub data_race_detector: bool,
|
pub data_race_detector: bool,
|
||||||
/// Determine if weak memory emulation should be enabled. Requires data race detection to be enabled
|
/// Determine if weak memory emulation should be enabled. Requires data race detection to be enabled
|
||||||
|
@ -169,6 +171,7 @@ impl Default for MiriConfig {
|
||||||
tracked_pointer_tags: FxHashSet::default(),
|
tracked_pointer_tags: FxHashSet::default(),
|
||||||
tracked_call_ids: FxHashSet::default(),
|
tracked_call_ids: FxHashSet::default(),
|
||||||
tracked_alloc_ids: FxHashSet::default(),
|
tracked_alloc_ids: FxHashSet::default(),
|
||||||
|
track_alloc_accesses: false,
|
||||||
data_race_detector: true,
|
data_race_detector: true,
|
||||||
weak_memory_emulation: true,
|
weak_memory_emulation: true,
|
||||||
track_outdated_loads: false,
|
track_outdated_loads: false,
|
||||||
|
|
|
@ -22,6 +22,13 @@ use rand::RngCore;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
/// Indicates which kind of access is being performed.
|
||||||
|
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||||
|
pub enum AccessKind {
|
||||||
|
Read,
|
||||||
|
Write,
|
||||||
|
}
|
||||||
|
|
||||||
// This mapping should match `decode_error_kind` in
|
// This mapping should match `decode_error_kind` in
|
||||||
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/unix/mod.rs>.
|
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/unix/mod.rs>.
|
||||||
const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
|
const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
|
||||||
|
|
|
@ -120,7 +120,7 @@ pub use crate::diagnostics::{
|
||||||
pub use crate::eval::{
|
pub use crate::eval::{
|
||||||
create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
|
create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
|
||||||
};
|
};
|
||||||
pub use crate::helpers::EvalContextExt as _;
|
pub use crate::helpers::{AccessKind, EvalContextExt as _};
|
||||||
pub use crate::intptrcast::{EvalContextExt as _, ProvenanceMode};
|
pub use crate::intptrcast::{EvalContextExt as _, ProvenanceMode};
|
||||||
pub use crate::machine::{
|
pub use crate::machine::{
|
||||||
AllocExtra, FrameExtra, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
|
AllocExtra, FrameExtra, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
|
||||||
|
|
|
@ -113,6 +113,8 @@ pub enum MiriMemoryKind {
|
||||||
C,
|
C,
|
||||||
/// Windows `HeapAlloc` memory.
|
/// Windows `HeapAlloc` memory.
|
||||||
WinHeap,
|
WinHeap,
|
||||||
|
/// Windows "local" memory (to be freed with `LocalFree`)
|
||||||
|
WinLocal,
|
||||||
/// Memory for args, errno, and other parts of the machine-managed environment.
|
/// Memory for args, errno, and other parts of the machine-managed environment.
|
||||||
/// This memory may leak.
|
/// This memory may leak.
|
||||||
Machine,
|
Machine,
|
||||||
|
@ -144,7 +146,7 @@ impl MayLeak for MiriMemoryKind {
|
||||||
fn may_leak(self) -> bool {
|
fn may_leak(self) -> bool {
|
||||||
use self::MiriMemoryKind::*;
|
use self::MiriMemoryKind::*;
|
||||||
match self {
|
match self {
|
||||||
Rust | Miri | C | WinHeap | Runtime => false,
|
Rust | Miri | C | WinHeap | WinLocal | Runtime => false,
|
||||||
Machine | Global | ExternStatic | Tls | Mmap => true,
|
Machine | Global | ExternStatic | Tls | Mmap => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +158,7 @@ impl MiriMemoryKind {
|
||||||
use self::MiriMemoryKind::*;
|
use self::MiriMemoryKind::*;
|
||||||
match self {
|
match self {
|
||||||
// Heap allocations are fine since the `Allocation` is created immediately.
|
// Heap allocations are fine since the `Allocation` is created immediately.
|
||||||
Rust | Miri | C | WinHeap | Mmap => true,
|
Rust | Miri | C | WinHeap | WinLocal | Mmap => true,
|
||||||
// Everything else is unclear, let's not show potentially confusing spans.
|
// Everything else is unclear, let's not show potentially confusing spans.
|
||||||
Machine | Global | ExternStatic | Tls | Runtime => false,
|
Machine | Global | ExternStatic | Tls | Runtime => false,
|
||||||
}
|
}
|
||||||
|
@ -171,6 +173,7 @@ impl fmt::Display for MiriMemoryKind {
|
||||||
Miri => write!(f, "Miri bare-metal heap"),
|
Miri => write!(f, "Miri bare-metal heap"),
|
||||||
C => write!(f, "C heap"),
|
C => write!(f, "C heap"),
|
||||||
WinHeap => write!(f, "Windows heap"),
|
WinHeap => write!(f, "Windows heap"),
|
||||||
|
WinLocal => write!(f, "Windows local memory"),
|
||||||
Machine => write!(f, "machine-managed memory"),
|
Machine => write!(f, "machine-managed memory"),
|
||||||
Runtime => write!(f, "language runtime memory"),
|
Runtime => write!(f, "language runtime memory"),
|
||||||
Global => write!(f, "global (static or const)"),
|
Global => write!(f, "global (static or const)"),
|
||||||
|
@ -512,6 +515,8 @@ pub struct MiriMachine<'mir, 'tcx> {
|
||||||
/// The allocation IDs to report when they are being allocated
|
/// The allocation IDs to report when they are being allocated
|
||||||
/// (helps for debugging memory leaks and use after free bugs).
|
/// (helps for debugging memory leaks and use after free bugs).
|
||||||
tracked_alloc_ids: FxHashSet<AllocId>,
|
tracked_alloc_ids: FxHashSet<AllocId>,
|
||||||
|
/// For the tracked alloc ids, also report read/write accesses.
|
||||||
|
track_alloc_accesses: bool,
|
||||||
|
|
||||||
/// Controls whether alignment of memory accesses is being checked.
|
/// Controls whether alignment of memory accesses is being checked.
|
||||||
pub(crate) check_alignment: AlignmentCheck,
|
pub(crate) check_alignment: AlignmentCheck,
|
||||||
|
@ -654,6 +659,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||||
extern_statics: FxHashMap::default(),
|
extern_statics: FxHashMap::default(),
|
||||||
rng: RefCell::new(rng),
|
rng: RefCell::new(rng),
|
||||||
tracked_alloc_ids: config.tracked_alloc_ids.clone(),
|
tracked_alloc_ids: config.tracked_alloc_ids.clone(),
|
||||||
|
track_alloc_accesses: config.track_alloc_accesses,
|
||||||
check_alignment: config.check_alignment,
|
check_alignment: config.check_alignment,
|
||||||
cmpxchg_weak_failure_rate: config.cmpxchg_weak_failure_rate,
|
cmpxchg_weak_failure_rate: config.cmpxchg_weak_failure_rate,
|
||||||
mute_stdout_stderr: config.mute_stdout_stderr,
|
mute_stdout_stderr: config.mute_stdout_stderr,
|
||||||
|
@ -793,6 +799,7 @@ impl VisitProvenance for MiriMachine<'_, '_> {
|
||||||
local_crates: _,
|
local_crates: _,
|
||||||
rng: _,
|
rng: _,
|
||||||
tracked_alloc_ids: _,
|
tracked_alloc_ids: _,
|
||||||
|
track_alloc_accesses: _,
|
||||||
check_alignment: _,
|
check_alignment: _,
|
||||||
cmpxchg_weak_failure_rate: _,
|
cmpxchg_weak_failure_rate: _,
|
||||||
mute_stdout_stderr: _,
|
mute_stdout_stderr: _,
|
||||||
|
@ -1235,6 +1242,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||||
(alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
|
(alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
|
||||||
range: AllocRange,
|
range: AllocRange,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
if machine.track_alloc_accesses && machine.tracked_alloc_ids.contains(&alloc_id) {
|
||||||
|
machine
|
||||||
|
.emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc(alloc_id, AccessKind::Read));
|
||||||
|
}
|
||||||
if let Some(data_race) = &alloc_extra.data_race {
|
if let Some(data_race) = &alloc_extra.data_race {
|
||||||
data_race.read(alloc_id, range, machine)?;
|
data_race.read(alloc_id, range, machine)?;
|
||||||
}
|
}
|
||||||
|
@ -1255,6 +1266,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||||
(alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
|
(alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
|
||||||
range: AllocRange,
|
range: AllocRange,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
|
if machine.track_alloc_accesses && machine.tracked_alloc_ids.contains(&alloc_id) {
|
||||||
|
machine
|
||||||
|
.emit_diagnostic(NonHaltingDiagnostic::AccessedAlloc(alloc_id, AccessKind::Write));
|
||||||
|
}
|
||||||
if let Some(data_race) = &mut alloc_extra.data_race {
|
if let Some(data_race) = &mut alloc_extra.data_race {
|
||||||
data_race.write(alloc_id, range, machine)?;
|
data_race.write(alloc_id, range, machine)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
state.last_key = Some(key);
|
state.last_key = Some(key);
|
||||||
trace!("Running TLS dtor {:?} on {:?} at {:?}", instance, ptr, active_thread);
|
trace!("Running TLS dtor {:?} on {:?} at {:?}", instance, ptr, active_thread);
|
||||||
assert!(
|
assert!(
|
||||||
!ptr.to_target_usize(this).unwrap() != 0,
|
ptr.to_target_usize(this).unwrap() != 0,
|
||||||
"data can't be NULL when dtor is called!"
|
"data can't be NULL when dtor is called!"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let name_out = name_out.to_pointer(this)?;
|
let name_out = name_out.to_pointer(this)?;
|
||||||
let len = len.to_target_usize(this)?;
|
let len = len.to_target_usize(this)?;
|
||||||
|
|
||||||
let name = this.get_thread_name(thread).to_owned();
|
// FIXME: we should use the program name if the thread name is not set
|
||||||
|
let name = this.get_thread_name(thread).unwrap_or(b"<unnamed>").to_owned();
|
||||||
let (success, _written) = this.write_c_str(&name, name_out, len)?;
|
let (success, _written) = this.write_c_str(&name, name_out, len)?;
|
||||||
|
|
||||||
Ok(if success { Scalar::from_u32(0) } else { this.eval_libc("ERANGE") })
|
Ok(if success { Scalar::from_u32(0) } else { this.eval_libc("ERANGE") })
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rustc_span::Symbol;
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
|
use crate::shims::os_str::bytes_to_os_str;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use shims::foreign_items::EmulateForeignItemResult;
|
use shims::foreign_items::EmulateForeignItemResult;
|
||||||
use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
|
use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
|
||||||
|
@ -12,7 +13,11 @@ use shims::windows::sync::EvalContextExt as _;
|
||||||
use shims::windows::thread::EvalContextExt as _;
|
use shims::windows::thread::EvalContextExt as _;
|
||||||
|
|
||||||
fn is_dyn_sym(name: &str) -> bool {
|
fn is_dyn_sym(name: &str) -> bool {
|
||||||
matches!(name, "SetThreadDescription" | "WaitOnAddress" | "WakeByAddressSingle")
|
// std does dynamic detection for these symbols
|
||||||
|
matches!(
|
||||||
|
name,
|
||||||
|
"SetThreadDescription" | "GetThreadDescription" | "WaitOnAddress" | "WakeByAddressSingle"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||||
|
@ -172,6 +177,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
|
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
|
||||||
this.write_pointer(res, dest)?;
|
this.write_pointer(res, dest)?;
|
||||||
}
|
}
|
||||||
|
"LocalFree" => {
|
||||||
|
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
|
let ptr = this.read_pointer(ptr)?;
|
||||||
|
this.free(ptr, MiriMemoryKind::WinLocal)?;
|
||||||
|
this.write_null(dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
// errno
|
// errno
|
||||||
"SetLastError" => {
|
"SetLastError" => {
|
||||||
|
@ -403,7 +414,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
|
|
||||||
let handle = this.read_scalar(handle)?;
|
let handle = this.read_scalar(handle)?;
|
||||||
|
|
||||||
let name = this.read_wide_str(this.read_pointer(name)?)?;
|
let name = this.read_wide_str(this.read_pointer(name)?)?;
|
||||||
|
|
||||||
let thread = match Handle::from_scalar(handle, this)? {
|
let thread = match Handle::from_scalar(handle, this)? {
|
||||||
|
@ -412,7 +422,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
_ => this.invalid_handle("SetThreadDescription")?,
|
_ => this.invalid_handle("SetThreadDescription")?,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.set_thread_name_wide(thread, &name);
|
// FIXME: use non-lossy conversion
|
||||||
|
this.set_thread_name(thread, String::from_utf16_lossy(&name).into_bytes());
|
||||||
|
|
||||||
|
this.write_null(dest)?;
|
||||||
|
}
|
||||||
|
"GetThreadDescription" => {
|
||||||
|
let [handle, name_ptr] =
|
||||||
|
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
|
|
||||||
|
let handle = this.read_scalar(handle)?;
|
||||||
|
let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name
|
||||||
|
|
||||||
|
let thread = match Handle::from_scalar(handle, this)? {
|
||||||
|
Some(Handle::Thread(thread)) => thread,
|
||||||
|
Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.get_active_thread(),
|
||||||
|
_ => this.invalid_handle("SetThreadDescription")?,
|
||||||
|
};
|
||||||
|
// Looks like the default thread name is empty.
|
||||||
|
let name = this.get_thread_name(thread).unwrap_or(b"").to_owned();
|
||||||
|
let name = this.alloc_os_str_as_wide_str(
|
||||||
|
bytes_to_os_str(&name)?,
|
||||||
|
MiriMemoryKind::WinLocal.into(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
this.write_scalar(Scalar::from_maybe_pointer(name, this), &name_ptr)?;
|
||||||
|
|
||||||
this.write_null(dest)?;
|
this.write_null(dest)?;
|
||||||
}
|
}
|
||||||
|
@ -432,7 +466,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||||
let ptr = this.read_pointer(ptr)?;
|
let ptr = this.read_pointer(ptr)?;
|
||||||
let len = this.read_target_usize(len)?;
|
let len = this.read_target_usize(len)?;
|
||||||
this.gen_random(ptr, len.into())?;
|
this.gen_random(ptr, len)?;
|
||||||
this.write_scalar(Scalar::from_i32(1), dest)?;
|
this.write_scalar(Scalar::from_i32(1), dest)?;
|
||||||
}
|
}
|
||||||
"BCryptGenRandom" => {
|
"BCryptGenRandom" => {
|
||||||
|
|
|
@ -172,6 +172,8 @@ regexes! {
|
||||||
r"\.rs:[0-9]+:[0-9]+(: [0-9]+:[0-9]+)?" => ".rs:LL:CC",
|
r"\.rs:[0-9]+:[0-9]+(: [0-9]+:[0-9]+)?" => ".rs:LL:CC",
|
||||||
// erase alloc ids
|
// erase alloc ids
|
||||||
"alloc[0-9]+" => "ALLOC",
|
"alloc[0-9]+" => "ALLOC",
|
||||||
|
// erase thread ids
|
||||||
|
r"unnamed-[0-9]+" => "unnamed-ID",
|
||||||
// erase borrow tags
|
// erase borrow tags
|
||||||
"<[0-9]+>" => "<TAG>",
|
"<[0-9]+>" => "<TAG>",
|
||||||
"<[0-9]+=" => "<TAG=",
|
"<[0-9]+=" => "<TAG=",
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | panic!()
|
||||||
|
|
|
|
||||||
= 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 on thread `unnamed-ID`:
|
||||||
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
|
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
|
||||||
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | panic!()
|
||||||
|
|
|
|
||||||
= 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 on thread `unnamed-ID`:
|
||||||
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
|
= note: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC
|
||||||
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 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 on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_join_main.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_join_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
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 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 on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_join_multiple.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_join_multiple.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
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 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 on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_join_self.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_join_self.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 @@ LL | | }
|
||||||
|
|
|
|
||||||
= 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 on thread `unnamed-ID`:
|
||||||
= note: inside `thread_start` at $DIR/unwind_top_of_stack.rs:LL:CC
|
= note: inside `thread_start` at $DIR/unwind_top_of_stack.rs:LL:CC
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0);
|
LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE on thread `unnamed-ID`:
|
||||||
= note: inside closure at RUSTLIB/core/src/macros/mod.rs:LL:CC
|
= note: inside closure at RUSTLIB/core/src/macros/mod.rs:LL:CC
|
||||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0);
|
LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0);
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/windows_join_self.rs:LL:CC
|
= note: inside closure at $DIR/windows_join_self.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
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
--> $DIR/env-set_var-data-race.rs:LL:CC
|
--> $DIR/env-set_var-data-race.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | libc::getenv(b"TZ/0".as_ptr().cast());
|
LL | libc::getenv(b"TZ/0".as_ptr().cast());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/env-set_var-data-race.rs:LL:CC
|
--> $DIR/env-set_var-data-race.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ LL | env::set_var("MY_RUST_VAR", "Ferris");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/env-set_var-data-race.rs:LL:CC
|
= note: inside closure at $DIR/env-set_var-data-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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0);
|
LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0);
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_mutex_deadlock.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_mutex_deadlock.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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | libc::pthread_mutex_lock(&mut mutex as *mut _);
|
LL | libc::pthread_mutex_lock(&mut mutex as *mut _);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE:
|
||||||
= note: inside `main` at $DIR/libc_pthread_mutex_normal_deadlock.rs:LL:CC
|
= note: inside `main` at $DIR/libc_pthread_mutex_normal_deadlock.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
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | ...t_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 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 on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_mutex_wrong_owner.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_mutex_wrong_owner.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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | libc::pthread_rwlock_wrlock(rw.get());
|
LL | libc::pthread_rwlock_wrlock(rw.get());
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE:
|
||||||
= note: inside `main` at $DIR/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC
|
= note: inside `main` at $DIR/libc_pthread_rwlock_read_write_deadlock_single_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
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _),
|
||||||
|
|
|
|
||||||
= 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 on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_rwlock_read_wrong_owner.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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0);
|
LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0);
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_rwlock_write_read_deadlock.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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | libc::pthread_rwlock_rdlock(rw.get());
|
LL | libc::pthread_rwlock_rdlock(rw.get());
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE:
|
||||||
= note: inside `main` at $DIR/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC
|
= note: inside `main` at $DIR/libc_pthread_rwlock_write_read_deadlock_single_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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0);
|
LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0);
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_rwlock_write_write_deadlock.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
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: deadlock: the evaluated program deadlocked
|
||||||
LL | libc::pthread_rwlock_wrlock(rw.get());
|
LL | libc::pthread_rwlock_wrlock(rw.get());
|
||||||
| ^ the evaluated program deadlocked
|
| ^ the evaluated program deadlocked
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE:
|
||||||
= note: inside `main` at $DIR/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC
|
= note: inside `main` at $DIR/libc_pthread_rwlock_write_write_deadlock_single_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
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _),
|
||||||
|
|
|
|
||||||
= 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 on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC
|
= note: inside closure at $DIR/libc_pthread_rwlock_write_wrong_owner.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
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: read access through <TAG> is forbidden
|
error: Undefined Behavior: read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/alias_through_mutation.rs:LL:CC
|
--> $DIR/alias_through_mutation.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _val = *target_alias;
|
LL | let _val = *target_alias;
|
||||||
| ^^^^^^^^^^^^^ read access through <TAG> is forbidden
|
| ^^^^^^^^^^^^^ read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/aliasing_mut1.rs:LL:CC
|
--> $DIR/aliasing_mut1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *x = 1;
|
LL | *x = 1;
|
||||||
| ^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
|
= help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/aliasing_mut2.rs:LL:CC
|
--> $DIR/aliasing_mut2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *y = 2;
|
LL | *y = 2;
|
||||||
| ^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
|
= help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/aliasing_mut3.rs:LL:CC
|
--> $DIR/aliasing_mut3.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *x = 1;
|
LL | *x = 1;
|
||||||
| ^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
|
= help: the accessed tag <TAG> has state Reserved (conflicted) which forbids this child write access
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> RUSTLIB/core/src/mem/mod.rs:LL:CC
|
--> RUSTLIB/core/src/mem/mod.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | ptr::write(dest, src);
|
LL | ptr::write(dest, src);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/box_exclusive_violation1.rs:LL:CC
|
--> $DIR/box_exclusive_violation1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *LEAK = 7;
|
LL | *LEAK = 7;
|
||||||
| ^^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: read access through <TAG> is forbidden
|
error: Undefined Behavior: read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/box_noalias_violation.rs:LL:CC
|
--> $DIR/box_noalias_violation.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *y
|
LL | *y
|
||||||
| ^^ read access through <TAG> is forbidden
|
| ^^ read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x4] is forbidden
|
||||||
--> $DIR/buggy_as_mut_slice.rs:LL:CC
|
--> $DIR/buggy_as_mut_slice.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | v2[1] = 7;
|
LL | v2[1] = 7;
|
||||||
| ^^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^^ write access through <TAG> at ALLOC[0x4] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x4] is forbidden
|
||||||
--> $DIR/buggy_split_at_mut.rs:LL:CC
|
--> $DIR/buggy_split_at_mut.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | b[1] = 6;
|
LL | b[1] = 6;
|
||||||
| ^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^ write access through <TAG> at ALLOC[0x4] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/illegal_write1.rs:LL:CC
|
--> $DIR/illegal_write1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { *x = 42 };
|
LL | unsafe { *x = 42 };
|
||||||
| ^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Frozen which forbids this child write access
|
= help: the accessed tag <TAG> has state Frozen which forbids this child write access
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: read access through <TAG> is forbidden
|
error: Undefined Behavior: read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/illegal_write5.rs:LL:CC
|
--> $DIR/illegal_write5.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _val = *xref;
|
LL | let _val = *xref;
|
||||||
| ^^^^^ read access through <TAG> is forbidden
|
| ^^^^^ read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/illegal_write6.rs:LL:CC
|
--> $DIR/illegal_write6.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { *y = 2 };
|
LL | unsafe { *y = 2 };
|
||||||
| ^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
--> $DIR/invalidate_against_protector2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { *x = 0 };
|
LL | unsafe { *x = 0 };
|
||||||
| ^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> (root of the allocation) is forbidden
|
error: Undefined Behavior: write access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/invalidate_against_protector3.rs:LL:CC
|
--> $DIR/invalidate_against_protector3.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { *x = 0 };
|
LL | unsafe { *x = 0 };
|
||||||
| ^^^^^^ write access through <TAG> (root of the allocation) is forbidden
|
| ^^^^^^ write access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> (root of the allocation) is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> (root of the allocation) is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/load_invalid_shr.rs:LL:CC
|
--> $DIR/load_invalid_shr.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _val = *xref_in_mem;
|
LL | let _val = *xref_in_mem;
|
||||||
| ^^^^^^^^^^^^ reborrow through <TAG> is forbidden
|
| ^^^^^^^^^^^^ reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/mut_exclusive_violation1.rs:LL:CC
|
--> $DIR/mut_exclusive_violation1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *LEAK = 7;
|
LL | *LEAK = 7;
|
||||||
| ^^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/mut_exclusive_violation2.rs:LL:CC
|
--> $DIR/mut_exclusive_violation2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *raw1 = 3;
|
LL | *raw1 = 3;
|
||||||
| ^^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: deallocation through <TAG> is forbidden
|
error: Undefined Behavior: deallocation through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> RUSTLIB/alloc/src/alloc.rs:LL:CC
|
--> RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
|
LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <TAG> is forbidden
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: deallocation through <TAG> is forbidden
|
error: Undefined Behavior: deallocation through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> RUSTLIB/alloc/src/alloc.rs:LL:CC
|
--> RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
|
LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <TAG> is forbidden
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
= help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: read access through <TAG> is forbidden
|
error: Undefined Behavior: read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/outdated_local.rs:LL:CC
|
--> $DIR/outdated_local.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | assert_eq!(unsafe { *y }, 1);
|
LL | assert_eq!(unsafe { *y }, 1);
|
||||||
| ^^ read access through <TAG> is forbidden
|
| ^^ read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Disabled which forbids this child read access
|
= help: the accessed tag <TAG> has state Disabled which forbids this child read access
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/pass_invalid_shr.rs:LL:CC
|
--> $DIR/pass_invalid_shr.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | foo(xref);
|
LL | foo(xref);
|
||||||
| ^^^^ reborrow through <TAG> is forbidden
|
| ^^^^ reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Disabled which forbids this reborrow (acting as a child read access)
|
= help: the accessed tag <TAG> has state Disabled which forbids this reborrow (acting as a child read access)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/pass_invalid_shr_option.rs:LL:CC
|
--> $DIR/pass_invalid_shr_option.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | foo(some_xref);
|
LL | foo(some_xref);
|
||||||
| ^^^^^^^^^ reborrow through <TAG> is forbidden
|
| ^^^^^^^^^ reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/pass_invalid_shr_tuple.rs:LL:CC
|
--> $DIR/pass_invalid_shr_tuple.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | foo(pair_xref);
|
LL | foo(pair_xref);
|
||||||
| ^^^^^^^^^ reborrow through <TAG> is forbidden
|
| ^^^^^^^^^ reborrow through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn thread_1(p: SendPtr) {
|
||||||
fn thread_2(p: SendPtr) {
|
fn thread_2(p: SendPtr) {
|
||||||
let p = p.0;
|
let p = p.0;
|
||||||
unsafe {
|
unsafe {
|
||||||
*p = 5; //~ ERROR: /Data race detected between \(1\) non-atomic (read|write) on thread `<unnamed>` and \(2\) non-atomic write on thread `<unnamed>`/
|
*p = 5; //~ ERROR: /Data race detected between \(1\) non-atomic (read|write) on thread `unnamed-[0-9]+` and \(2\) non-atomic write on thread `unnamed-[0-9]+`/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
--> $DIR/retag_data_race_write.rs:LL:CC
|
--> $DIR/retag_data_race_write.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *p = 5;
|
LL | *p = 5;
|
||||||
| ^^^^^^ Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/retag_data_race_write.rs:LL:CC
|
--> $DIR/retag_data_race_write.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ LL | let _r = &mut *p;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
= 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= note: inside `thread_2` at $DIR/retag_data_race_write.rs:LL:CC
|
= note: inside `thread_2` at $DIR/retag_data_race_write.rs:LL:CC
|
||||||
note: inside closure
|
note: inside closure
|
||||||
--> $DIR/retag_data_race_write.rs:LL:CC
|
--> $DIR/retag_data_race_write.rs:LL:CC
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
--> $DIR/retag_data_race_write.rs:LL:CC
|
--> $DIR/retag_data_race_write.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *p = 5;
|
LL | *p = 5;
|
||||||
| ^^^^^^ Data race detected between (1) non-atomic read on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/retag_data_race_write.rs:LL:CC
|
--> $DIR/retag_data_race_write.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ LL | let _r = &mut *p;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
= 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= note: inside `thread_2` at $DIR/retag_data_race_write.rs:LL:CC
|
= note: inside `thread_2` at $DIR/retag_data_race_write.rs:LL:CC
|
||||||
note: inside closure
|
note: inside closure
|
||||||
--> $DIR/retag_data_race_write.rs:LL:CC
|
--> $DIR/retag_data_race_write.rs:LL:CC
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x4] is forbidden
|
||||||
--> $DIR/return_invalid_shr.rs:LL:CC
|
--> $DIR/return_invalid_shr.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | ret
|
LL | ret
|
||||||
| ^^^ reborrow through <TAG> is forbidden
|
| ^^^ reborrow through <TAG> at ALLOC[0x4] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Disabled which forbids this reborrow (acting as a child read access)
|
= help: the accessed tag <TAG> has state Disabled which forbids this reborrow (acting as a child read access)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x4] is forbidden
|
||||||
--> $DIR/return_invalid_shr_option.rs:LL:CC
|
--> $DIR/return_invalid_shr_option.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | ret
|
LL | ret
|
||||||
| ^^^ reborrow through <TAG> is forbidden
|
| ^^^ reborrow through <TAG> at ALLOC[0x4] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: reborrow through <TAG> is forbidden
|
error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x4] is forbidden
|
||||||
--> $DIR/return_invalid_shr_tuple.rs:LL:CC
|
--> $DIR/return_invalid_shr_tuple.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | ret
|
LL | ret
|
||||||
| ^^^ reborrow through <TAG> is forbidden
|
| ^^^ reborrow through <TAG> at ALLOC[0x4] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: write access through <TAG> is forbidden
|
error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/shr_frozen_violation1.rs:LL:CC
|
--> $DIR/shr_frozen_violation1.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | *(x as *const i32 as *mut i32) = 7;
|
LL | *(x as *const i32 as *mut i32) = 7;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> is forbidden
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
= help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: read access through <TAG> is forbidden
|
error: Undefined Behavior: read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
--> $DIR/shr_frozen_violation2.rs:LL:CC
|
--> $DIR/shr_frozen_violation2.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _val = *frozen;
|
LL | let _val = *frozen;
|
||||||
| ^^^^^^^ read access through <TAG> is forbidden
|
| ^^^^^^^ read access through <TAG> at ALLOC[0x0] is forbidden
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||||
= help: the accessed tag <TAG> has state Disabled which forbids this child read access
|
= help: the accessed tag <TAG> has state Disabled which forbids this child read access
|
||||||
|
|
|
@ -4,6 +4,7 @@ error: abnormal termination: trace/breakpoint trap
|
||||||
LL | core::intrinsics::breakpoint()
|
LL | core::intrinsics::breakpoint()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap
|
||||||
|
|
|
|
||||||
|
= note: BACKTRACE:
|
||||||
= note: inside `main` at $DIR/breakpoint.rs:LL:CC
|
= note: inside `main` at $DIR/breakpoint.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() {
|
||||||
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 (1) creating a new allocation on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>`
|
*pointer.load(Ordering::Relaxed) //~ ERROR: Data race detected between (1) creating a new allocation on thread `unnamed-1` and (2) non-atomic read on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) creating a new allocation on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) creating a new allocation on thread `unnamed-ID` and (2) non-atomic read on thread `unnamed-ID` 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 (1) creating a new allocation on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) creating a new allocation on thread `unnamed-ID` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/alloc_read_race.rs:LL:CC
|
--> $DIR/alloc_read_race.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ LL | pointer.store(Box::into_raw(Box::new_uninit()), Ordering::Relax
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
= 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub fn main() {
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let ptr = ptr; // avoid field capturing
|
let ptr = ptr; // avoid field capturing
|
||||||
let pointer = &*ptr.0;
|
let pointer = &*ptr.0;
|
||||||
*pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between (1) creating a new allocation on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>`
|
*pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between (1) creating a new allocation on thread `unnamed-1` and (2) non-atomic write on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) creating a new allocation on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) creating a new allocation on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` 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 (1) creating a new allocation on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) creating a new allocation on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/alloc_write_race.rs:LL:CC
|
--> $DIR/alloc_write_race.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ LL | .store(Box::into_raw(Box::<usize>::new_uninit()) as *mut us
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let c = c; // avoid field capturing
|
let c = c; // avoid field capturing
|
||||||
(&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) atomic load on thread `<unnamed>`
|
(&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-1` and (2) atomic load on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) atomic load on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) atomic load on thread `unnamed-ID` 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 (1) non-atomic write on thread `<unnamed>` and (2) atomic load on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) atomic load on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/atomic_read_na_write_race1.rs:LL:CC
|
--> $DIR/atomic_read_na_write_race1.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn main() {
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let c = c; // avoid field capturing
|
let c = c; // avoid field capturing
|
||||||
let atomic_ref = &mut *c.0;
|
let atomic_ref = &mut *c.0;
|
||||||
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) atomic load on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>`
|
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) atomic load on thread `unnamed-1` and (2) non-atomic write on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) atomic load on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) atomic load on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` 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 (1) atomic load on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) atomic load on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/atomic_read_na_write_race2.rs:LL:CC
|
--> $DIR/atomic_read_na_write_race2.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn main() {
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let c = c; // avoid field capturing
|
let c = c; // avoid field capturing
|
||||||
let atomic_ref = &mut *c.0;
|
let atomic_ref = &mut *c.0;
|
||||||
*atomic_ref.get_mut() //~ ERROR: Data race detected between (1) atomic store on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>`
|
*atomic_ref.get_mut() //~ ERROR: Data race detected between (1) atomic store on thread `unnamed-1` and (2) non-atomic read on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) atomic store on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) atomic store on thread `unnamed-ID` and (2) non-atomic read on thread `unnamed-ID` 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 (1) atomic store on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) atomic store on thread `unnamed-ID` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/atomic_write_na_read_race1.rs:LL:CC
|
--> $DIR/atomic_write_na_read_race1.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let c = c; // avoid field capturing
|
let c = c; // avoid field capturing
|
||||||
(&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between (1) non-atomic read on thread `<unnamed>` and (2) atomic store on thread `<unnamed>`
|
(&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between (1) non-atomic read on thread `unnamed-1` and (2) atomic store on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `<unnamed>` and (2) atomic store on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) atomic store on thread `unnamed-ID` 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 (1) non-atomic read on thread `<unnamed>` and (2) atomic store on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) atomic store on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/atomic_write_na_read_race2.rs:LL:CC
|
--> $DIR/atomic_write_na_read_race2.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let c = c; // avoid field capturing
|
let c = c; // avoid field capturing
|
||||||
(&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) atomic store on thread `<unnamed>`
|
(&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-1` and (2) atomic store on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) atomic store on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) atomic store on thread `unnamed-ID` 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 (1) non-atomic write on thread `<unnamed>` and (2) atomic store on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) atomic store on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/atomic_write_na_write_race1.rs:LL:CC
|
--> $DIR/atomic_write_na_write_race1.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn main() {
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let c = c; // avoid field capturing
|
let c = c; // avoid field capturing
|
||||||
let atomic_ref = &mut *c.0;
|
let atomic_ref = &mut *c.0;
|
||||||
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) atomic store on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>`
|
*atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) atomic store on thread `unnamed-1` and (2) non-atomic write on thread `unnamed-2`
|
||||||
});
|
});
|
||||||
|
|
||||||
j1.join().unwrap();
|
j1.join().unwrap();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) atomic store on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) atomic store on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` 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 (1) atomic store on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) atomic store on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/atomic_write_na_write_race2.rs:LL:CC
|
--> $DIR/atomic_write_na_write_race2.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn main() {
|
||||||
let join2 = unsafe {
|
let join2 = unsafe {
|
||||||
spawn(move || {
|
spawn(move || {
|
||||||
let c = c; // capture `c`, not just its field.
|
let c = c; // capture `c`, not just its field.
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-1` and (2) non-atomic write on thread `unnamed-3`
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` 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 (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `<unnamed>` at ALLOC. (2) just happened here
|
| ^^^^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) non-atomic write on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/dangling_thread_async_race.rs:LL:CC
|
--> $DIR/dangling_thread_async_race.rs:LL:CC
|
||||||
|
@ -11,7 +11,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -34,6 +34,6 @@ fn main() {
|
||||||
spawn(|| ()).join().unwrap();
|
spawn(|| ()).join().unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*c.0 = 64; //~ ERROR: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `main`
|
*c.0 = 64; //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-1` and (2) non-atomic write on thread `main`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `main` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) non-atomic 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 (1) non-atomic write on thread `<unnamed>` and (2) non-atomic write on thread `main` at ALLOC. (2) just happened here
|
| ^^^^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) non-atomic write on thread `main` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/dangling_thread_race.rs:LL:CC
|
--> $DIR/dangling_thread_race.rs:LL:CC
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub fn main() {
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let ptr = ptr; // avoid field capturing
|
let ptr = ptr; // avoid field capturing
|
||||||
__rust_dealloc(
|
__rust_dealloc(
|
||||||
//~^ ERROR: Data race detected between (1) non-atomic read on thread `<unnamed>` and (2) deallocation on thread `<unnamed>`
|
//~^ ERROR: Data race detected between (1) non-atomic read on thread `unnamed-1` and (2) deallocation on thread `unnamed-2`
|
||||||
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 (1) non-atomic read on thread `<unnamed>` and (2) deallocation on thread `<unnamed>` at ALLOC. (2) just happened here
|
error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` 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,7 +7,7 @@ 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 (1) non-atomic read on thread `<unnamed>` and (2) deallocation on thread `<unnamed>` at ALLOC. (2) just happened here
|
| |_____________^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here
|
||||||
|
|
|
|
||||||
help: and (1) occurred earlier here
|
help: and (1) occurred earlier here
|
||||||
--> $DIR/dealloc_read_race1.rs:LL:CC
|
--> $DIR/dealloc_read_race1.rs:LL:CC
|
||||||
|
@ -16,7 +16,7 @@ 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 (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= 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
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub fn main() {
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
let ptr = ptr; // avoid field capturing
|
let ptr = ptr; // avoid field capturing
|
||||||
// Also an error of the form: Data race detected between (1) deallocation on thread `<unnamed>` and (2) non-atomic read on thread `<unnamed>`
|
// Also an error of the form: Data race detected between (1) deallocation on thread `unnamed-ID` and (2) non-atomic read on thread `unnamed-ID`
|
||||||
// but the invalid allocation is detected first.
|
// but the invalid allocation is detected first.
|
||||||
*ptr.0 //~ ERROR: has been freed
|
*ptr.0 //~ ERROR: has been freed
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,7 +20,7 @@ LL | | std::mem::size_of::<usize>(),
|
||||||
LL | | std::mem::align_of::<usize>(),
|
LL | | std::mem::align_of::<usize>(),
|
||||||
LL | | )
|
LL | | )
|
||||||
| |_____________^
|
| |_____________^
|
||||||
= note: BACKTRACE (of the first span):
|
= note: BACKTRACE (of the first span) on thread `unnamed-ID`:
|
||||||
= note: inside closure at $DIR/dealloc_read_race2.rs:LL:CC
|
= note: inside closure at $DIR/dealloc_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
|
||||||
|
|
|
@ -36,7 +36,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 (1) non-atomic read on thread `<unnamed>` and (2) deallocation on thread `<unnamed>`
|
} //~ ERROR: Data race detected between (1) non-atomic read on thread `unnamed-2` and (2) deallocation on thread `unnamed-1`
|
||||||
});
|
});
|
||||||
|
|
||||||
let j2 = spawn(move || {
|
let j2 = spawn(move || {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue