diff --git a/Cargo.lock b/Cargo.lock index e33d99ed4496c..3eb598782717f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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)" = "" +"checksum backtrace-sys 0.1.12 (git+https://github.com/alexcrichton/backtrace-rs)" = "" "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" diff --git a/miri/lib.rs b/miri/lib.rs index cdccc5a9d4435..c887890fabff3 100644 --- a/miri/lib.rs +++ b/miri/lib.rs @@ -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); } } } diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 1ccb9ec0d296a..1a64bb8c7c797 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -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" } diff --git a/src/librustc_mir/interpret/error.rs b/src/librustc_mir/interpret/error.rs index 3b297ed5bd01a..f22d26ab8bf56 100644 --- a/src/librustc_mir/interpret/error.rs +++ b/src/librustc_mir/interpret/error.rs @@ -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, } impl<'tcx> From> 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, } } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 9f37b3521dcbb..6f47dd035730f 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -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; - } - 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, "# \n").unwrap(); - } - if let Some(file_path) = symbol.filename() { - write!(trace_text, "{}", file_path.display()).unwrap(); - } else { - write!(trace_text, "").unwrap(); + if skip_init { + continue; } - if let Some(line) = symbol.lineno() { - write!(trace_text, ":{}\n", line).unwrap(); - } else { - write!(trace_text, "\n").unwrap(); + 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, "\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, "").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() {