Skip to content

Commit 6cc407e

Browse files
committed
pointer tag tracking: on creation, log the offsets it is created for
1 parent 4282450 commit 6cc407e

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

src/diagnostics.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl MachineStopType for TerminationInfo {}
6767

6868
/// Miri specific diagnostics
6969
pub enum NonHaltingDiagnostic {
70-
CreatedPointerTag(NonZeroU64),
70+
CreatedPointerTag(NonZeroU64, Option<(AllocId, AllocRange)>),
7171
/// This `Item` was popped from the borrow stack, either due to an access with the given tag or
7272
/// a deallocation when the second argument is `None`.
7373
PoppedPointerTag(Item, Option<(SbTagExtra, AccessKind)>),
@@ -318,7 +318,7 @@ fn report_msg<'mir, 'tcx>(
318318
diag_level: DiagLevel,
319319
title: &str,
320320
span_msg: Vec<String>,
321-
mut helps: Vec<(Option<SpanData>, String)>,
321+
helps: Vec<(Option<SpanData>, String)>,
322322
stacktrace: &[FrameInfo<'tcx>],
323323
) {
324324
let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span);
@@ -344,15 +344,15 @@ fn report_msg<'mir, 'tcx>(
344344

345345
// Show help messages.
346346
if !helps.is_empty() {
347-
// Add visual separator before backtrace.
348-
helps.last_mut().unwrap().1.push('\n');
349347
for (span_data, help) in helps {
350348
if let Some(span_data) = span_data {
351349
err.span_help(span_data.span(), &help);
352350
} else {
353351
err.help(&help);
354352
}
355353
}
354+
// Add visual separator before backtrace.
355+
err.note("backtrace:");
356356
}
357357
// Add backtrace
358358
for (idx, frame_info) in stacktrace.iter().enumerate() {
@@ -448,7 +448,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
448448
for e in diagnostics.drain(..) {
449449
use NonHaltingDiagnostic::*;
450450
let msg = match e {
451-
CreatedPointerTag(tag) => format!("created tag {:?}", tag),
451+
CreatedPointerTag(tag, None) => format!("created tag {tag:?}"),
452+
CreatedPointerTag(tag, Some((alloc_id, range))) =>
453+
format!("created tag {tag:?} at {alloc_id}{}", HexRange(range)),
452454
PoppedPointerTag(item, tag) =>
453455
match tag {
454456
None =>

src/stacked_borrows.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,9 @@ impl GlobalStateInner {
222222
}
223223
}
224224

225+
/// Generates a new pointer tag. Remember to also check track_pointer_tags and log its creation!
225226
fn new_ptr(&mut self) -> SbTag {
226227
let id = self.next_ptr_tag;
227-
if self.tracked_pointer_tags.contains(&id) {
228-
register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(id.0));
229-
}
230228
self.next_ptr_tag = SbTag(NonZeroU64::new(id.0.get() + 1).unwrap());
231229
id
232230
}
@@ -253,6 +251,9 @@ impl GlobalStateInner {
253251
pub fn base_ptr_tag(&mut self, id: AllocId) -> SbTag {
254252
self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| {
255253
let tag = self.new_ptr();
254+
if self.tracked_pointer_tags.contains(&tag) {
255+
register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(tag.0, None));
256+
}
256257
trace!("New allocation {:?} has base tag {:?}", id, tag);
257258
self.base_ptr_tags.try_insert(id, tag).unwrap();
258259
tag
@@ -802,16 +803,28 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
802803
let this = self.eval_context_mut();
803804
let current_span = &mut this.machine.current_span();
804805

806+
// It is crucial that this gets called on all code paths, to ensure we track tag creation.
805807
let log_creation = |this: &MiriEvalContext<'mir, 'tcx>,
806808
current_span: &mut CurrentSpan<'_, 'mir, 'tcx>,
807809
alloc_id,
808810
base_offset,
809811
orig_tag|
810812
-> InterpResult<'tcx> {
813+
let global = this.machine.stacked_borrows.as_ref().unwrap().borrow();
814+
if global.tracked_pointer_tags.contains(&new_tag) {
815+
register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
816+
new_tag.0,
817+
Some((alloc_id, alloc_range(base_offset, size))),
818+
));
819+
}
820+
drop(global); // don't hold that reference any longer than we have to
821+
822+
// The SB history tracking needs a parent tag, so skip if we come from a wildcard.
811823
let SbTagExtra::Concrete(orig_tag) = orig_tag else {
812824
// FIXME: should we log this?
813825
return Ok(())
814826
};
827+
815828
let extra = this.get_alloc_extra(alloc_id)?;
816829
let mut stacked_borrows = extra
817830
.stacked_borrows
@@ -850,6 +863,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
850863
return Ok(Some(alloc_id));
851864
}
852865
// This pointer doesn't come with an AllocId. :shrug:
866+
register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(new_tag.0, None));
853867
return Ok(None);
854868
}
855869
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr)?;

0 commit comments

Comments
 (0)