From d363a47fcbbdcef228acef6f8625fc09ce168c55 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 28 Nov 2019 10:36:37 +0100 Subject: [PATCH 1/8] Add a scheme to find the place where an id was destroyed --- benches/helpers/miri_helper.rs | 1 + src/bin/miri-rustc-tests.rs | 4 +++- src/bin/miri.rs | 13 +++++++++++++ src/eval.rs | 4 +++- src/lib.rs | 5 ++++- src/machine.rs | 4 ++-- src/stacked_borrows.rs | 14 ++++++++++---- .../compile-fail/stacked_borrows/track_id.rs | 19 +++++++++++++++++++ 8 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 tests/compile-fail/stacked_borrows/track_id.rs diff --git a/benches/helpers/miri_helper.rs b/benches/helpers/miri_helper.rs index aa0f3d9959..40683f8d74 100644 --- a/benches/helpers/miri_helper.rs +++ b/benches/helpers/miri_helper.rs @@ -32,6 +32,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls<'_> { excluded_env_vars: vec![], args: vec![], seed: None, + tracked_id: None, }; eval_main(tcx, entry_def_id, config); }); diff --git a/src/bin/miri-rustc-tests.rs b/src/bin/miri-rustc-tests.rs index df8bb583f8..8b1739f344 100644 --- a/src/bin/miri-rustc-tests.rs +++ b/src/bin/miri-rustc-tests.rs @@ -45,6 +45,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { excluded_env_vars: vec![], args: vec![], seed: None, + tracked_id: None, }; let did = self.0.hir().body_owner_def_id(body_id); println!("running test: {}", self.0.def_path_debug_str(did)); @@ -64,7 +65,8 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { ignore_leaks: false, excluded_env_vars: vec![], args: vec![], - seed: None + seed: None, + tracked_id: None, }; miri::eval_main(tcx, entry_def_id, config); diff --git a/src/bin/miri.rs b/src/bin/miri.rs index e255afc346..e3aa75b9e8 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -126,6 +126,7 @@ fn main() { let mut communicate = false; let mut ignore_leaks = false; let mut seed: Option = None; + let mut tracked_id: Option = None; let mut rustc_args = vec![]; let mut miri_args = vec![]; let mut after_dashdash = false; @@ -176,6 +177,17 @@ fn main() { arg if arg.starts_with("-Zmiri-env-exclude=") => { excluded_env_vars.push(arg.trim_start_matches("-Zmiri-env-exclude=").to_owned()); }, + arg if arg.starts_with("-Zmiri-track-id=") => { + let id: u64 = match arg.trim_start_matches("-Zmiri-track-id=").parse() { + Ok(id) => id, + Err(err) => panic!("-Zmiri-track-id requires a valid `u64` as the argument: {}", err), + }; + if let Some(id) = miri::PtrId::new(id) { + tracked_id = Some(id); + } else { + panic!("-Zmiri-track-id must be a nonzero id"); + } + }, _ => { rustc_args.push(arg); } @@ -208,6 +220,7 @@ fn main() { excluded_env_vars, seed, args: miri_args, + tracked_id, }; rustc_driver::install_ice_hook(); let result = rustc_driver::catch_fatal_errors(move || { diff --git a/src/eval.rs b/src/eval.rs index 8be42226b5..fb82679523 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -26,6 +26,8 @@ pub struct MiriConfig { pub args: Vec, /// The seed to use when non-determinism or randomness are required (e.g. ptr-to-int cast, `getrandom()`). pub seed: Option, + /// The stacked borrow id to report about + pub tracked_id: Option, } /// Details of premature program termination. @@ -47,7 +49,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx.at(syntax::source_map::DUMMY_SP), ty::ParamEnv::reveal_all(), Evaluator::new(config.communicate), - MemoryExtra::new(StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.validate), + MemoryExtra::new(StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.validate, config.tracked_id), ); // Complete initialization. EnvVars::init(&mut ecx, config.excluded_env_vars); diff --git a/src/lib.rs b/src/lib.rs index abed7ab9df..ee13631727 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,10 @@ pub use crate::operator::EvalContextExt as OperatorEvalContextExt; pub use crate::range_map::RangeMap; pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt}; pub use crate::mono_hash_map::MonoHashMap; -pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item}; +pub use crate::stacked_borrows::{ + EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item, PtrId, + GlobalState, +}; pub use crate::machine::{ PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS, MemoryExtra, AllocExtra, FrameData, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt, diff --git a/src/machine.rs b/src/machine.rs index 65b6bcfb2a..3d8e724c57 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -77,9 +77,9 @@ pub struct MemoryExtra { } impl MemoryExtra { - pub fn new(rng: StdRng, validate: bool) -> Self { + pub fn new(rng: StdRng, validate: bool, tracked_id: Option) -> Self { MemoryExtra { - stacked_borrows: Default::default(), + stacked_borrows: Rc::new(RefCell::new(GlobalState::new(tracked_id))), intptrcast: Default::default(), rng: RefCell::new(rng), validate, diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index 23a32fc2ac..bd42191821 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -105,6 +105,8 @@ pub struct GlobalState { next_call_id: CallId, /// Those call IDs corresponding to functions that are still running. active_calls: HashSet, + /// The id to trace in this execution run + tracked_id: Option, } /// Memory extra state gives us interior mutable access to the global state. pub type MemoryExtra = Rc>; @@ -151,18 +153,17 @@ impl fmt::Display for RefKind { } /// Utilities for initialization and ID generation -impl Default for GlobalState { - fn default() -> Self { +impl GlobalState { + pub fn new(tracked_id: Option) -> Self { GlobalState { next_ptr_id: NonZeroU64::new(1).unwrap(), base_ptr_ids: HashMap::default(), next_call_id: NonZeroU64::new(1).unwrap(), active_calls: HashSet::default(), + tracked_id, } } -} -impl GlobalState { fn new_ptr(&mut self) -> PtrId { let id = self.next_ptr_id; self.next_ptr_id = NonZeroU64::new(id.get() + 1).unwrap(); @@ -312,6 +313,11 @@ impl<'tcx> Stack { let first_incompatible_idx = self.find_first_write_incompatible(granting_idx); for item in self.borrows.drain(first_incompatible_idx..).rev() { trace!("access: popping item {:?}", item); + if let Tag::Tagged(id) = item.tag { + if Some(id) == global.tracked_id { + throw_unsup!(Unsupported(format!("popped id {}", id))); + } + } Stack::check_protector(&item, Some(tag), global)?; } } else { diff --git a/tests/compile-fail/stacked_borrows/track_id.rs b/tests/compile-fail/stacked_borrows/track_id.rs new file mode 100644 index 0000000000..67d38b1194 --- /dev/null +++ b/tests/compile-fail/stacked_borrows/track_id.rs @@ -0,0 +1,19 @@ +// compile-flags: -Zmiri-track-id=1372 +// do not run on anything but x86_64 linux, because minute changes can change the borrow stack ids +// only-x86_64 +// only-linux + +use std::mem; + +fn main() { + let mut target = 42; + // Make sure we cannot use a raw-tagged `&mut` pointing to a frozen location. + // Even just creating it unfreezes. + let raw = &mut target as *mut _; // let this leak to raw + let reference = unsafe { &*raw }; // freeze + let ptr = reference as *const _ as *mut i32; // raw ptr, with raw tag + let _mut_ref: &mut i32 = unsafe { mem::transmute(ptr) }; // &mut, with raw tag + //~^ ERROR popped id 1372 + // Now we retag, making our ref top-of-stack -- and, in particular, unfreezing. + let _val = *reference; +} From a0de213e421fa64f293d4247a2e7225104d8b6d9 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 28 Nov 2019 11:14:16 +0100 Subject: [PATCH 2/8] Vocabulary fix --- tests/compile-fail/stacked_borrows/track_id.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compile-fail/stacked_borrows/track_id.rs b/tests/compile-fail/stacked_borrows/track_id.rs index 67d38b1194..04f4f251fb 100644 --- a/tests/compile-fail/stacked_borrows/track_id.rs +++ b/tests/compile-fail/stacked_borrows/track_id.rs @@ -1,5 +1,5 @@ // compile-flags: -Zmiri-track-id=1372 -// do not run on anything but x86_64 linux, because minute changes can change the borrow stack ids +// do not run on anything but x86_64 linux, because minor libstd changes can change the borrow stack ids // only-x86_64 // only-linux From 67417945d4925e0c74277df2ba38d968791aba6d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 28 Nov 2019 14:33:35 +0100 Subject: [PATCH 3/8] Detect all variants of stack removals --- src/stacked_borrows.rs | 10 +++++----- tests/compile-fail/stacked_borrows/track_id.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index bd42191821..be54b7f5ab 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -271,6 +271,11 @@ impl<'tcx> Stack { /// Check if the given item is protected. fn check_protector(item: &Item, tag: Option, global: &GlobalState) -> InterpResult<'tcx> { + if let Tag::Tagged(id) = item.tag { + if Some(id) == global.tracked_id { + throw_unsup!(Unsupported(format!("disabling item {:?} for tag {:?}", item, tag))); + } + } if let Some(call) = item.protector { if global.is_active(call) { if let Some(tag) = tag { @@ -313,11 +318,6 @@ impl<'tcx> Stack { let first_incompatible_idx = self.find_first_write_incompatible(granting_idx); for item in self.borrows.drain(first_incompatible_idx..).rev() { trace!("access: popping item {:?}", item); - if let Tag::Tagged(id) = item.tag { - if Some(id) == global.tracked_id { - throw_unsup!(Unsupported(format!("popped id {}", id))); - } - } Stack::check_protector(&item, Some(tag), global)?; } } else { diff --git a/tests/compile-fail/stacked_borrows/track_id.rs b/tests/compile-fail/stacked_borrows/track_id.rs index 04f4f251fb..e691603b53 100644 --- a/tests/compile-fail/stacked_borrows/track_id.rs +++ b/tests/compile-fail/stacked_borrows/track_id.rs @@ -13,7 +13,7 @@ fn main() { let reference = unsafe { &*raw }; // freeze let ptr = reference as *const _ as *mut i32; // raw ptr, with raw tag let _mut_ref: &mut i32 = unsafe { mem::transmute(ptr) }; // &mut, with raw tag - //~^ ERROR popped id 1372 + //~^ ERROR disabling item [SharedReadOnly for <1372>] for tag Some() // Now we retag, making our ref top-of-stack -- and, in particular, unfreezing. let _val = *reference; } From eab25383174ec70b76395d079ad6e85dfd15f2ff Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 1 Dec 2019 00:02:58 +0100 Subject: [PATCH 4/8] Rename track-id to track-pointer-tag --- benches/helpers/miri_helper.rs | 2 +- src/bin/miri-rustc-tests.rs | 4 ++-- src/bin/miri.rs | 14 +++++++------- src/eval.rs | 4 ++-- src/machine.rs | 4 ++-- src/stacked_borrows.rs | 8 ++++---- tests/compile-fail/stacked_borrows/track_id.rs | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/benches/helpers/miri_helper.rs b/benches/helpers/miri_helper.rs index 40683f8d74..e2951110ac 100644 --- a/benches/helpers/miri_helper.rs +++ b/benches/helpers/miri_helper.rs @@ -32,7 +32,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls<'_> { excluded_env_vars: vec![], args: vec![], seed: None, - tracked_id: None, + tracked_pointer_tag: None, }; eval_main(tcx, entry_def_id, config); }); diff --git a/src/bin/miri-rustc-tests.rs b/src/bin/miri-rustc-tests.rs index 8b1739f344..370d2a2061 100644 --- a/src/bin/miri-rustc-tests.rs +++ b/src/bin/miri-rustc-tests.rs @@ -45,7 +45,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { excluded_env_vars: vec![], args: vec![], seed: None, - tracked_id: None, + tracked_pointer_tag: None, }; let did = self.0.hir().body_owner_def_id(body_id); println!("running test: {}", self.0.def_path_debug_str(did)); @@ -66,7 +66,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { excluded_env_vars: vec![], args: vec![], seed: None, - tracked_id: None, + tracked_pointer_tag: None, }; miri::eval_main(tcx, entry_def_id, config); diff --git a/src/bin/miri.rs b/src/bin/miri.rs index e3aa75b9e8..48af812962 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -126,7 +126,7 @@ fn main() { let mut communicate = false; let mut ignore_leaks = false; let mut seed: Option = None; - let mut tracked_id: Option = None; + let mut tracked_pointer_tag: Option = None; let mut rustc_args = vec![]; let mut miri_args = vec![]; let mut after_dashdash = false; @@ -177,15 +177,15 @@ fn main() { arg if arg.starts_with("-Zmiri-env-exclude=") => { excluded_env_vars.push(arg.trim_start_matches("-Zmiri-env-exclude=").to_owned()); }, - arg if arg.starts_with("-Zmiri-track-id=") => { - let id: u64 = match arg.trim_start_matches("-Zmiri-track-id=").parse() { + arg if arg.starts_with("-Zmiri-track-pointer-tag=") => { + let id: u64 = match arg.trim_start_matches("-Zmiri-track-pointer-tag=").parse() { Ok(id) => id, - Err(err) => panic!("-Zmiri-track-id requires a valid `u64` as the argument: {}", err), + Err(err) => panic!("-Zmiri-track-pointer-tag requires a valid `u64` as the argument: {}", err), }; if let Some(id) = miri::PtrId::new(id) { - tracked_id = Some(id); + tracked_pointer_tag = Some(id); } else { - panic!("-Zmiri-track-id must be a nonzero id"); + panic!("-Zmiri-track-pointer-tag must be a nonzero id"); } }, _ => { @@ -220,7 +220,7 @@ fn main() { excluded_env_vars, seed, args: miri_args, - tracked_id, + tracked_pointer_tag, }; rustc_driver::install_ice_hook(); let result = rustc_driver::catch_fatal_errors(move || { diff --git a/src/eval.rs b/src/eval.rs index fb82679523..81de2fa882 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -27,7 +27,7 @@ pub struct MiriConfig { /// The seed to use when non-determinism or randomness are required (e.g. ptr-to-int cast, `getrandom()`). pub seed: Option, /// The stacked borrow id to report about - pub tracked_id: Option, + pub tracked_pointer_tag: Option, } /// Details of premature program termination. @@ -49,7 +49,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx.at(syntax::source_map::DUMMY_SP), ty::ParamEnv::reveal_all(), Evaluator::new(config.communicate), - MemoryExtra::new(StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.validate, config.tracked_id), + MemoryExtra::new(StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.validate, config.tracked_pointer_tag), ); // Complete initialization. EnvVars::init(&mut ecx, config.excluded_env_vars); diff --git a/src/machine.rs b/src/machine.rs index 3d8e724c57..d5cd86d978 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -77,9 +77,9 @@ pub struct MemoryExtra { } impl MemoryExtra { - pub fn new(rng: StdRng, validate: bool, tracked_id: Option) -> Self { + pub fn new(rng: StdRng, validate: bool, tracked_pointer_tag: Option) -> Self { MemoryExtra { - stacked_borrows: Rc::new(RefCell::new(GlobalState::new(tracked_id))), + stacked_borrows: Rc::new(RefCell::new(GlobalState::new(tracked_pointer_tag))), intptrcast: Default::default(), rng: RefCell::new(rng), validate, diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index be54b7f5ab..ad70b05d8a 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -106,7 +106,7 @@ pub struct GlobalState { /// Those call IDs corresponding to functions that are still running. active_calls: HashSet, /// The id to trace in this execution run - tracked_id: Option, + tracked_pointer_tag: Option, } /// Memory extra state gives us interior mutable access to the global state. pub type MemoryExtra = Rc>; @@ -154,13 +154,13 @@ impl fmt::Display for RefKind { /// Utilities for initialization and ID generation impl GlobalState { - pub fn new(tracked_id: Option) -> Self { + pub fn new(tracked_pointer_tag: Option) -> Self { GlobalState { next_ptr_id: NonZeroU64::new(1).unwrap(), base_ptr_ids: HashMap::default(), next_call_id: NonZeroU64::new(1).unwrap(), active_calls: HashSet::default(), - tracked_id, + tracked_pointer_tag, } } @@ -272,7 +272,7 @@ impl<'tcx> Stack { /// Check if the given item is protected. fn check_protector(item: &Item, tag: Option, global: &GlobalState) -> InterpResult<'tcx> { if let Tag::Tagged(id) = item.tag { - if Some(id) == global.tracked_id { + if Some(id) == global.tracked_pointer_tag { throw_unsup!(Unsupported(format!("disabling item {:?} for tag {:?}", item, tag))); } } diff --git a/tests/compile-fail/stacked_borrows/track_id.rs b/tests/compile-fail/stacked_borrows/track_id.rs index e691603b53..35a0f04ee6 100644 --- a/tests/compile-fail/stacked_borrows/track_id.rs +++ b/tests/compile-fail/stacked_borrows/track_id.rs @@ -1,4 +1,4 @@ -// compile-flags: -Zmiri-track-id=1372 +// compile-flags: -Zmiri-track-pointer-tag=1372 // do not run on anything but x86_64 linux, because minor libstd changes can change the borrow stack ids // only-x86_64 // only-linux From acb43f80fdd2fb8c81192a030d9c847d27fa502d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 1 Dec 2019 00:03:06 +0100 Subject: [PATCH 5/8] Document the new flag --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 16eae05973..176b4c4c34 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ Several `-Z` flags are relevant for Miri: the program has access to host resources such as environment variables and randomness (and, eventually, file systems and more). * `-Zmiri-ignore-leaks` disables the memory leak checker. -* `-Zmiri-env-exclude=` keeps the `var` environment variable isolated from +* `-Zmiri-env-exclude=` keeps the `var` environment variable isolated from the host. Can be used multiple times to exclude several variables. The `TERM` environment variable is excluded by default. * `-Zmir-opt-level` controls how many MIR optimizations are performed. Miri @@ -171,6 +171,11 @@ Several `-Z` flags are relevant for Miri: sets this flag per default. * `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri enables this per default because it is needed for validation. +* `-Zmiri-track-pointer-tag` aborts interpretation with a backtrace when the + given pointer tag is popped from a borrow stack (which is where the tag + becomes invalid and any future use of it will error anyway). This helps you + in finding out why UB is happening and where in your code would be a good + place to look for it. Moreover, Miri recognizes some environment variables: From 7cd0d7f15266eeebada17e51881b470561c3e697 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 1 Dec 2019 00:04:24 +0100 Subject: [PATCH 6/8] Remove a flaky test --- .../compile-fail/stacked_borrows/track_id.rs | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 tests/compile-fail/stacked_borrows/track_id.rs diff --git a/tests/compile-fail/stacked_borrows/track_id.rs b/tests/compile-fail/stacked_borrows/track_id.rs deleted file mode 100644 index 35a0f04ee6..0000000000 --- a/tests/compile-fail/stacked_borrows/track_id.rs +++ /dev/null @@ -1,19 +0,0 @@ -// compile-flags: -Zmiri-track-pointer-tag=1372 -// do not run on anything but x86_64 linux, because minor libstd changes can change the borrow stack ids -// only-x86_64 -// only-linux - -use std::mem; - -fn main() { - let mut target = 42; - // Make sure we cannot use a raw-tagged `&mut` pointing to a frozen location. - // Even just creating it unfreezes. - let raw = &mut target as *mut _; // let this leak to raw - let reference = unsafe { &*raw }; // freeze - let ptr = reference as *const _ as *mut i32; // raw ptr, with raw tag - let _mut_ref: &mut i32 = unsafe { mem::transmute(ptr) }; // &mut, with raw tag - //~^ ERROR disabling item [SharedReadOnly for <1372>] for tag Some() - // Now we retag, making our ref top-of-stack -- and, in particular, unfreezing. - let _val = *reference; -} From 817f4159a2146b95fd29fb5ea1725463e8f2dfd3 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 9 Dec 2019 14:29:28 +0100 Subject: [PATCH 7/8] Use the machine stop error instead of abusing other error kinds --- src/eval.rs | 3 +++ src/stacked_borrows.rs | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index 81de2fa882..9a70663716 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -33,6 +33,7 @@ pub struct MiriConfig { /// Details of premature program termination. pub enum TerminationInfo { Exit(i64), + PoppedTrackedPointerTag(Item), Abort, } @@ -218,6 +219,8 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> .expect("invalid MachineStop payload"); match info { TerminationInfo::Exit(code) => return Some(*code), + TerminationInfo::PoppedTrackedPointerTag(item) => + format!("popped tracked tag for item {:?}", item), TerminationInfo::Abort => format!("the evaluated program aborted execution") } diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index ad70b05d8a..8782eb83d1 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -12,7 +12,7 @@ use rustc::hir::Mutability::{Mutable, Immutable}; use rustc::mir::RetagKind; use crate::{ - InterpResult, HelpersEvalContextExt, + InterpResult, HelpersEvalContextExt, TerminationInfo, MemoryKind, MiriMemoryKind, RangeMap, AllocId, Pointer, Immediate, ImmTy, PlaceTy, MPlaceTy, }; @@ -273,7 +273,7 @@ impl<'tcx> Stack { fn check_protector(item: &Item, tag: Option, global: &GlobalState) -> InterpResult<'tcx> { if let Tag::Tagged(id) = item.tag { if Some(id) == global.tracked_pointer_tag { - throw_unsup!(Unsupported(format!("disabling item {:?} for tag {:?}", item, tag))); + throw_machine_stop!(TerminationInfo::PoppedTrackedPointerTag(item.clone())); } } if let Some(call) = item.protector { From 8d409a7b593b32b6b1fa1914ce352efea1bb8095 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 10 Dec 2019 14:47:28 +0100 Subject: [PATCH 8/8] Update README.md Co-Authored-By: Ralf Jung --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 176b4c4c34..5be16899a5 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ Several `-Z` flags are relevant for Miri: sets this flag per default. * `-Zmir-emit-retag` controls whether `Retag` statements are emitted. Miri enables this per default because it is needed for validation. -* `-Zmiri-track-pointer-tag` aborts interpretation with a backtrace when the +* `-Zmiri-track-pointer-tag=` aborts interpretation with a backtrace when the given pointer tag is popped from a borrow stack (which is where the tag becomes invalid and any future use of it will error anyway). This helps you in finding out why UB is happening and where in your code would be a good