From cbb89578357d4628a7bdb3fde8d6417bcaadcdd1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Oct 2022 13:15:32 +0200 Subject: [PATCH] more details on stacked borrows tracking --- src/diagnostics.rs | 22 ++++++++++++++-------- src/stacked_borrows/mod.rs | 21 +++++++++++++++++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 868c85c04a88d..ecfe0cd3f8a65 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -60,7 +60,10 @@ impl MachineStopType for TerminationInfo {} /// Miri specific diagnostics pub enum NonHaltingDiagnostic { - CreatedPointerTag(NonZeroU64, Option<(AllocId, AllocRange)>), + /// (new_tag, new_kind, (alloc_id, base_offset, orig_tag)) + /// + /// new_kind is `None` for base tags. + CreatedPointerTag(NonZeroU64, Option, Option<(AllocId, AllocRange, ProvenanceExtra)>), /// This `Item` was popped from the borrow stack, either due to an access with the given tag or /// a deallocation when the second argument is `None`. PoppedPointerTag(Item, Option<(ProvenanceExtra, AccessKind)>), @@ -376,7 +379,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { MiriInterpCx::generate_stacktrace_from_stack(self.threads.active_thread_stack()); let (stacktrace, _was_pruned) = prune_stacktrace(stacktrace, self); - let (title, diag_level) = match e { + let (title, diag_level) = match &e { RejectedIsolatedOp(_) => ("operation rejected by isolation", DiagLevel::Warning), Int2Ptr { .. } => ("integer-to-pointer cast", DiagLevel::Warning), CreatedPointerTag(..) @@ -388,10 +391,13 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { | WeakMemoryOutdatedLoad => ("tracking was triggered", DiagLevel::Note), }; - let msg = match e { - CreatedPointerTag(tag, None) => format!("created tag {tag:?}"), - CreatedPointerTag(tag, Some((alloc_id, range))) => - format!("created tag {tag:?} at {alloc_id:?}{range:?}"), + let msg = match &e { + CreatedPointerTag(tag, None, _) => format!("created base tag {tag:?}"), + CreatedPointerTag(tag, Some(kind), None) => format!("created {tag:?} for {kind}"), + CreatedPointerTag(tag, Some(kind), Some((alloc_id, range, orig_tag))) => + format!( + "created tag {tag:?} for {kind} at {alloc_id:?}{range:?} derived from {orig_tag:?}" + ), PoppedPointerTag(item, tag) => match tag { None => format!("popped tracked tag for item {item:?} due to deallocation",), @@ -418,7 +424,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { format!("weak memory emulation: outdated value returned from load"), }; - let notes = match e { + let notes = match &e { ProgressReport { block_count } => { // It is important that each progress report is slightly different, since // identical diagnostics are being deduplicated. @@ -427,7 +433,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { _ => vec![], }; - let helps = match e { + let helps = match &e { Int2Ptr { details: true } => vec![ ( diff --git a/src/stacked_borrows/mod.rs b/src/stacked_borrows/mod.rs index f7f4b1357f106..429c6eb8ef555 100644 --- a/src/stacked_borrows/mod.rs +++ b/src/stacked_borrows/mod.rs @@ -5,6 +5,7 @@ use log::trace; use std::cell::RefCell; use std::cmp; use std::fmt; +use std::fmt::Write; use std::num::NonZeroU64; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -203,7 +204,7 @@ impl GlobalStateInner { self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| { let tag = self.new_ptr(); if self.tracked_pointer_tags.contains(&tag) { - machine.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(tag.0, None)); + machine.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(tag.0, None, None)); } trace!("New allocation {:?} has base tag {:?}", id, tag); self.base_ptr_tags.try_insert(id, tag).unwrap(); @@ -674,10 +675,26 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag -> InterpResult<'tcx> { let global = this.machine.stacked_borrows.as_ref().unwrap().borrow(); + let ty = place.layout.ty; if global.tracked_pointer_tags.contains(&new_tag) { + let mut kind_str = format!("{kind}"); + match kind { + RefKind::Unique { two_phase: false } + if !ty.is_unpin(this.tcx.at(DUMMY_SP), this.param_env()) => + { + write!(kind_str, " (!Unpin pointee type {ty})").unwrap() + }, + RefKind::Shared + if !ty.is_freeze(this.tcx.at(DUMMY_SP), this.param_env()) => + { + write!(kind_str, " (!Freeze pointee type {ty})").unwrap() + }, + _ => write!(kind_str, " (pointee type {ty})").unwrap(), + }; this.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag( new_tag.0, - loc.map(|(alloc_id, base_offset, _)| (alloc_id, alloc_range(base_offset, size))), + Some(kind_str), + loc.map(|(alloc_id, base_offset, orig_tag)| (alloc_id, alloc_range(base_offset, size), orig_tag)), )); } drop(global); // don't hold that reference any longer than we have to