]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/windows/backtrace/printing/msvc.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / libstd / sys / windows / backtrace / printing / msvc.rs
CommitLineData
8bb4bdeb
XL
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
11use ffi::CStr;
12use io;
abe05a73 13use libc::{c_ulong, c_char};
8bb4bdeb
XL
14use mem;
15use sys::c;
16use sys::backtrace::BacktraceContext;
17use sys_common::backtrace::Frame;
18
19type SymFromAddrFn =
20 unsafe extern "system" fn(c::HANDLE, u64, *mut u64,
21 *mut c::SYMBOL_INFO) -> c::BOOL;
22type SymGetLineFromAddr64Fn =
23 unsafe extern "system" fn(c::HANDLE, u64, *mut u32,
24 *mut c::IMAGEHLP_LINE64) -> c::BOOL;
25
26/// Converts a pointer to symbol to its string value.
27pub fn resolve_symname<F>(frame: Frame,
28 callback: F,
29 context: &BacktraceContext) -> io::Result<()>
30 where F: FnOnce(Option<&str>) -> io::Result<()>
31{
32 let SymFromAddr = sym!(&context.dbghelp, "SymFromAddr", SymFromAddrFn)?;
33
34 unsafe {
35 let mut info: c::SYMBOL_INFO = mem::zeroed();
36 info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
37 // the struct size in C. the value is different to
38 // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
39 // due to struct alignment.
40 info.SizeOfStruct = 88;
41
42 let mut displacement = 0u64;
43 let ret = SymFromAddr(context.handle,
44 frame.symbol_addr as u64,
45 &mut displacement,
46 &mut info);
47
48 let symname = if ret == c::TRUE {
49 let ptr = info.Name.as_ptr() as *const c_char;
50 CStr::from_ptr(ptr).to_str().ok()
51 } else {
52 None
53 };
54 callback(symname)
55 }
56}
57
58pub fn foreach_symbol_fileline<F>(frame: Frame,
59 mut f: F,
60 context: &BacktraceContext)
61 -> io::Result<bool>
abe05a73 62 where F: FnMut(&[u8], u32) -> io::Result<()>
8bb4bdeb
XL
63{
64 let SymGetLineFromAddr64 = sym!(&context.dbghelp,
65 "SymGetLineFromAddr64",
66 SymGetLineFromAddr64Fn)?;
67
68 unsafe {
69 let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
70 line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
71
72 let mut displacement = 0u32;
73 let ret = SymGetLineFromAddr64(context.handle,
74 frame.exact_position as u64,
75 &mut displacement,
76 &mut line);
77 if ret == c::TRUE {
78 let name = CStr::from_ptr(line.Filename).to_bytes();
abe05a73 79 f(name, line.LineNumber as u32)?;
8bb4bdeb
XL
80 }
81 Ok(false)
82 }
83}