use new MachineStop error variant

This commit is contained in:
Ralf Jung 2019-12-02 09:05:35 +01:00
parent cde718f083
commit f3c00a447c
4 changed files with 20 additions and 5 deletions

View file

@ -1 +1 @@
4007d4ef26eab44bdabc2b7574d032152264d3ad
f5c81e0a986e4285d3d0fd781a1bd475753eb12c

View file

@ -24,6 +24,12 @@ pub struct MiriConfig {
pub seed: Option<u64>,
}
/// 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::<TerminationInfo>()
.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()

View file

@ -47,7 +47,7 @@ pub use crate::machine::{
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.

View file

@ -152,9 +152,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
"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 {