Reuse the Backtrace
object instead of rolling our own
This commit is contained in:
parent
163821b500
commit
f7bc6ab162
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user