Skip to content

Commit fef5fa2

Browse files
committed
add a Miri extern fn to mark an allocation as being a static root for leak checking
1 parent 4033358 commit fef5fa2

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

src/eval.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::ffi::OsStr;
55

66
use rand::rngs::StdRng;
77
use rand::SeedableRng;
8+
use log::info;
89

910
use rustc_hir::def_id::DefId;
1011
use rustc_middle::ty::{self, layout::LayoutCx, TyCtxt};
@@ -195,8 +196,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
195196
/// Returns `Some(return_code)` if program executed completed.
196197
/// Returns `None` if an evaluation error occured.
197198
pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> Option<i64> {
198-
// FIXME: on Windows, we ignore leaks (https://github.com/rust-lang/miri/issues/1302).
199-
let ignore_leaks = config.ignore_leaks || tcx.sess.target.target.target_os == "windows";
199+
// Copy setting before we move `config`.
200+
let ignore_leaks = config.ignore_leaks;
200201

201202
let (mut ecx, ret_place) = match create_ecx(tcx, main_id, config) {
202203
Ok(v) => v,
@@ -244,7 +245,8 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
244245
match res {
245246
Ok(return_code) => {
246247
if !ignore_leaks {
247-
let leaks = ecx.memory.leak_report();
248+
info!("Additonal static roots: {:?}", ecx.machine.static_roots);
249+
let leaks = ecx.memory.leak_report(&ecx.machine.static_roots);
248250
if leaks != 0 {
249251
tcx.sess.err("the evaluated program leaked memory");
250252
// Ignore the provided return code - let the reported error

src/machine.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ pub struct Evaluator<'mir, 'tcx> {
262262

263263
/// Precomputed `TyLayout`s for primitive data types that are commonly used inside Miri.
264264
pub(crate) layouts: PrimitiveLayouts<'tcx>,
265+
266+
/// Allocations that are considered roots of static memory (that may leak).
267+
pub(crate) static_roots: Vec<AllocId>,
265268
}
266269

267270
impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
@@ -289,6 +292,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
289292
time_anchor: Instant::now(),
290293
layouts,
291294
threads: ThreadManager::default(),
295+
static_roots: Vec::new(),
292296
}
293297
}
294298
}

src/shims/foreign_items.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
197197
// Here we dispatch all the shims for foreign functions. If you have a platform specific
198198
// shim, add it to the corresponding submodule.
199199
match link_name {
200+
// Miri-specific extern functions
201+
"miri_static_root" => {
202+
let &[ptr] = check_arg_count(args)?;
203+
let ptr = this.read_scalar(ptr)?.not_undef()?;
204+
let ptr = this.force_ptr(ptr)?;
205+
if ptr.offset != Size::ZERO {
206+
throw_unsup_format!("Pointer passed to miri_static_root must point to beginning of an allocated block");
207+
}
208+
this.machine.static_roots.push(ptr.alloc_id);
209+
}
210+
200211
// Standard C allocation
201212
"malloc" => {
202213
let &[size] = check_arg_count(args)?;

0 commit comments

Comments
 (0)