X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Feval.rs;h=cc5a6eb21fabac1083490440533eda642d9683f7;hb=6fbaa72642dacf92746c695046c8dfe6834ef18f;hp=b0a59c64d1e16f8e027e47f30c7a7db128c5381e;hpb=82f17ab91714bcc8bd2a5591e90db690d449d38c;p=rust.git diff --git a/src/eval.rs b/src/eval.rs index b0a59c64d1e..cc5a6eb21fa 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -5,6 +5,7 @@ use rand::rngs::StdRng; use rand::SeedableRng; +use log::info; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, layout::LayoutCx, TyCtxt}; @@ -31,8 +32,10 @@ pub struct MiriConfig { pub args: Vec, /// The seed to use when non-determinism or randomness are required (e.g. ptr-to-int cast, `getrandom()`). pub seed: Option, - /// The stacked borrow id to report about + /// The stacked borrows pointer id to report about pub tracked_pointer_tag: Option, + /// The stacked borrows call ID to report about + pub tracked_call_id: Option, /// The allocation id to report about. pub tracked_alloc_id: Option, } @@ -49,6 +52,7 @@ fn default() -> MiriConfig { args: vec![], seed: None, tracked_pointer_tag: None, + tracked_call_id: None, tracked_alloc_id: None, } } @@ -63,17 +67,18 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( main_id: DefId, config: MiriConfig, ) -> InterpResult<'tcx, (InterpCx<'mir, 'tcx, Evaluator<'mir, 'tcx>>, MPlaceTy<'tcx, Tag>)> { - let tcx_at = tcx.at(rustc_span::source_map::DUMMY_SP); let param_env = ty::ParamEnv::reveal_all(); let layout_cx = LayoutCx { tcx, param_env }; let mut ecx = InterpCx::new( - tcx_at, + tcx, + rustc_span::source_map::DUMMY_SP, param_env, Evaluator::new(config.communicate, config.validate, layout_cx), MemoryExtra::new( StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.stacked_borrows, config.tracked_pointer_tag, + config.tracked_call_id, config.tracked_alloc_id, config.check_alignment, ), @@ -191,12 +196,12 @@ 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 { - // 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, - Err(mut err) => { + Err(err) => { err.print_backtrace(); panic!("Miri initialization error: {}", err.kind) } @@ -205,15 +210,31 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> // Perform the main execution. let res: InterpResult<'_, i64> = (|| { // Main loop. - while ecx.schedule()? { - assert!(ecx.step()?); - ecx.process_diagnostics(); + loop { + let info = ecx.preprocess_diagnostics(); + match ecx.schedule()? { + SchedulingAction::ExecuteStep => { + assert!(ecx.step()?, "a terminated thread was scheduled for execution"); + } + SchedulingAction::ExecuteTimeoutCallback => { + assert!(ecx.machine.communicate, + "scheduler callbacks require disabled isolation, but the code \ + that created the callback did not check it"); + ecx.run_timeout_callback()?; + } + SchedulingAction::ExecuteDtors => { + // This will either enable the thread again (so we go back + // to `ExecuteStep`), or determine that this thread is done + // for good. + ecx.schedule_next_tls_dtor_for_active_thread()?; + } + SchedulingAction::Stop => { + break; + } + } + ecx.process_diagnostics(info); } - // Read the return code pointer *before* we run TLS destructors, to assert - // that it was written to by the time that `start` lang item returned. - let return_code = ecx.read_scalar(ret_place.into())?.not_undef()?.to_machine_isize(&ecx)?; - // Global destructors. - ecx.run_tls_dtors()?; + let return_code = ecx.read_scalar(ret_place.into())?.check_init()?.to_machine_isize(&ecx)?; Ok(return_code) })(); @@ -224,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