TB: integration
This commit is contained in:
parent
0afab595b4
commit
8bbb0404f8
@ -32,7 +32,7 @@
|
||||
};
|
||||
use rustc_session::{config::CrateType, search_paths::PathKind, CtfeBacktrace};
|
||||
|
||||
use miri::{BacktraceStyle, ProvenanceMode, RetagFields};
|
||||
use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields};
|
||||
|
||||
struct MiriCompilerCalls {
|
||||
miri_config: miri::MiriConfig,
|
||||
@ -317,6 +317,8 @@ fn main() {
|
||||
miri_config.validate = false;
|
||||
} else if arg == "-Zmiri-disable-stacked-borrows" {
|
||||
miri_config.borrow_tracker = None;
|
||||
} else if arg == "-Zmiri-tree-borrows" {
|
||||
miri_config.borrow_tracker = Some(BorrowTrackerMethod::TreeBorrows);
|
||||
} else if arg == "-Zmiri-disable-data-race-detector" {
|
||||
miri_config.data_race_detector = false;
|
||||
miri_config.weak_memory_emulation = false;
|
||||
|
@ -22,6 +22,10 @@ pub enum TerminationInfo {
|
||||
help: Option<String>,
|
||||
history: Option<TagHistory>,
|
||||
},
|
||||
TreeBorrowsUb {
|
||||
msg: String,
|
||||
// FIXME: incomplete
|
||||
},
|
||||
Int2PtrWithStrictProvenance,
|
||||
Deadlock,
|
||||
MultipleSymbolDefinitions {
|
||||
@ -61,6 +65,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
"integer-to-pointer casts and `ptr::from_exposed_addr` are not supported with `-Zmiri-strict-provenance`"
|
||||
),
|
||||
StackedBorrowsUb { msg, .. } => write!(f, "{msg}"),
|
||||
TreeBorrowsUb { msg } => write!(f, "{msg}"),
|
||||
Deadlock => write!(f, "the evaluated program deadlocked"),
|
||||
MultipleSymbolDefinitions { link_name, .. } =>
|
||||
write!(f, "multiple definitions of symbol `{link_name}`"),
|
||||
@ -184,7 +189,8 @@ pub fn report_error<'tcx, 'mir>(
|
||||
Abort(_) => Some("abnormal termination"),
|
||||
UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance =>
|
||||
Some("unsupported operation"),
|
||||
StackedBorrowsUb { .. } | DataRace { .. } => Some("Undefined Behavior"),
|
||||
StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } =>
|
||||
Some("Undefined Behavior"),
|
||||
Deadlock => Some("deadlock"),
|
||||
MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None,
|
||||
};
|
||||
@ -212,6 +218,12 @@ pub fn report_error<'tcx, 'mir>(
|
||||
}
|
||||
}
|
||||
helps
|
||||
},
|
||||
TreeBorrowsUb { .. } => {
|
||||
let helps = vec![
|
||||
(None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental")),
|
||||
];
|
||||
helps
|
||||
}
|
||||
MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
|
||||
vec![
|
||||
|
@ -87,7 +87,7 @@ pub struct MiriConfig {
|
||||
pub env: Vec<(OsString, OsString)>,
|
||||
/// Determine if validity checking is enabled.
|
||||
pub validate: bool,
|
||||
/// Determines if Stacked Borrows is enabled.
|
||||
/// Determines if Stacked Borrows or Tree Borrows is enabled.
|
||||
pub borrow_tracker: Option<BorrowTrackerMethod>,
|
||||
/// Controls alignment checking.
|
||||
pub check_alignment: AlignmentCheck,
|
||||
@ -134,7 +134,7 @@ pub struct MiriConfig {
|
||||
pub preemption_rate: f64,
|
||||
/// Report the current instruction being executed every N basic blocks.
|
||||
pub report_progress: Option<u32>,
|
||||
/// Whether Stacked Borrows retagging should recurse into fields of datatypes.
|
||||
/// Whether Stacked Borrows and Tree Borrows retagging should recurse into fields of datatypes.
|
||||
pub retag_fields: RetagFields,
|
||||
/// The location of a shared object file to load when calling external functions
|
||||
/// FIXME! consider allowing users to specify paths to multiple SO files, or to a directory
|
||||
|
@ -95,6 +95,7 @@
|
||||
pub use crate::borrow_tracker::stacked_borrows::{
|
||||
EvalContextExt as _, Item, Permission, Stack, Stacks,
|
||||
};
|
||||
pub use crate::borrow_tracker::tree_borrows::{EvalContextExt as _, Tree};
|
||||
pub use crate::borrow_tracker::{
|
||||
BorTag, BorrowTrackerMethod, CallId, EvalContextExt as _, RetagFields,
|
||||
};
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
/// Extra data stored with each stack frame
|
||||
pub struct FrameExtra<'tcx> {
|
||||
/// Extra data for Stacked Borrows.
|
||||
/// Extra data for the Borrow Tracker.
|
||||
pub borrow_tracker: Option<borrow_tracker::FrameState>,
|
||||
|
||||
/// If this is Some(), then this is a special "catch unwind" frame (the frame of `try_fn`
|
||||
@ -146,7 +146,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
pub enum Provenance {
|
||||
Concrete {
|
||||
alloc_id: AllocId,
|
||||
/// Stacked Borrows tag.
|
||||
/// Borrow Tracker tag.
|
||||
tag: BorTag,
|
||||
},
|
||||
Wildcard,
|
||||
@ -195,7 +195,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
} else {
|
||||
write!(f, "[{alloc_id:?}]")?;
|
||||
}
|
||||
// Print Stacked Borrows tag.
|
||||
// Print Borrow Tracker tag.
|
||||
write!(f, "{tag:?}")?;
|
||||
}
|
||||
Provenance::Wildcard => {
|
||||
|
@ -232,6 +232,19 @@ fn lookup_exported_symbol(
|
||||
}
|
||||
}
|
||||
|
||||
/// Read bytes from a `(ptr, len)` argument
|
||||
fn read_byte_slice<'i>(&'i self, bytes: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, &'i [u8]>
|
||||
where
|
||||
'mir: 'i,
|
||||
{
|
||||
let this = self.eval_context_ref();
|
||||
let (ptr, len) = this.read_immediate(bytes)?.to_scalar_pair();
|
||||
let ptr = ptr.to_pointer(this)?;
|
||||
let len = len.to_target_usize(this)?;
|
||||
let bytes = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
/// Emulates calling a foreign item, failing if the item is not supported.
|
||||
/// This function will handle `goto_block` if needed.
|
||||
/// Returns Ok(None) if the foreign item was completely handled
|
||||
@ -427,13 +440,27 @@ fn emulate_foreign_item_by_name(
|
||||
})?;
|
||||
this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
|
||||
}
|
||||
"miri_print_borrow_stacks" => {
|
||||
let [id] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
"miri_print_borrow_state" => {
|
||||
let [id, show_unnamed] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let id = this.read_scalar(id)?.to_u64()?;
|
||||
let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?;
|
||||
if let Some(id) = std::num::NonZeroU64::new(id) {
|
||||
this.print_stacks(AllocId(id))?;
|
||||
this.print_borrow_state(AllocId(id), show_unnamed)?;
|
||||
}
|
||||
}
|
||||
"miri_pointer_name" => {
|
||||
// This associates a name to a tag. Very useful for debugging, and also makes
|
||||
// tests more strict.
|
||||
let [ptr, nth_parent, name] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let nth_parent = this.read_scalar(nth_parent)?.to_u8()?;
|
||||
let name = this.read_byte_slice(name)?;
|
||||
// We must make `name` owned because we need to
|
||||
// end the shared borrow from `read_byte_slice` before we can
|
||||
// start the mutable borrow for `give_pointer_debug_name`.
|
||||
let name = String::from_utf8_lossy(name).into_owned();
|
||||
this.give_pointer_debug_name(ptr, nth_parent, &name)?;
|
||||
}
|
||||
"miri_static_root" => {
|
||||
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
@ -487,12 +514,8 @@ fn emulate_foreign_item_by_name(
|
||||
// Writes some bytes to the interpreter's stdout/stderr. See the
|
||||
// README for details.
|
||||
"miri_write_to_stdout" | "miri_write_to_stderr" => {
|
||||
let [bytes] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let (ptr, len) = this.read_immediate(bytes)?.to_scalar_pair();
|
||||
let ptr = ptr.to_pointer(this)?;
|
||||
let len = len.to_target_usize(this)?;
|
||||
let msg = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?;
|
||||
|
||||
let [msg] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let msg = this.read_byte_slice(msg)?;
|
||||
// Note: we're ignoring errors writing to host stdout/stderr.
|
||||
let _ignore = match link_name.as_str() {
|
||||
"miri_write_to_stdout" => std::io::stdout().write_all(msg),
|
||||
|
Loading…
Reference in New Issue
Block a user