auto merge of #19819 : vadimcn/rust/fix-demangle, r=alexcrichton

Windows dbghelp strips leading underscores from symbols, and I could not find a way to turn this off.  So let's accept  "ZN...E" form too.
Also, print PC displacement from symbols.  This is helpful in gauging whether the PC was indeed within the function displayed in the backtrace, or whether it just happened to be the closest public symbol in the module.
This commit is contained in:
bors 2014-12-18 14:42:06 +00:00
commit c4d58ce15b

View File

@ -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("$") {
@ -992,6 +999,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]));
}
@ -1030,4 +1040,11 @@ mod test {
t!("_ZN12test$x20test4foobE", "test test::foob");
t!("_ZN12test$UP$test4foobE", "testBoxtest::foob");
}
#[test]
fn demangle_windows() {
t!("ZN4testE", "test");
t!("ZN12test$x20test4foobE", "test test::foob");
t!("ZN12test$UP$test4foobE", "testBoxtest::foob");
}
}