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 aa0f3d995925..40683f8d7475 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 df8bb583f8e3..8b1739f3443b 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 e255afc3463d..e3aa75b9e880 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 8be42226b5ec..fb82679523e3 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 abed7ab9dfeb..ee13631727d2 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 65b6bcfb2ab7..3d8e724c57c3 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 23a32fc2ac5c..bd42191821b7 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 000000000000..67d38b119412 --- /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 67d38b119412..04f4f251fbaf 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 bd42191821b7..be54b7f5abab 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 04f4f251fbaf..e691603b5341 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 40683f8d7475..e2951110acdf 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 8b1739f3443b..370d2a206178 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 e3aa75b9e880..48af81296257 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 fb82679523e3..81de2fa882c5 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 3d8e724c57c3..d5cd86d97878 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 be54b7f5abab..ad70b05d8abd 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 e691603b5341..35a0f04ee6f1 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 16eae05973b2..176b4c4c342d 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 35a0f04ee6f1..000000000000 --- 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 81de2fa882c5..9a70663716d6 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 ad70b05d8abd..8782eb83d183 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 176b4c4c342d..5be16899a5ef 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