Skip to content

Commit da18143

Browse files
committed
Merge pull request #19819 from vadimcn/fix-demangle
Fix symbol demangling on Windows. Reviewed-by: alexcrichton
2 parents 5f3ce88 + 317d912 commit da18143

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/libstd/rt/backtrace.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,18 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
6666
// expecting, we just print it literally. Note that we must handle non-rust
6767
// symbols because we could have any function in the backtrace.
6868
let mut valid = true;
69+
let mut inner = s;
6970
if s.len() > 4 && s.starts_with("_ZN") && s.ends_with("E") {
70-
let mut chars = s.slice(3, s.len() - 1).chars();
71+
inner = s.slice(3, s.len() - 1);
72+
// On Windows, dbghelp strips leading underscores, so we accept "ZN...E" form too.
73+
} else if s.len() > 3 && s.starts_with("ZN") && s.ends_with("E") {
74+
inner = s.slice(2, s.len() - 1);
75+
} else {
76+
valid = false;
77+
}
78+
79+
if valid {
80+
let mut chars = inner.chars();
7181
while valid {
7282
let mut i = 0;
7383
for c in chars {
@@ -84,28 +94,25 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
8494
valid = false;
8595
}
8696
}
87-
} else {
88-
valid = false;
8997
}
9098

9199
// Alright, let's do this.
92100
if !valid {
93101
try!(writer.write_str(s));
94102
} else {
95-
let mut s = s.slice_from(3);
96103
let mut first = true;
97-
while s.len() > 1 {
104+
while inner.len() > 0 {
98105
if !first {
99106
try!(writer.write_str("::"));
100107
} else {
101108
first = false;
102109
}
103-
let mut rest = s;
110+
let mut rest = inner;
104111
while rest.char_at(0).is_numeric() {
105112
rest = rest.slice_from(1);
106113
}
107-
let i: uint = from_str(s.slice_to(s.len() - rest.len())).unwrap();
108-
s = rest.slice_from(i);
114+
let i: uint = from_str(inner.slice_to(inner.len() - rest.len())).unwrap();
115+
inner = rest.slice_from(i);
109116
rest = rest.slice_to(i);
110117
while rest.len() > 0 {
111118
if rest.starts_with("$") {
@@ -999,6 +1006,9 @@ mod imp {
9991006
Some(s) => try!(super::demangle(w, s)),
10001007
None => try!(w.write(bytes[..bytes.len()-1])),
10011008
}
1009+
if displacement != 0 {
1010+
try!(write!(w, "+{:#x}", displacement));
1011+
}
10021012
}
10031013
try!(w.write(&['\n' as u8]));
10041014
}
@@ -1037,4 +1047,11 @@ mod test {
10371047
t!("_ZN12test$x20test4foobE", "test test::foob");
10381048
t!("_ZN12test$UP$test4foobE", "testBoxtest::foob");
10391049
}
1050+
1051+
#[test]
1052+
fn demangle_windows() {
1053+
t!("yZN4testE", "test");
1054+
t!("ZN12test$x20test4foobE", "test test::foob");
1055+
t!("ZN12test$UP$test4foobE", "testBoxtest::foob");
1056+
}
10401057
}

0 commit comments

Comments
 (0)