Skip to content

Commit 80bd9cf

Browse files
authored
Merge pull request rust-lang#4651 from RalfJung/user-relevant-crates
add -Zmiri-user-relevant-crates
2 parents 3c92cf1 + 0c7ff00 commit 80bd9cf

File tree

5 files changed

+41
-26
lines changed

5 files changed

+41
-26
lines changed

src/tools/miri/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,12 @@ environment variable. We first document the most relevant and most commonly used
373373
ensure alignment. (The standard library `align_to` method works fine in both modes; under
374374
symbolic alignment it only fills the middle slice when the allocation guarantees sufficient
375375
alignment.)
376+
* `-Zmiri-user-relevant-crates=<crate>,<crate>,...` extends the list of crates that Miri considers
377+
"user-relevant". This affects the rendering of backtraces (for user-relevant crates, Miri shows
378+
not just the function name but the actual code) and it affects the spans collected for data races
379+
and aliasing violations (where Miri will show the span of the topmost non-`#[track_caller]` frame
380+
in a user-relevant crate). When using `cargo miri`, the crates in the local workspace are always
381+
considered user-relevant.
376382

377383
The remaining flags are for advanced use only, and more likely to change or be removed.
378384
Some of these are **unsound**, which means they can lead

src/tools/miri/src/bin/miri.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,8 @@ fn main() {
710710
fatal_error!("-Zmiri-force-page-size requires a power of 2: {page_size}");
711711
};
712712
miri_config.page_size = Some(page_size);
713+
} else if let Some(param) = arg.strip_prefix("-Zmiri-user-relevant-crates=") {
714+
miri_config.user_relevant_crates.extend(param.split(',').map(|s| s.to_owned()));
713715
} else {
714716
// Forward to rustc.
715717
rustc_args.push(arg);

src/tools/miri/src/eval.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ pub struct MiriConfig {
115115
pub float_rounding_error: FloatRoundingErrorMode,
116116
/// Whether Miri artifically introduces short reads/writes on file descriptors.
117117
pub short_fd_operations: bool,
118+
/// A list of crates that are considered user-relevant.
119+
pub user_relevant_crates: Vec<String>,
118120
}
119121

120122
impl Default for MiriConfig {
@@ -158,6 +160,7 @@ impl Default for MiriConfig {
158160
float_nondet: true,
159161
float_rounding_error: FloatRoundingErrorMode::Random,
160162
short_fd_operations: true,
163+
user_relevant_crates: vec![],
161164
}
162165
}
163166
}

src/tools/miri/src/helpers.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ impl<'tcx> MiriMachine<'tcx> {
10911091
/// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`.
10921092
pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool {
10931093
let def_id = frame.instance().def_id();
1094-
(def_id.is_local() || self.local_crates.contains(&def_id.krate))
1094+
(def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate))
10951095
&& !frame.instance().def.requires_caller_location(self.tcx)
10961096
}
10971097
}
@@ -1102,25 +1102,6 @@ pub fn isolation_abort_error<'tcx>(name: &str) -> InterpResult<'tcx> {
11021102
)))
11031103
}
11041104

