Reuse the Backtrace object instead of rolling our own

This commit is contained in:
Oliver Schneider 2017-08-03 12:37:52 +02:00
parent 163821b500
commit f7bc6ab162
2 changed files with 41 additions and 28 deletions

View File

@ -1,6 +1,5 @@
use std::error::Error;
use std::fmt;
use std::path::{PathBuf, Path};
use rustc::mir;
use rustc::ty::{FnSig, Ty, layout};
@ -11,41 +10,23 @@ use super::{
use rustc_const_math::ConstMathErr;
use syntax::codemap::Span;
use backtrace::Backtrace;
#[derive(Debug)]
pub struct EvalError<'tcx> {
pub kind: EvalErrorKind<'tcx>,
pub backtrace: Vec<Frame>,
pub backtrace: Backtrace,
}
impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
fn from(kind: EvalErrorKind<'tcx>) -> Self {
let mut backtrace = Vec::new();
use backtrace::{trace, resolve};
trace(|frame| {
resolve(frame.ip(), |symbol| {
backtrace.push(Frame {
function: symbol.name().map(|s| s.to_string()).unwrap_or(String::new()),
file: symbol.filename().unwrap_or(Path::new("")).to_owned(),
line: symbol.lineno().unwrap_or(0),
});
});
true
});
EvalError {
kind,
backtrace,
backtrace: Backtrace::new(),
}
}
}
#[derive(Debug)]
pub struct Frame {
pub function: String,
pub file: PathBuf,
pub line: u32,
}
#[derive(Debug)]
pub enum EvalErrorKind<'tcx> {
/// This variant is used by machines to signal their own errors that do not

View File

@ -1705,13 +1705,45 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
pub fn report(&self, e: &EvalError) {
let mut trace_text = "\n################################\nerror occurred in miri at\n".to_string();
for frame in e.backtrace.iter().skip_while(|frame| frame.function.starts_with("backtrace::")) {
// don't report initialization gibberish
if frame.function == "miri::after_analysis" {
break;
let mut skip_init = true;
'frames: for (i, frame) in e.backtrace.frames().iter().enumerate() {
for symbol in frame.symbols() {
if let Some(name) = symbol.name() {
// unmangle the symbol via `to_string`
let name = name.to_string();
if name.starts_with("miri::after_analysis") {
// don't report initialization gibberish
break 'frames;
} else if name.starts_with("backtrace::capture::Backtrace::new")
// debug mode produces funky symbol names
|| name.starts_with("backtrace::capture::{{impl}}::new") {
// don't report backtrace internals
skip_init = false;
continue 'frames;
}
}
}
if skip_init {
continue;
}
write!(trace_text, "{}\n", i).unwrap();
for symbol in frame.symbols() {
if let Some(name) = symbol.name() {
write!(trace_text, "# {}\n", name).unwrap();
} else {
write!(trace_text, "# <unknown>\n").unwrap();
}
if let Some(file_path) = symbol.filename() {
write!(trace_text, "{}", file_path.display()).unwrap();
} else {
write!(trace_text, "<unknown_file>").unwrap();
}
if let Some(line) = symbol.lineno() {
write!(trace_text, ":{}\n", line).unwrap();
} else {
write!(trace_text, "\n").unwrap();
}
}
write!(trace_text, "# {}\n", frame.function).unwrap();
write!(trace_text, "{}:{}\n", frame.file.display(), frame.line).unwrap();
}
trace!("{}", trace_text);
if let Some(frame) = self.stack().last() {