diff options
Diffstat (limited to 'vendor/backtrace/src/symbolize/dbghelp.rs')
-rw-r--r-- | vendor/backtrace/src/symbolize/dbghelp.rs | 218 |
1 files changed, 0 insertions, 218 deletions
diff --git a/vendor/backtrace/src/symbolize/dbghelp.rs b/vendor/backtrace/src/symbolize/dbghelp.rs deleted file mode 100644 index 181dba7..0000000 --- a/vendor/backtrace/src/symbolize/dbghelp.rs +++ /dev/null @@ -1,218 +0,0 @@ -//! Symbolication strategy using `dbghelp.dll` on Windows, only used for MSVC -//! -//! This symbolication strategy, like with backtraces, uses dynamically loaded -//! information from `dbghelp.dll`. (see `src/dbghelp.rs` for info about why -//! it's dynamically loaded). -//! -//! This API selects its resolution strategy based on the frame provided or the -//! information we have at hand. If a frame from `StackWalkEx` is given to us -//! then we use similar APIs to generate correct information about inlined -//! functions. Otherwise if all we have is an address or an older stack frame -//! from `StackWalk64` we use the older APIs for symbolication. -//! -//! There's a good deal of support in this module, but a good chunk of it is -//! converting back and forth between Windows types and Rust types. For example -//! symbols come to us as wide strings which we then convert to utf-8 strings if -//! we can. - -#![allow(bad_style)] - -use super::super::{backtrace::StackFrame, dbghelp, windows::*}; -use super::{BytesOrWideString, ResolveWhat, SymbolName}; -use core::char; -use core::ffi::c_void; -use core::marker; -use core::mem; -use core::slice; - -// Store an OsString on std so we can provide the symbol name and filename. -pub struct Symbol<'a> { - name: *const [u8], - addr: *mut c_void, - line: Option<u32>, - filename: Option<*const [u16]>, - #[cfg(feature = "std")] - _filename_cache: Option<::std::ffi::OsString>, - #[cfg(not(feature = "std"))] - _filename_cache: (), - _marker: marker::PhantomData<&'a i32>, -} - -impl Symbol<'_> { - pub fn name(&self) -> Option<SymbolName<'_>> { - Some(SymbolName::new(unsafe { &*self.name })) - } - - pub fn addr(&self) -> Option<*mut c_void> { - Some(self.addr as *mut _) - } - - pub fn filename_raw(&self) -> Option<BytesOrWideString<'_>> { - self.filename - .map(|slice| unsafe { BytesOrWideString::Wide(&*slice) }) - } - - pub fn colno(&self) -> Option<u32> { - None - } - - pub fn lineno(&self) -> Option<u32> { - self.line - } - - #[cfg(feature = "std")] - pub fn filename(&self) -> Option<&::std::path::Path> { - use std::path::Path; - - self._filename_cache.as_ref().map(Path::new) - } -} - -#[repr(C, align(8))] -struct Aligned8<T>(T); - -pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol)) { - // Ensure this process's symbols are initialized - let dbghelp = match dbghelp::init() { - Ok(dbghelp) => dbghelp, - Err(()) => return, // oh well... - }; - - match what { - ResolveWhat::Address(_) => resolve_without_inline(&dbghelp, what.address_or_ip(), cb), - ResolveWhat::Frame(frame) => match &frame.inner.stack_frame { - StackFrame::New(frame) => resolve_with_inline(&dbghelp, frame, cb), - StackFrame::Old(_) => resolve_without_inline(&dbghelp, frame.ip(), cb), - }, - } -} - -unsafe fn resolve_with_inline( - dbghelp: &dbghelp::Init, - frame: &STACKFRAME_EX, - cb: &mut dyn FnMut(&super::Symbol), -) { - do_resolve( - |info| { - dbghelp.SymFromInlineContextW()( - GetCurrentProcess(), - super::adjust_ip(frame.AddrPC.Offset as *mut _) as u64, - frame.InlineFrameContext, - &mut 0, - info, - ) - }, - |line| { - dbghelp.SymGetLineFromInlineContextW()( - GetCurrentProcess(), - super::adjust_ip(frame.AddrPC.Offset as *mut _) as u64, - frame.InlineFrameContext, - 0, - &mut 0, - line, - ) - }, - cb, - ) -} - -unsafe fn resolve_without_inline( - dbghelp: &dbghelp::Init, - addr: *mut c_void, - cb: &mut dyn FnMut(&super::Symbol), -) { - do_resolve( - |info| dbghelp.SymFromAddrW()(GetCurrentProcess(), addr as DWORD64, &mut 0, info), - |line| dbghelp.SymGetLineFromAddrW64()(GetCurrentProcess(), addr as DWORD64, &mut 0, line), - cb, - ) -} - -unsafe fn do_resolve( - sym_from_addr: impl FnOnce(*mut SYMBOL_INFOW) -> BOOL, - get_line_from_addr: impl FnOnce(&mut IMAGEHLP_LINEW64) -> BOOL, - cb: &mut dyn FnMut(&super::Symbol), -) { - const SIZE: usize = 2 * MAX_SYM_NAME + mem::size_of::<SYMBOL_INFOW>(); - let mut data = Aligned8([0u8; SIZE]); - let data = &mut data.0; - let info = &mut *(data.as_mut_ptr() as *mut SYMBOL_INFOW); - info.MaxNameLen = MAX_SYM_NAME as ULONG; - // the struct size in C. the value is different to - // `size_of::<SYMBOL_INFOW>() - MAX_SYM_NAME + 1` (== 81) - // due to struct alignment. - info.SizeOfStruct = 88; - - if sym_from_addr(info) != TRUE { - return; - } - - // If the symbol name is greater than MaxNameLen, SymFromAddrW will - // give a buffer of (MaxNameLen - 1) characters and set NameLen to - // the real value. - let name_len = ::core::cmp::min(info.NameLen as usize, info.MaxNameLen as usize - 1); - let name_ptr = info.Name.as_ptr() as *const u16; - let name = slice::from_raw_parts(name_ptr, name_len); - - // Reencode the utf-16 symbol to utf-8 so we can use `SymbolName::new` like - // all other platforms - let mut name_len = 0; - let mut name_buffer = [0; 256]; - { - let mut remaining = &mut name_buffer[..]; - for c in char::decode_utf16(name.iter().cloned()) { - let c = c.unwrap_or(char::REPLACEMENT_CHARACTER); - let len = c.len_utf8(); - if len < remaining.len() { - c.encode_utf8(remaining); - let tmp = remaining; - remaining = &mut tmp[len..]; - name_len += len; - } else { - break; - } - } - } - let name = &name_buffer[..name_len] as *const [u8]; - - let mut line = mem::zeroed::<IMAGEHLP_LINEW64>(); - line.SizeOfStruct = mem::size_of::<IMAGEHLP_LINEW64>() as DWORD; - - let mut filename = None; - let mut lineno = None; - if get_line_from_addr(&mut line) == TRUE { - lineno = Some(line.LineNumber as u32); - - let base = line.FileName; - let mut len = 0; - while *base.offset(len) != 0 { - len += 1; - } - - let len = len as usize; - - filename = Some(slice::from_raw_parts(base, len) as *const [u16]); - } - - cb(&super::Symbol { - inner: Symbol { - name, - addr: info.Address as *mut _, - line: lineno, - filename, - _filename_cache: cache(filename), - _marker: marker::PhantomData, - }, - }) -} - -#[cfg(feature = "std")] -unsafe fn cache(filename: Option<*const [u16]>) -> Option<::std::ffi::OsString> { - use std::os::windows::ffi::OsStringExt; - filename.map(|f| ::std::ffi::OsString::from_wide(&*f)) -} - -#[cfg(not(feature = "std"))] -unsafe fn cache(_filename: Option<*const [u16]>) {} - -pub unsafe fn clear_symbol_cache() {} |