Skip to content

Commit 2ad417e

Browse files
committed
Print spans where tags are created and invalidated
1 parent 65125df commit 2ad417e

File tree

4 files changed

+256
-40
lines changed

4 files changed

+256
-40
lines changed

src/diagnostics.rs

Lines changed: 33 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,38 @@ 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}) => {
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+
}
175+
Some(TagHistory::Untagged{ recently_created, recently_invalidated, matching_created }) => {
176+
if let Some((range, span)) = recently_created {
177+
let msg = format!("tag was most recently created at offsets {}", HexRange(*range));
178+
helps.push((Some(span.clone()), msg));
179+
}
180+
if let Some((range, span)) = recently_invalidated {
181+
let msg = format!("tag was later invalidated at offsets {}", HexRange(*range));
182+
helps.push((Some(span.clone()), msg));
183+
}
184+
if let Some((range, span)) = matching_created {
185+
let msg = format!("this tag was also created here at offsets {}", HexRange(*range));
186+
helps.push((Some(span.clone()), msg));
187+
}
188+
}
189+
None => {}
190+
}
191+
helps
164192
}
165193
MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
166194
vec![

src/eval.rs

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

282+
// This is potentially a performance hazard.
283+
// Factoring it into its own function lets us keep an eye on how much it shows up in a profile.
284+
fn set_current_span<'mir, 'tcx: 'mir>(ecx: &mut MiriEvalContext<'mir, 'tcx>) {
285+
let current_span = Machine::stack(&ecx)
286+
.into_iter()
287+
.rev()
288+
.find(|frame| {
289+
let info =
290+
FrameInfo { instance: frame.instance, span: frame.current_span(), lint_root: None };
291+
ecx.machine.is_local(&info)
292+
})
293+
.map(|frame| frame.current_span())
294+
.unwrap_or(rustc_span::DUMMY_SP);
295+
if let Some(sb) = ecx.memory.extra.stacked_borrows.as_mut() {
296+
sb.get_mut().current_span = current_span;
297+
}
298+
}
299+
282300
/// Evaluates the entry function specified by `entry_id`.
283301
/// Returns `Some(return_code)` if program executed completed.
284302
/// Returns `None` if an evaluation error occured.
@@ -306,6 +324,9 @@ pub fn eval_entry<'tcx>(
306324
let info = ecx.preprocess_diagnostics();
307325
match ecx.schedule()? {
308326
SchedulingAction::ExecuteStep => {
327+
if ecx.memory.extra.stacked_borrows.is_some() {
328+
set_current_span(&mut ecx);
329+
}
309330
assert!(ecx.step()?, "a terminated thread was scheduled for execution");
310331
}
311332
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+
}

0 commit comments

Comments
 (0)