add execution time limit

This commit is contained in:
Oliver Schneider 2016-07-05 13:17:40 +02:00
parent 3e5d86bb08
commit 88d98998e1
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
4 changed files with 22 additions and 6 deletions

View file

@ -39,6 +39,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
let krate = state.hir_crate.as_ref().unwrap();
let mut memory_size = 100*1024*1024; // 100MB
let mut step_limit = 1000_000;
fn extract_str(lit: &syntax::ast::Lit) -> syntax::parse::token::InternedString {
match lit.node {
syntax::ast::LitKind::Str(ref s, _) => s.clone(),
@ -53,6 +54,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
MetaItemKind::NameValue(ref name, ref value) => {
match &**name {
"memory_size" => memory_size = extract_str(value).parse::<u64>().expect("not a number"),
"step_limit" => step_limit = extract_str(value).parse::<u64>().expect("not a number"),
_ => state.session.span_err(item.span, "unknown miri attribute"),
}
}
@ -65,7 +67,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
let mut mir_map = MirMap { map: mir_map.map.clone() };
run_mir_passes(tcx, &mut mir_map);
eval_main(tcx, &mir_map, node_id, memory_size);
eval_main(tcx, &mir_map, node_id, memory_size, step_limit);
state.session.abort_if_errors();
});

View file

@ -33,7 +33,8 @@ pub enum EvalError<'tcx> {
allocation_size: u64,
memory_size: u64,
memory_usage: u64,
}
},
ExecutionTimeLimitReached,
}
pub type EvalResult<'tcx, T> = Result<T, EvalError<'tcx>>;
@ -75,7 +76,9 @@ impl<'tcx> Error for EvalError<'tcx> {
EvalError::InvalidChar(..) =>
"tried to interpret an invalid 32-bit value as a char",
EvalError::OutOfMemory{..} =>
"could not allocate more memory"
"could not allocate more memory",
EvalError::ExecutionTimeLimitReached =>
"reached the configured maximum execution time",
}
}

View file

@ -929,6 +929,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
mir_map: &'a MirMap<'tcx>,
node_id: ast::NodeId,
memory_size: u64,
step_limit: u64,
) {
let mir = mir_map.map.get(&node_id).expect("no mir for main function");
let def_id = tcx.map.local_def_id(node_id);
@ -952,17 +953,18 @@ pub fn eval_main<'a, 'tcx: 'a>(
ecx.frame_mut().locals[1] = args;
}
loop {
for _ in 0..step_limit {
match ecx.step() {
Ok(true) => {}
Ok(false) => break,
Ok(false) => return,
// FIXME: diverging functions can end up here in some future miri
Err(e) => {
report(tcx, &ecx, e);
break;
return;
}
}
}
report(tcx, &ecx, EvalError::ExecutionTimeLimitReached);
}
fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {

View file

@ -0,0 +1,9 @@
//error-pattern: reached the configured maximum execution time
#![feature(custom_attribute)]
#![miri(step_limit="1000")]
fn main() {
for i in 0..1000000 {
assert!(i < 1000);
}
}