add execution time limit
This commit is contained in:
parent
3e5d86bb08
commit
88d98998e1
4 changed files with 22 additions and 6 deletions
|
|
@ -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();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
9
tests/compile-fail/timeout.rs
Normal file
9
tests/compile-fail/timeout.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue