1
Fork 0

print stacktrace when miri can't find the MIR for something

This commit is contained in:
Oliver Schneider 2016-09-27 17:01:06 +02:00
parent 69aeaea01f
commit db8185e439
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
4 changed files with 18 additions and 11 deletions

View file

@ -9,6 +9,7 @@ use syntax::codemap::Span;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum EvalError<'tcx> { pub enum EvalError<'tcx> {
FunctionPointerTyMismatch(&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>), FunctionPointerTyMismatch(&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>),
NoMirFor(String),
DanglingPointerDeref, DanglingPointerDeref,
InvalidMemoryAccess, InvalidMemoryAccess,
InvalidFunctionPointer, InvalidFunctionPointer,
@ -82,6 +83,8 @@ impl<'tcx> Error for EvalError<'tcx> {
"array index out of bounds", "array index out of bounds",
EvalError::Math(..) => EvalError::Math(..) =>
"mathematical operation failed", "mathematical operation failed",
EvalError::NoMirFor(..) =>
"mir not found",
EvalError::InvalidChar(..) => EvalError::InvalidChar(..) =>
"tried to interpret an invalid 32-bit value as a char", "tried to interpret an invalid 32-bit value as a char",
EvalError::OutOfMemory{..} => EvalError::OutOfMemory{..} =>
@ -113,6 +116,7 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
write!(f, "memory access of {}..{} outside bounds of allocation {} which has size {}", write!(f, "memory access of {}..{} outside bounds of allocation {} which has size {}",
ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size) ptr.offset, ptr.offset + size, ptr.alloc_id, allocation_size)
}, },
EvalError::NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
EvalError::FunctionPointerTyMismatch(expected, got) => EvalError::FunctionPointerTyMismatch(expected, got) =>
write!(f, "tried to call a function of type {:?} through a function pointer of type {:?}", expected, got), write!(f, "tried to call a function of type {:?} through a function pointer of type {:?}", expected, got),
EvalError::ArrayIndexOutOfBounds(span, len, index) => EvalError::ArrayIndexOutOfBounds(span, len, index) =>

View file

@ -267,22 +267,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP) ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP)
} }
pub fn load_mir(&self, def_id: DefId) -> CachedMir<'a, 'tcx> { pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, CachedMir<'a, 'tcx>> {
trace!("load mir {:?}", def_id);
if def_id.is_local() { if def_id.is_local() {
CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap()) Ok(CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap()))
} else { } else {
let mut mir_cache = self.mir_cache.borrow_mut(); let mut mir_cache = self.mir_cache.borrow_mut();
if let Some(mir) = mir_cache.get(&def_id) { if let Some(mir) = mir_cache.get(&def_id) {
return CachedMir::Owned(mir.clone()); return Ok(CachedMir::Owned(mir.clone()));
} }
let cs = &self.tcx.sess.cstore; let cs = &self.tcx.sess.cstore;
let mir = cs.maybe_get_item_mir(self.tcx, def_id).unwrap_or_else(|| { match cs.maybe_get_item_mir(self.tcx, def_id) {
panic!("no mir for `{}`", self.tcx.item_path_str(def_id)); Some(mir) => {
}); let cached = Rc::new(mir);
let cached = Rc::new(mir); mir_cache.insert(def_id, cached.clone());
mir_cache.insert(def_id, cached.clone()); Ok(CachedMir::Owned(cached))
CachedMir::Owned(cached) },
None => Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id))),
}
} }
} }

View file

@ -125,8 +125,8 @@ impl<'a, 'b, 'tcx> ConstantExtractor<'a, 'b, 'tcx> {
if self.ecx.statics.contains_key(&cid) { if self.ecx.statics.contains_key(&cid) {
return; return;
} }
let mir = self.ecx.load_mir(def_id);
self.try(|this| { self.try(|this| {
let mir = this.ecx.load_mir(def_id)?;
let ptr = this.ecx.alloc_ret_ptr(mir.return_ty, substs)?; let ptr = this.ecx.alloc_ret_ptr(mir.return_ty, substs)?;
this.ecx.statics.insert(cid.clone(), ptr); this.ecx.statics.insert(cid.clone(), ptr);
let cleanup = if immutable && !mir.return_ty.type_contents(this.ecx.tcx).interior_unsafe() { let cleanup = if immutable && !mir.return_ty.type_contents(this.ecx.tcx).interior_unsafe() {

View file

@ -184,7 +184,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
(def_id, substs) (def_id, substs)
}; };
let mir = self.load_mir(resolved_def_id); let mir = self.load_mir(resolved_def_id)?;
let (return_ptr, return_to_block) = match destination { let (return_ptr, return_to_block) = match destination {
Some((ptr, block)) => (Some(ptr), StackPopCleanup::Goto(block)), Some((ptr, block)) => (Some(ptr), StackPopCleanup::Goto(block)),
None => (None, StackPopCleanup::None), None => (None, StackPopCleanup::None),