only collect backtrace when RUST_BACKTRACE is set; resolve symbols lazily when printing

This commit is contained in:
Ralf Jung 2017-08-04 10:55:35 -07:00
parent 726b027ba3
commit ac49e7c650
5 changed files with 58 additions and 50 deletions

12
Cargo.lock generated
View File

@ -2,7 +2,7 @@
name = "rustc_miri"
version = "0.1.0"
dependencies = [
"backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.2 (git+https://github.com/alexcrichton/backtrace-rs)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -21,9 +21,9 @@ dependencies = [
[[package]]
name = "backtrace"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "git+https://github.com/alexcrichton/backtrace-rs#3d96a9242ed2096984d15d177f4762b699bee6d4"
dependencies = [
"backtrace-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace-sys 0.1.12 (git+https://github.com/alexcrichton/backtrace-rs)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -35,7 +35,7 @@ dependencies = [
[[package]]
name = "backtrace-sys"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "git+https://github.com/alexcrichton/backtrace-rs#3d96a9242ed2096984d15d177f4762b699bee6d4"
dependencies = [
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)",
@ -290,8 +290,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
"checksum backtrace-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "afccc5772ba333abccdf60d55200fa3406f8c59dcf54d5f7998c9107d3799c7c"
"checksum backtrace 0.3.2 (git+https://github.com/alexcrichton/backtrace-rs)" = "<none>"
"checksum backtrace-sys 0.1.12 (git+https://github.com/alexcrichton/backtrace-rs)" = "<none>"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"

View File

@ -127,8 +127,8 @@ pub fn eval_main<'a, 'tcx: 'a>(
tcx.sess.err("the evaluated program leaked memory");
}
}
Err(e) => {
ecx.report(&e);
Err(mut e) => {
ecx.report(&mut e);
}
}
}

View File

@ -17,4 +17,4 @@ log = "0.3.6"
log_settings = "0.1.1"
lazy_static = "0.2.8"
regex = "0.2.2"
backtrace = "0.3"
backtrace = { version = "0.3", git = "https://github.com/alexcrichton/backtrace-rs" }

View File

@ -1,5 +1,5 @@
use std::error::Error;
use std::fmt;
use std::{fmt, env};
use rustc::mir;
use rustc::ty::{FnSig, Ty, layout};
@ -15,14 +15,18 @@ use backtrace::Backtrace;
#[derive(Debug)]
pub struct EvalError<'tcx> {
pub kind: EvalErrorKind<'tcx>,
pub backtrace: Backtrace,
pub backtrace: Option<Backtrace>,
}
impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
fn from(kind: EvalErrorKind<'tcx>) -> Self {
let backtrace = match env::var("RUST_BACKTRACE") {
Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
_ => None
};
EvalError {
kind,
backtrace: Backtrace::new(),
backtrace,
}
}
}

View File

@ -1716,49 +1716,53 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
Ok(())
}
pub fn report(&self, e: &EvalError) {
let mut trace_text = "\n################################\nerror occurred in miri at\n".to_string();
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")
pub fn report(&self, e: &mut EvalError) {
if let Some(ref mut backtrace) = e.backtrace {
let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
let mut skip_init = true;
backtrace.resolve();
'frames: for (i, frame) in 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;
|| name.starts_with("backtrace::capture::{{impl}}::new") {
// don't report backtrace internals
skip_init = false;
continue 'frames;
}
}
}
if skip_init {
continue;
}
for symbol in frame.symbols() {
write!(trace_text, "{}: " , i).unwrap();
if let Some(name) = symbol.name() {
write!(trace_text, "{}\n", name).unwrap();
} else {
write!(trace_text, "<unknown>\n").unwrap();
}
write!(trace_text, "\tat ").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();
}
}
}
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();
}
}
error!("{}", trace_text);
}
trace!("{}", trace_text);
if let Some(frame) = self.stack().last() {
let block = &frame.mir.basic_blocks()[frame.block];
let span = if frame.stmt < block.statements.len() {