Skip to content

Commit

Permalink
Print spans where tags are created and invalidated
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Apr 4, 2022
1 parent ec51594 commit bc98662
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 40 deletions.
38 changes: 33 additions & 5 deletions src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use log::trace;
use rustc_middle::ty;
use rustc_span::{source_map::DUMMY_SP, Span, SpanData, Symbol};

use crate::stacked_borrows::{AccessKind, SbTag};
use crate::helpers::HexRange;
use crate::stacked_borrows::{AccessKind, SbTag, TagHistory};
use crate::*;

/// Details of premature program termination.
Expand All @@ -19,6 +20,7 @@ pub enum TerminationInfo {
msg: String,
help: Option<String>,
url: String,
history: Option<TagHistory>,
},
Deadlock,
MultipleSymbolDefinitions {
Expand Down Expand Up @@ -155,12 +157,38 @@ pub fn report_error<'tcx, 'mir>(
(None, format!("pass the flag `-Zmiri-disable-isolation` to disable isolation;")),
(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")),
],
ExperimentalUb { url, help, .. } => {
ExperimentalUb { url, help, history, .. } => {
msg.extend(help.clone());
vec![
let mut helps = vec![
(None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental")),
(None, format!("see {} for further information", url))
]
(None, format!("see {} for further information", url)),
];
match history {
Some(TagHistory::Tagged {tag, created: (created_range, created_span), invalidated}) => {
let msg = format!("{:?} was created due to a retag at offsets {}", tag, HexRange(*created_range));
helps.push((Some(created_span.clone()), msg));
if let Some((invalidated_range, invalidated_span)) = invalidated {
let msg = format!("{:?} was later invalidated due to a retag at offsets {}", tag, HexRange(*invalidated_range));
helps.push((Some(invalidated_span.clone()), msg));
}
}
Some(TagHistory::Untagged{ recently_created, recently_invalidated, matching_created }) => {
if let Some((range, span)) = recently_created {
let msg = format!("tag was most recently created at offsets {}", HexRange(*range));
helps.push((Some(span.clone()), msg));
}
if let Some((range, span)) = recently_invalidated {
let msg = format!("tag was later invalidated at offsets {}", HexRange(*range));
helps.push((Some(span.clone()), msg));
}
if let Some((range, span)) = matching_created {
let msg = format!("this tag was also created here at offsets {}", HexRange(*range));
helps.push((Some(span.clone()), msg));
}
}
None => {}
}
helps
}
MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
vec![
Expand Down
21 changes: 21 additions & 0 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,24 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
Ok((ecx, ret_place))
}

// This is potentially a performance hazard.
// Factoring it into its own function lets us keep an eye on how much it shows up in a profile.
fn set_current_span<'mir, 'tcx: 'mir>(ecx: &mut MiriEvalContext<'mir, 'tcx>) {
let current_span = Machine::stack(&ecx)
.into_iter()
.rev()
.find(|frame| {
let info =
FrameInfo { instance: frame.instance, span: frame.current_span(), lint_root: None };
ecx.machine.is_local(&info)
})
.map(|frame| frame.current_span())
.unwrap_or(rustc_span::DUMMY_SP);
if let Some(sb) = ecx.memory.extra.stacked_borrows.as_mut() {
sb.get_mut().current_span = current_span;
}
}

/// Evaluates the entry function specified by `entry_id`.
/// Returns `Some(return_code)` if program executed completed.
/// Returns `None` if an evaluation error occured.
Expand Down Expand Up @@ -311,6 +329,9 @@ pub fn eval_entry<'tcx>(
let info = ecx.preprocess_diagnostics();
match ecx.schedule()? {
SchedulingAction::ExecuteStep => {
if ecx.memory.extra.stacked_borrows.is_some() {
set_current_span(&mut ecx);
}
assert!(ecx.step()?, "a terminated thread was scheduled for execution");
}
SchedulingAction::ExecuteTimeoutCallback => {
Expand Down
9 changes: 9 additions & 0 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -794,3 +794,12 @@ pub fn get_local_crates(tcx: &TyCtxt<'_>) -> Vec<CrateNum> {
}
local_crates
}

/// Formats an AllocRange like [0x1..0x3], for use in diagnostics.
pub struct HexRange(pub AllocRange);

impl std::fmt::Display for HexRange {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[{:#x}..{:#x}]", self.0.start.bytes(), self.0.end().bytes())
}
}
Loading

0 comments on commit bc98662

Please sign in to comment.