]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
b039eaaf SL |
11 | #![allow(deprecated)] |
12 | ||
e9174d1e | 13 | use dynamic_lib::DynamicLibrary; |
92a42be0 | 14 | use ffi::CStr; |
e9174d1e | 15 | use io::prelude::*; |
92a42be0 SL |
16 | use io; |
17 | use libc::{c_ulong, c_int, c_char, c_void}; | |
18 | use mem; | |
92a42be0 SL |
19 | use sys::c; |
20 | use sys_common::backtrace::{output, output_fileline}; | |
e9174d1e | 21 | |
7453a54e SL |
22 | type SymFromAddrFn = |
23 | extern "system" fn(c::HANDLE, u64, *mut u64, | |
24 | *mut c::SYMBOL_INFO) -> c::BOOL; | |
25 | type SymGetLineFromAddr64Fn = | |
26 | extern "system" fn(c::HANDLE, u64, *mut u32, | |
27 | *mut c::IMAGEHLP_LINE64) -> c::BOOL; | |
28 | ||
92a42be0 SL |
29 | pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, |
30 | process: c::HANDLE) -> io::Result<()> { | |
e9174d1e SL |
31 | let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn); |
32 | let SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn); | |
33 | ||
92a42be0 SL |
34 | let mut info: c::SYMBOL_INFO = unsafe { mem::zeroed() }; |
35 | info.MaxNameLen = c::MAX_SYM_NAME as c_ulong; | |
e9174d1e SL |
36 | // the struct size in C. the value is different to |
37 | // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81) | |
38 | // due to struct alignment. | |
39 | info.SizeOfStruct = 88; | |
40 | ||
41 | let mut displacement = 0u64; | |
42 | let ret = SymFromAddr(process, addr, &mut displacement, &mut info); | |
43 | ||
92a42be0 SL |
44 | let name = if ret == c::TRUE { |
45 | let ptr = info.Name.as_ptr() as *const c_char; | |
e9174d1e SL |
46 | Some(unsafe { CStr::from_ptr(ptr).to_bytes() }) |
47 | } else { | |
48 | None | |
49 | }; | |
50 | ||
92a42be0 | 51 | try!(output(w, i, addr as usize as *mut c_void, name)); |
e9174d1e SL |
52 | |
53 | // Now find out the filename and line number | |
92a42be0 SL |
54 | let mut line: c::IMAGEHLP_LINE64 = unsafe { mem::zeroed() }; |
55 | line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32; | |
e9174d1e SL |
56 | |
57 | let mut displacement = 0u32; | |
58 | let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line); | |
92a42be0 | 59 | if ret == c::TRUE { |
e9174d1e SL |
60 | output_fileline(w, |
61 | unsafe { CStr::from_ptr(line.Filename).to_bytes() }, | |
92a42be0 | 62 | line.LineNumber as c_int, |
e9174d1e SL |
63 | false) |
64 | } else { | |
65 | Ok(()) | |
66 | } | |
67 | } |