about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2017-08-04 10:55:35 -0700
committerRalf Jung <post@ralfj.de>2017-08-04 10:55:35 -0700
commitac49e7c650afcff2d253a1a156592f72c44a49d2 (patch)
treeef278ea00d1c3c3b221677847202f8c6d583a950 /src
parent726b027ba3d2658d1a7796f46ea404c7299b7c0c (diff)
downloadrust-ac49e7c650afcff2d253a1a156592f72c44a49d2.tar.gz
rust-ac49e7c650afcff2d253a1a156592f72c44a49d2.zip
only collect backtrace when RUST_BACKTRACE is set; resolve symbols lazily when printing
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/Cargo.toml2
-rw-r--r--src/librustc_mir/interpret/error.rs10
-rw-r--r--src/librustc_mir/interpret/eval_context.rs76
3 files changed, 48 insertions, 40 deletions
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 1ccb9ec0d29..1a64bb8c7c7 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 3b297ed5bd0..f22d26ab8bf 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<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,
         }
     }
 }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 9f37b3521dc..6f47dd03573 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, "# <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 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, "<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();
+                    }
                 }
             }
+            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() {