Skip to content

Commit f3f7e08

Browse files
committed
Print spans where tags are created and invalidated
1 parent cf5e753 commit f3f7e08

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
@@ -283,6 +283,24 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
283283
Ok((ecx, ret_place))
284284
}
285285

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

src/helpers.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,3 +813,12 @@ pub fn get_local_crates(tcx: &TyCtxt<'_>) -> Vec<CrateNum> {
813813
}
814814
local_crates
815815
}
816+
817+
/// Formats an AllocRange like [0x1..0x3], for use in diagnostics.
818+
pub struct HexRange(pub AllocRange);
819+
820+
impl std::fmt::Display for HexRange {
821+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
822+
write!(f, "[{:#x}..{:#x}]", self.0.start.bytes(), self.0.end().bytes())
823+
}
824+
}

src/machine.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
632632
alloc_id,
633633
tag,
634634
range,
635-
machine.stacked_borrows.as_ref().unwrap(),
635+
machine.stacked_borrows.as_ref().unwrap(),
636636
)
637637
} else {
638638
Ok(())
@@ -655,7 +655,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
655655
alloc_id,
656656
tag,
657657
range,
658-
machine.stacked_borrows.as_mut().unwrap(),
658+
machine.stacked_borrows.as_ref().unwrap(),
659659
)
660660
} else {
661661
Ok(())
@@ -681,7 +681,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
681681
alloc_id,
682682
tag,
683683
range,
684-
machine.stacked_borrows.as_mut().unwrap(),
684+
machine.stacked_borrows.as_ref().unwrap(),
685685
)
686686
} else {
687687
Ok(())

0 commit comments

Comments
 (0)