about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorVadim Chugunov <vadimcn@gmail.com>2014-12-13 00:13:19 -0800
committerVadim Chugunov <vadimcn@gmail.com>2014-12-13 14:16:53 -0800
commit317d91261b970bca7dbb38c54acde4a1f5406aaa (patch)
tree51d1266426871268d7fbdca954947859ae08554c /src/libstd/rt
parenta5921241a3146cccaffc336a0d1ade1a90e3517f (diff)
downloadrust-317d91261b970bca7dbb38c54acde4a1f5406aaa.tar.gz
rust-317d91261b970bca7dbb38c54acde4a1f5406aaa.zip
Windows dbghelp strips leading underscores from symbols, so let's accept "ZN...E" form too.
Also, print PC displacement from symbols.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/backtrace.rs33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 4ac09a071bb..a5c6d180dd9 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -66,8 +66,18 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
     // expecting, we just print it literally. Note that we must handle non-rust
     // symbols because we could have any function in the backtrace.
     let mut valid = true;
+    let mut inner = s;
     if s.len() > 4 && s.starts_with("_ZN") && s.ends_with("E") {
-        let mut chars = s.slice(3, s.len() - 1).chars();
+        inner = s.slice(3, s.len() - 1);
+    // On Windows, dbghelp strips leading underscores, so we accept "ZN...E" form too.
+    } else if s.len() > 3 && s.starts_with("ZN") && s.ends_with("E") {
+        inner = s.slice(2, s.len() - 1);
+    } else {
+        valid = false;
+    }
+
+    if valid {
+        let mut chars = inner.chars();
         while valid {
             let mut i = 0;
             for c in chars {
@@ -84,28 +94,25 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
                 valid = false;
             }
         }
-    } else {
-        valid = false;
     }
 
     // Alright, let's do this.
     if !valid {
         try!(writer.write_str(s));
     } else {
-        let mut s = s.slice_from(3);
         let mut first = true;
-        while s.len() > 1 {
+        while inner.len() > 0 {
             if !first {
                 try!(writer.write_str("::"));
             } else {
                 first = false;
             }
-            let mut rest = s;
+            let mut rest = inner;
             while rest.char_at(0).is_numeric() {
                 rest = rest.slice_from(1);
             }
-            let i: uint = from_str(s.slice_to(s.len() - rest.len())).unwrap();
-            s = rest.slice_from(i);
+            let i: uint = from_str(inner.slice_to(inner.len() - rest.len())).unwrap();
+            inner = rest.slice_from(i);
             rest = rest.slice_to(i);
             while rest.len() > 0 {
                 if rest.starts_with("$") {
@@ -999,6 +1006,9 @@ mod imp {
                     Some(s) => try!(super::demangle(w, s)),
                     None => try!(w.write(bytes[..bytes.len()-1])),
                 }
+                if displacement != 0 {
+                    try!(write!(w, "+{:#x}", displacement));
+                }
             }
             try!(w.write(&['\n' as u8]));
         }
@@ -1037,4 +1047,11 @@ mod test {
         t!("_ZN12test$x20test4foobE", "test test::foob");
         t!("_ZN12test$UP$test4foobE", "testBoxtest::foob");
     }
+
+    #[test]
+    fn demangle_windows() {
+        t!("yZN4testE", "test");
+        t!("ZN12test$x20test4foobE", "test test::foob");
+        t!("ZN12test$UP$test4foobE", "testBoxtest::foob");
+    }
 }