Skip to content

Commit fa31195

Browse files
committed
Print spans where tags are created and invalidated
1 parent be72564 commit fa31195

File tree

5 files changed

+341
-52
lines changed

5 files changed

+341
-52
lines changed

src/diagnostics.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use log::trace;
77
use rustc_middle::ty;
88
use rustc_span::{source_map::DUMMY_SP, Span, SpanData, Symbol};
99

10-
use crate::stacked_borrows::{AccessKind, SbTag};
10+
use crate::helpers::HexRange;
11+
use crate::stacked_borrows::{AccessKind, SbTag, TagHistory};
1112
use crate::*;
1213

1314
/// Details of premature program termination.
@@ -19,6 +20,7 @@ pub enum TerminationInfo {
1920
msg: String,
2021
help: Option<String>,
2122
url: String,
23+
history: Option<TagHistory>,
2224
},
2325
Deadlock,
2426
MultipleSymbolDefinitions {
@@ -155,12 +157,46 @@ pub fn report_error<'tcx, 'mir>(
155157
(None, format!("pass the flag `-Zmiri-disable-isolation` to disable isolation;")),
156158
(None, format!("or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning")),
157159
],
158-
ExperimentalUb { url, help, .. } => {
160+
ExperimentalUb { url, help, history, .. } => {
159161
msg.extend(help.clone());
160-
vec![
162+
let mut helps = vec![
161163
(None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental")),
162-
(None, format!("see {} for further information", url))
163-
]
164+
(None, format!("see {} for further information", url)),
165+
];
166+
match history {
167+
Some(TagHistory::Tagged {tag, created: (created_range, created_span), invalidated, protected }) => {
168+
let msg = format!("{:?} was created due to a retag at offsets {}", tag, HexRange(*created_range));
169+
helps.push((Some(created_span.clone()), msg));
170+
if let Some((invalidated_range, invalidated_span)) = invalidated {
171+
let msg = format!("{:?} was later invalidated due to a retag at offsets {}", tag, HexRange(*invalidated_range));
172+
helps.push((Some(invalidated_span.clone()), msg));
173+
}
174+
if let Some((protecting_tag, protecting_tag_span, protection_span)) = protected {
175+
helps.push((Some(protecting_tag_span.clone()), format!("{:?} was protected due to {:?} which was created here", tag, protecting_tag)));
176+
helps.push((Some(protection_span.clone()), "this protector is live for this call".to_string()));
177+
}
178+
}
179+
Some(TagHistory::Untagged{ recently_created, recently_invalidated, matching_created, protected }) => {
180+
if let Some((range, span)) = recently_created {
181+
let msg = format!("tag was most recently created at offsets {}", HexRange(*range));
182+
helps.push((Some(span.clone()), msg));
183+
}
184+
if let Some((range, span)) = recently_invalidated {
185+
let msg = format!("tag was later invalidated at offsets {}", HexRange(*range));
186+
helps.push((Some(span.clone()), msg));
187+
}
188+
if let Some((range, span)) = matching_created {
189+
let msg = format!("this tag was also created here at offsets {}", HexRange(*range));
190+
helps.push((Some(span.clone()), msg));
191+
}
192+
if let Some((protecting_tag, protecting_tag_span, protection_span)) = protected {
193+
helps.push((Some(protecting_tag_span.clone()), format!("{:?} was protected due to a tag which was created here", protecting_tag)));
194+
helps.push((Some(protection_span.clone()), "this protector is live for this call".to_string()));
195+
}
196+
}
197+
None => {}
198+
}
199+
helps
164200
}
165201
MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
166202
vec![

src/eval.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,24 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
282282
Ok((ecx, ret_place))
283283
}
284284

285+
// This is potentially a performance hazard.
286+
// Factoring it into its own function lets us keep an eye on how much it shows up in a profile.
287+
fn set_current_span<'mir, 'tcx: 'mir>(ecx: &mut MiriEvalContext<'mir, 'tcx>) {
288+
let current_span = Machine::stack(&ecx)
289+
.into_iter()
290+
.rev()
291+
.find(|frame| {
292+
let info =
293+
FrameInfo { instance: frame.instance, span: frame.current_span(), lint_root: None };
294+
ecx.machine.is_local(&info)
295+
})
296+
.map(|frame| frame.current_span())
297+
.unwrap_or(rustc_span::DUMMY_SP);
298+
if let Some(sb) = ecx.machine.stacked_borrows.as_mut() {
299+
sb.get_mut().current_span = current_span;
300+
}
301+
}
302+
285303
/// Evaluates the entry function specified by `entry_id`.
286304
/// Returns `Some(return_code)` if program executed completed.
287305
/// Returns `None` if an evaluation error occured.
@@ -309,6 +327,9 @@ pub fn eval_entry<'tcx>(
309327
let info = ecx.preprocess_diagnostics();
310328
match ecx.schedule()? {
311329
SchedulingAction::ExecuteStep => {
330+
if ecx.machine.stacked_borrows.is_some() {
331+
set_current_span(&mut ecx);
332+
}
312333
assert!(ecx.step()?, "a terminated thread was scheduled for execution");
313334
}
314335
SchedulingAction::ExecuteTimeoutCallback => {

src/helpers.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,3 +794,12 @@ pub fn get_local_crates(tcx: &TyCtxt<'_>) -> Vec<CrateNum> {
794794
}
795795
local_crates
796796
}
797+
798+
/// Formats an AllocRange like [0x1..0x3], for use in diagnostics.
799+
pub struct HexRange(pub AllocRange);
800+
801+
impl std::fmt::Display for HexRange {
802+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
803+
write!(f, "[{:#x}..{:#x}]", self.0.start.bytes(), self.0.end().bytes())
804+
}
805+
}

src/machine.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
619619
tag.alloc_id,
620620
tag.sb,
621621
range,
622-
machine.stacked_borrows.as_ref().unwrap(),
622+
machine.stacked_borrows.as_ref().unwrap(),
623623
)
624624
} else {
625625
Ok(())
@@ -642,7 +642,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
642642
tag.alloc_id,
643643
tag.sb,
644644
range,
645-
machine.stacked_borrows.as_mut().unwrap(),
645+
machine.stacked_borrows.as_ref().unwrap(),
646646
)
647647
} else {
648648
Ok(())
@@ -668,7 +668,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
668668
tag.alloc_id,
669669
tag.sb,
670670
range,
671-
machine.stacked_borrows.as_mut().unwrap(),
671+
machine.stacked_borrows.as_ref().unwrap(),
672672
)
673673
} else {
674674
Ok(())

0 commit comments

Comments
 (0)