Merge pull request #4651 from RalfJung/user-relevant-crates

add -Zmiri-user-relevant-crates
This commit is contained in:
Ralf Jung 2025-10-27 14:24:06 +00:00 committed by GitHub
commit 80bd9cffaf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 41 additions and 26 deletions

View file

@ -373,6 +373,12 @@ environment variable. We first document the most relevant and most commonly used
ensure alignment. (The standard library `align_to` method works fine in both modes; under
symbolic alignment it only fills the middle slice when the allocation guarantees sufficient
alignment.)
* `-Zmiri-user-relevant-crates=<crate>,<crate>,...` extends the list of crates that Miri considers
"user-relevant". This affects the rendering of backtraces (for user-relevant crates, Miri shows
not just the function name but the actual code) and it affects the spans collected for data races
and aliasing violations (where Miri will show the span of the topmost non-`#[track_caller]` frame
in a user-relevant crate). When using `cargo miri`, the crates in the local workspace are always
considered user-relevant.
The remaining flags are for advanced use only, and more likely to change or be removed.
Some of these are **unsound**, which means they can lead

View file

@ -710,6 +710,8 @@ fn main() {
fatal_error!("-Zmiri-force-page-size requires a power of 2: {page_size}");
};
miri_config.page_size = Some(page_size);
} else if let Some(param) = arg.strip_prefix("-Zmiri-user-relevant-crates=") {
miri_config.user_relevant_crates.extend(param.split(',').map(|s| s.to_owned()));
} else {
// Forward to rustc.
rustc_args.push(arg);

View file

@ -115,6 +115,8 @@ pub struct MiriConfig {
pub float_rounding_error: FloatRoundingErrorMode,
/// Whether Miri artifically introduces short reads/writes on file descriptors.
pub short_fd_operations: bool,
/// A list of crates that are considered user-relevant.
pub user_relevant_crates: Vec<String>,
}
impl Default for MiriConfig {
@ -158,6 +160,7 @@ impl Default for MiriConfig {
float_nondet: true,
float_rounding_error: FloatRoundingErrorMode::Random,
short_fd_operations: true,
user_relevant_crates: vec![],
}
}
}

View file

@ -1091,7 +1091,7 @@ impl<'tcx> MiriMachine<'tcx> {
/// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`.
pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool {
let def_id = frame.instance().def_id();
(def_id.is_local() || self.local_crates.contains(&def_id.krate))
(def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate))
&& !frame.instance().def.requires_caller_location(self.tcx)
}
}
@ -1102,25 +1102,6 @@ pub fn isolation_abort_error<'tcx>(name: &str) -> InterpResult<'tcx> {
)))
}
/// Retrieve the list of local crates that should have been passed by cargo-miri in
/// MIRI_LOCAL_CRATES and turn them into `CrateNum`s.
pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
// Convert the local crate names from the passed-in config into CrateNums so that they can
// be looked up quickly during execution
let local_crate_names = std::env::var("MIRI_LOCAL_CRATES")
.map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::<Vec<_>>())
.unwrap_or_default();
let mut local_crates = Vec::new();
for &crate_num in tcx.crates(()) {
let name = tcx.crate_name(crate_num);
let name = name.as_str();
if local_crate_names.iter().any(|local_name| local_name == name) {
local_crates.push(crate_num);
}
}
local_crates
}
pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar {
// SIMD uses all-1 as pattern for "true". In two's complement,
// -1 has all its bits set to one and `from_int` will truncate or

View file

@ -580,8 +580,8 @@ pub struct MiriMachine<'tcx> {
/// Equivalent setting as RUST_BACKTRACE on encountering an error.
pub(crate) backtrace_style: BacktraceStyle,
/// Crates which are considered local for the purposes of error reporting.
pub(crate) local_crates: Vec<CrateNum>,
/// Crates which are considered user-relevant for the purposes of error reporting.
pub(crate) user_relevant_crates: Vec<CrateNum>,
/// Mapping extern static names to their pointer.
extern_statics: FxHashMap<Symbol, StrictPointer>,
@ -684,7 +684,7 @@ impl<'tcx> MiriMachine<'tcx> {
genmc_ctx: Option<Rc<GenmcCtx>>,
) -> Self {
let tcx = layout_cx.tcx();
let local_crates = helpers::get_local_crates(tcx);
let user_relevant_crates = Self::get_user_relevant_crates(tcx, config);
let layouts =
PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types");
let profiler = config.measureme_out.as_ref().map(|out| {
@ -774,7 +774,7 @@ impl<'tcx> MiriMachine<'tcx> {
string_cache: Default::default(),
exported_symbols_cache: FxHashMap::default(),
backtrace_style: config.backtrace_style,
local_crates,
user_relevant_crates,
extern_statics: FxHashMap::default(),
rng: RefCell::new(rng),
allocator: (!config.native_lib.is_empty())
@ -865,6 +865,29 @@ impl<'tcx> MiriMachine<'tcx> {
symbols
}
/// Retrieve the list of user-relevant crates based on MIRI_LOCAL_CRATES as set by cargo-miri,
/// and extra crates set in the config.
fn get_user_relevant_crates(tcx: TyCtxt<'_>, config: &MiriConfig) -> Vec<CrateNum> {
// Convert the local crate names from the passed-in config into CrateNums so that they can
// be looked up quickly during execution
let local_crate_names = std::env::var("MIRI_LOCAL_CRATES")
.map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::<Vec<_>>())
.unwrap_or_default();
let mut local_crates = Vec::new();
for &crate_num in tcx.crates(()) {
let name = tcx.crate_name(crate_num);
let name = name.as_str();
if local_crate_names
.iter()
.chain(&config.user_relevant_crates)
.any(|local_name| local_name == name)
{
local_crates.push(crate_num);
}
}
local_crates
}
pub(crate) fn late_init(
ecx: &mut MiriInterpCx<'tcx>,
config: &MiriConfig,
@ -889,7 +912,7 @@ impl<'tcx> MiriMachine<'tcx> {
/// Check whether the stack frame that this `FrameInfo` refers to is part of a local crate.
pub(crate) fn is_local(&self, frame: &FrameInfo<'_>) -> bool {
let def_id = frame.instance.def_id();
def_id.is_local() || self.local_crates.contains(&def_id.krate)
def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate)
}
/// Called when the interpreter is going to shut down abnormally, such as due to a Ctrl-C.
@ -1006,7 +1029,7 @@ impl VisitProvenance for MiriMachine<'_> {
string_cache: _,
exported_symbols_cache: _,
backtrace_style: _,
local_crates: _,
user_relevant_crates: _,
rng: _,
allocator: _,
tracked_alloc_ids: _,