diff options
| author | Vadim Chugunov <vadimcn@gmail.com> | 2014-12-13 00:13:19 -0800 |
|---|---|---|
| committer | Vadim Chugunov <vadimcn@gmail.com> | 2014-12-13 14:16:53 -0800 |
| commit | 317d91261b970bca7dbb38c54acde4a1f5406aaa (patch) | |
| tree | 51d1266426871268d7fbdca954947859ae08554c /src/libstd/rt | |
| parent | a5921241a3146cccaffc336a0d1ade1a90e3517f (diff) | |
| download | rust-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.rs | 33 |
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"); + } } |
