diff --git a/rust-version b/rust-version index 43425c9afc58..3a0cf96e1327 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -4007d4ef26eab44bdabc2b7574d032152264d3ad +f5c81e0a986e4285d3d0fd781a1bd475753eb12c diff --git a/src/eval.rs b/src/eval.rs index 986c6143ab4d..2c165760418f 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -24,6 +24,12 @@ pub struct MiriConfig { pub seed: Option, } +/// Details of premature program termination. +pub enum TerminationInfo { + Exit(i64), + Abort, +} + /// Returns a freshly created `InterpCx`, along with an `MPlaceTy` representing /// the location where the return value of the `start` lang item will be /// written to. @@ -200,7 +206,15 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> Err(mut e) => { // Special treatment for some error kinds let msg = match e.kind { - InterpError::Exit(code) => return Some(code.into()), + InterpError::MachineStop(ref info) => { + let info = info.downcast_ref::() + .expect("invalid MachineStop payload"); + match info { + TerminationInfo::Exit(code) => return Some(*code), + TerminationInfo::Abort => + format!("The program aborted execution") + } + } err_unsup!(NoMirFor(..)) => format!("{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.", e), _ => e.to_string() diff --git a/src/lib.rs b/src/lib.rs index f29ec8f22bba..05234e880f58 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,7 @@ PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS, MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt, }; -pub use crate::eval::{eval_main, create_ecx, MiriConfig}; +pub use crate::eval::{eval_main, create_ecx, MiriConfig, TerminationInfo}; /// Insert rustc arguments at the beginning of the argument list that Miri wants to be /// set per default, for maximal validation power. diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index b9e6734613c0..114931e435a4 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -152,9 +152,10 @@ fn emulate_foreign_item( } "exit" | "ExitProcess" => { - // it's really u32 for ExitProcess, but we have to put it into the `Exit` error variant anyway + // it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway let code = this.read_scalar(args[0])?.to_i32()?; - return Err(InterpError::Exit(code).into()); + let ti = Box::new(TerminationInfo::Exit(code.into())); + return Err(InterpError::MachineStop(ti).into()); } _ => { if let Some(p) = ret {