about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-03 12:37:52 +0200
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-03 12:37:52 +0200
commitf7bc6ab162cf5dfda7f41fa09c413e9e1908cd2b (patch)
treebf4d36e5f879b3c11049a220f85a115194f9e482 /src
parent163821b500ed953479d2b791f1f7f86bbe2f1183 (diff)
downloadrust-f7bc6ab162cf5dfda7f41fa09c413e9e1908cd2b.tar.gz
rust-f7bc6ab162cf5dfda7f41fa09c413e9e1908cd2b.zip
Reuse the `Backtrace` object instead of rolling our own
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/error.rs25
-rw-r--r--src/librustc_mir/interpret/eval_context.rs44
2 files changed, 41 insertions, 28 deletions
diff --git a/src/librustc_mir/interpret/error.rs b/src/librustc_mir/interpret/error.rs
index d487e23aa4e..3b297ed5bd0 100644
--- a/src/librustc_mir/interpret/error.rs
+++ b/src/librustc_mir/interpret/error.rs
@@ -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,42 +10,24 @@ 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
     /// match an existing variant
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 42c1bc656c3..45d1a990505 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -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() {