add a Miri extern fn to mark an allocation as being a static root for leak checking
This commit is contained in:
parent
4033358956
commit
fef5fa2ae1
3 changed files with 20 additions and 3 deletions
|
|
@ -5,6 +5,7 @@ use std::ffi::OsStr;
|
|||
|
||||
use rand::rngs::StdRng;
|
||||
use rand::SeedableRng;
|
||||
use log::info;
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::{self, layout::LayoutCx, TyCtxt};
|
||||
|
|
@ -195,8 +196,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||
/// Returns `Some(return_code)` if program executed completed.
|
||||
/// Returns `None` if an evaluation error occured.
|
||||
pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> Option<i64> {
|
||||
// FIXME: on Windows, we ignore leaks (https://github.com/rust-lang/miri/issues/1302).
|
||||
let ignore_leaks = config.ignore_leaks || tcx.sess.target.target.target_os == "windows";
|
||||
// Copy setting before we move `config`.
|
||||
let ignore_leaks = config.ignore_leaks;
|
||||
|
||||
let (mut ecx, ret_place) = match create_ecx(tcx, main_id, config) {
|
||||
Ok(v) => v,
|
||||
|
|
@ -244,7 +245,8 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
|
|||
match res {
|
||||
Ok(return_code) => {
|
||||
if !ignore_leaks {
|
||||
let leaks = ecx.memory.leak_report();
|
||||
info!("Additonal static roots: {:?}", ecx.machine.static_roots);
|
||||
let leaks = ecx.memory.leak_report(&ecx.machine.static_roots);
|
||||
if leaks != 0 {
|
||||
tcx.sess.err("the evaluated program leaked memory");
|
||||
// Ignore the provided return code - let the reported error
|
||||
|
|
|
|||
|
|
@ -262,6 +262,9 @@ pub struct Evaluator<'mir, 'tcx> {
|
|||
|
||||
/// Precomputed `TyLayout`s for primitive data types that are commonly used inside Miri.
|
||||
pub(crate) layouts: PrimitiveLayouts<'tcx>,
|
||||
|
||||
/// Allocations that are considered roots of static memory (that may leak).
|
||||
pub(crate) static_roots: Vec<AllocId>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
|
||||
|
|
@ -289,6 +292,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
|
|||
time_anchor: Instant::now(),
|
||||
layouts,
|
||||
threads: ThreadManager::default(),
|
||||
static_roots: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,6 +197,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
// Here we dispatch all the shims for foreign functions. If you have a platform specific
|
||||
// shim, add it to the corresponding submodule.
|
||||
match link_name {
|
||||
// Miri-specific extern functions
|
||||
"miri_static_root" => {
|
||||
let &[ptr] = check_arg_count(args)?;
|
||||
let ptr = this.read_scalar(ptr)?.not_undef()?;
|
||||
let ptr = this.force_ptr(ptr)?;
|
||||
if ptr.offset != Size::ZERO {
|
||||
throw_unsup_format!("Pointer passed to miri_static_root must point to beginning of an allocated block");
|
||||
}
|
||||
this.machine.static_roots.push(ptr.alloc_id);
|
||||
}
|
||||
|
||||
// Standard C allocation
|
||||
"malloc" => {
|
||||
let &[size] = check_arg_count(args)?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue