Skip to content

Commit c4d58ce

Browse files
committed
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.
2 parents 2a23159 + b3b7185 commit c4d58ce

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("$") {
@@ -992,6 +999,9 @@ mod imp {
992999
Some(s) => try!(super::demangle(w, s)),
9931000
None => try!(w.write(bytes[..bytes.len()-1])),
9941001
}
1002+
if displacement != 0 {
1003+
try!(write!(w, "+{:#x}", displacement));
1004+
}
9951005
}
9961006
try!(w.write(&['\n' as u8]));
9971007
}
@@ -1030,4 +1040,11 @@ mod test {
10301040
t!("_ZN12test$x20test4foobE", "test test::foob");
10311041
t!("_ZN12test$UP$test4foobE", "testBoxtest::foob");
10321042
}
1043+
1044+
#[test]
1045+
fn demangle_windows() {
1046+
t!("ZN4testE", "test");
1047+
t!("ZN12test$x20test4foobE", "test test::foob");
1048+
t!("ZN12test$UP$test4foobE", "testBoxtest::foob");
1049+
}
10331050
}

0 commit comments

Comments
 (0)