1105-
/// Retrieve the list of local crates that should have been passed by cargo-miri in
1106-
/// MIRI_LOCAL_CRATES and turn them into `CrateNum`s.
1107-
pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
1108-
// Convert the local crate names from the passed-in config into CrateNums so that they can
1109-
// be looked up quickly during execution
1110-
let local_crate_names = std::env::var("MIRI_LOCAL_CRATES")
1111-
.map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::<Vec<_>>())
1112-
.unwrap_or_default();
1113-
let mut local_crates = Vec::new();
1114-
for &crate_num in tcx.crates(()) {
1115-
let name = tcx.crate_name(crate_num);
1116-
let name = name.as_str();
1117-
if local_crate_names.iter().any(|local_name| local_name == name) {
1118-
local_crates.push(crate_num);
1119-
}
1120-
}
1121-
local_crates
1122-
}
1123-
11241105
pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar {
11251106
// SIMD uses all-1 as pattern for "true". In two's complement,
11261107
// -1 has all its bits set to one and `from_int` will truncate or

src/tools/miri/src/machine.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,8 @@ pub struct MiriMachine<'tcx> {
580580
/// Equivalent setting as RUST_BACKTRACE on encountering an error.
581581
pub(crate) backtrace_style: BacktraceStyle,
582582

583-
/// Crates which are considered local for the purposes of error reporting.
584-
pub(crate) local_crates: Vec<CrateNum>,
583+
/// Crates which are considered user-relevant for the purposes of error reporting.
584+
pub(crate) user_relevant_crates: Vec<CrateNum>,
585585

586586
/// Mapping extern static names to their pointer.
587587
extern_statics: FxHashMap<Symbol, StrictPointer>,
@@ -684,7 +684,7 @@ impl<'tcx> MiriMachine<'tcx> {
684684
genmc_ctx: Option<Rc<GenmcCtx>>,
685685
) -> Self {
686686
let tcx = layout_cx.tcx();
687-
let local_crates = helpers::get_local_crates(tcx);
687+
let user_relevant_crates = Self::get_user_relevant_crates(tcx, config);
688688
let layouts =
689689
PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types");
690690
let profiler = config.measureme_out.as_ref().map(|out| {
@@ -774,7 +774,7 @@ impl<'tcx> MiriMachine<'tcx> {
774774
string_cache: Default::default(),
775775
exported_symbols_cache: FxHashMap::default(),
776776
backtrace_style: config.backtrace_style,
777-
local_crates,
777+
user_relevant_crates,
778778
extern_statics: FxHashMap::default(),
779779
rng: RefCell::new(rng),
780780
allocator: (!config.native_lib.is_empty())
@@ -865,6 +865,29 @@ impl<'tcx> MiriMachine<'tcx> {
865865
symbols
866866
}
867867

868+
/// Retrieve the list of user-relevant crates based on MIRI_LOCAL_CRATES as set by cargo-miri,
869+
/// and extra crates set in the config.
870+
fn get_user_relevant_crates(tcx: TyCtxt<'_>, config: &MiriConfig) -> Vec<CrateNum> {
871+
// Convert the local crate names from the passed-in config into CrateNums so that they can
872+
// be looked up quickly during execution
873+
let local_crate_names = std::env::var("MIRI_LOCAL_CRATES")
874+
.map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::<Vec<_>>())
875+
.unwrap_or_default();
876+
let mut local_crates = Vec::new();
877+
for &crate_num in tcx.crates(()) {
878+
let name = tcx.crate_name(crate_num);
879+
let name = name.as_str();
880+
if local_crate_names
881+
.iter()
882+
.chain(&config.user_relevant_crates)
883+
.any(|local_name| local_name == name)
884+
{
885+
local_crates.push(crate_num);
886+
}
887+
}
888+
local_crates
889+
}
890+
868891
pub(crate) fn late_init(
869892
ecx: &mut MiriInterpCx<'tcx>,
870893
config: &MiriConfig,
@@ -889,7 +912,7 @@ impl<'tcx> MiriMachine<'tcx> {
889912
/// Check whether the stack frame that this `FrameInfo` refers to is part of a local crate.
890913
pub(crate) fn is_local(&self, frame: &FrameInfo<'_>) -> bool {
891914
let def_id = frame.instance.def_id();
892-
def_id.is_local() || self.local_crates.contains(&def_id.krate)
915+
def_id.is_local() || self.user_relevant_crates.contains(&def_id.krate)
893916
}
894917

895918
/// 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<'_> {
10061029
string_cache: _,
10071030
exported_symbols_cache: _,
10081031
backtrace_style: _,
1009-
local_crates: _,
1032+
user_relevant_crates: _,
10101033
rng: _,
10111034
allocator: _,
10121035
tracked_alloc_ids: _,

0 commit comments

Comments
 (0)