aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys/windows/backtrace
diff options
context:
space:
mode:
Diffstat (limited to 'ctr-std/src/sys/windows/backtrace')
-rw-r--r--ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs62
-rw-r--r--ctr-std/src/sys/windows/backtrace/mod.rs326
-rw-r--r--ctr-std/src/sys/windows/backtrace/printing/mod.rs34
-rw-r--r--ctr-std/src/sys/windows/backtrace/printing/msvc.rs217
4 files changed, 0 insertions, 639 deletions
diff --git a/ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs b/ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs
deleted file mode 100644
index f0d29dd..0000000
--- a/ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use sys::c;
-use libc::c_char;
-use path::PathBuf;
-use fs::{OpenOptions, File};
-use sys::ext::fs::OpenOptionsExt;
-use sys::handle::Handle;
-use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte};
-
-fn query_full_process_image_name() -> io::Result<PathBuf> {
- unsafe {
- let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION,
- c::FALSE,
- c::GetCurrentProcessId()));
- fill_utf16_buf(|buf, mut sz| {
- if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 {
- 0
- } else {
- sz
- }
- }, os2path)
- }
-}
-
-fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> {
- // We query the current image name, open the file without FILE_SHARE_DELETE so it
- // can't be moved and then get the current image name again. If the names are the
- // same than we have successfully locked the file
- let image_name1 = query_full_process_image_name()?;
- let file = OpenOptions::new()
- .read(true)
- .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE)
- .open(&image_name1)?;
- let image_name2 = query_full_process_image_name()?;
-
- if image_name1 != image_name2 {
- return Err(io::Error::new(io::ErrorKind::Other,
- "executable moved while trying to lock it"));
- }
-
- Ok((image_name1, file))
-}
-
-// Get the executable filename for libbacktrace
-// This returns the path in the ANSI code page and a File which should remain open
-// for as long as the path should remain valid
-pub fn get_executable_filename() -> io::Result<(Vec<c_char>, File)> {
- let (executable, file) = lock_and_get_executable_filename()?;
- let u16_executable = to_u16s(executable.into_os_string())?;
- Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS,
- &u16_executable, true)?, file))
-}
diff --git a/ctr-std/src/sys/windows/backtrace/mod.rs b/ctr-std/src/sys/windows/backtrace/mod.rs
deleted file mode 100644
index f64cae8..0000000
--- a/ctr-std/src/sys/windows/backtrace/mod.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! As always, windows has something very different than unix, we mainly want
-//! to avoid having to depend too much on libunwind for windows.
-//!
-//! If you google around, you'll find a fair bit of references to built-in
-//! functions to get backtraces on windows. It turns out that most of these are
-//! in an external library called dbghelp. I was unable to find this library
-//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
-//! of it.
-//!
-//! You'll also find that there's a function called CaptureStackBackTrace
-//! mentioned frequently (which is also easy to use), but sadly I didn't have a
-//! copy of that function in my mingw install (maybe it was broken?). Instead,
-//! this takes the route of using StackWalk64 in order to walk the stack.
-
-#![allow(deprecated)] // dynamic_lib
-
-use io;
-use libc::c_void;
-use mem;
-use ptr;
-use sys::c;
-use sys::dynamic_lib::DynamicLibrary;
-use sys_common::backtrace::Frame;
-
-macro_rules! sym {
- ($lib:expr, $e:expr, $t:ident) => (
- $lib.symbol($e).map(|f| unsafe {
- $crate::mem::transmute::<usize, $t>(f)
- })
- )
-}
-
-mod printing;
-
-#[cfg(target_env = "gnu")]
-#[path = "backtrace_gnu.rs"]
-pub mod gnu;
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-use self::printing::{load_printing_fns_64, load_printing_fns_ex};
-
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
- let dbghelp = DynamicLibrary::open("dbghelp.dll")?;
-
- // Fetch the symbols necessary from dbghelp.dll
- let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn)?;
- let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn)?;
-
- // StackWalkEx might not be present and we'll fall back to StackWalk64
- let sw_var = match sym!(dbghelp, "StackWalkEx", StackWalkExFn) {
- Ok(StackWalkEx) => {
- StackWalkVariant::StackWalkEx(StackWalkEx, load_printing_fns_ex(&dbghelp)?)
- }
- Err(e) => match sym!(dbghelp, "StackWalk64", StackWalk64Fn) {
- Ok(StackWalk64) => {
- StackWalkVariant::StackWalk64(StackWalk64, load_printing_fns_64(&dbghelp)?)
- }
- Err(..) => return Err(e),
- },
- };
-
- // Allocate necessary structures for doing the stack walk
- let process = unsafe { c::GetCurrentProcess() };
-
- let backtrace_context = BacktraceContext {
- handle: process,
- SymCleanup,
- StackWalkVariant: sw_var,
- dbghelp,
- };
-
- // Initialize this process's symbols
- let ret = unsafe { SymInitialize(process, ptr::null_mut(), c::TRUE) };
- if ret != c::TRUE {
- return Ok((0, backtrace_context));
- }
-
- // And now that we're done with all the setup, do the stack walking!
- match backtrace_context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(StackWalkEx, _) => {
- set_frames(StackWalkEx, frames).map(|i| (i, backtrace_context))
- }
-
- StackWalkVariant::StackWalk64(StackWalk64, _) => {
- set_frames(StackWalk64, frames).map(|i| (i, backtrace_context))
- }
- }
-}
-
-fn set_frames<W: StackWalker>(StackWalk: W, frames: &mut [Frame]) -> io::Result<usize> {
- let process = unsafe { c::GetCurrentProcess() };
- let thread = unsafe { c::GetCurrentProcess() };
- let mut context: c::CONTEXT = unsafe { mem::zeroed() };
- unsafe { c::RtlCaptureContext(&mut context) };
- let mut frame = W::Item::new();
- let image = frame.init(&context);
-
- let mut i = 0;
- while i < frames.len()
- && StackWalk.walk(image, process, thread, &mut frame, &mut context) == c::TRUE
- {
- let addr = frame.get_addr();
- frames[i] = Frame {
- symbol_addr: addr,
- exact_position: addr,
- inline_context: 0,
- };
-
- i += 1
- }
- Ok(i)
-}
-
-type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL;
-type SymCleanupFn = unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
-
-type StackWalkExFn = unsafe extern "system" fn(
- c::DWORD,
- c::HANDLE,
- c::HANDLE,
- *mut c::STACKFRAME_EX,
- *mut c::CONTEXT,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- c::DWORD,
-) -> c::BOOL;
-
-type StackWalk64Fn = unsafe extern "system" fn(
- c::DWORD,
- c::HANDLE,
- c::HANDLE,
- *mut c::STACKFRAME64,
- *mut c::CONTEXT,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- *mut c_void,
-) -> c::BOOL;
-
-trait StackWalker {
- type Item: StackFrame;
-
- fn walk(&self, c::DWORD, c::HANDLE, c::HANDLE, &mut Self::Item, &mut c::CONTEXT) -> c::BOOL;
-}
-
-impl StackWalker for StackWalkExFn {
- type Item = c::STACKFRAME_EX;
- fn walk(
- &self,
- image: c::DWORD,
- process: c::HANDLE,
- thread: c::HANDLE,
- frame: &mut Self::Item,
- context: &mut c::CONTEXT,
- ) -> c::BOOL {
- unsafe {
- self(
- image,
- process,
- thread,
- frame,
- context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- 0,
- )
- }
- }
-}
-
-impl StackWalker for StackWalk64Fn {
- type Item = c::STACKFRAME64;
- fn walk(
- &self,
- image: c::DWORD,
- process: c::HANDLE,
- thread: c::HANDLE,
- frame: &mut Self::Item,
- context: &mut c::CONTEXT,
- ) -> c::BOOL {
- unsafe {
- self(
- image,
- process,
- thread,
- frame,
- context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- )
- }
- }
-}
-
-trait StackFrame {
- fn new() -> Self;
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD;
- fn get_addr(&self) -> *const u8;
-}
-
-impl StackFrame for c::STACKFRAME_EX {
- fn new() -> c::STACKFRAME_EX {
- unsafe { mem::zeroed() }
- }
-
- #[cfg(target_arch = "x86")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Eip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Esp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Ebp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_I386
- }
-
- #[cfg(target_arch = "x86_64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Rip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Rsp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Rbp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_AMD64
- }
-
- #[cfg(target_arch = "aarch64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Pc as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Sp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Fp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_ARM64
- }
-
- fn get_addr(&self) -> *const u8 {
- (self.AddrPC.Offset - 1) as *const u8
- }
-}
-
-impl StackFrame for c::STACKFRAME64 {
- fn new() -> c::STACKFRAME64 {
- unsafe { mem::zeroed() }
- }
-
- #[cfg(target_arch = "x86")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Eip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Esp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Ebp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_I386
- }
-
- #[cfg(target_arch = "x86_64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Rip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Rsp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Rbp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_AMD64
- }
-
- #[cfg(target_arch = "aarch64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Pc as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Sp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Fp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_ARM64
- }
-
- fn get_addr(&self) -> *const u8 {
- (self.AddrPC.Offset - 1) as *const u8
- }
-}
-
-enum StackWalkVariant {
- StackWalkEx(StackWalkExFn, printing::PrintingFnsEx),
- StackWalk64(StackWalk64Fn, printing::PrintingFns64),
-}
-
-pub struct BacktraceContext {
- handle: c::HANDLE,
- SymCleanup: SymCleanupFn,
- // Only used in printing for msvc and not gnu
- // The gnu version is effectively a ZST dummy.
- #[allow(dead_code)]
- StackWalkVariant: StackWalkVariant,
- // keeping DynamycLibrary loaded until its functions no longer needed
- #[allow(dead_code)]
- dbghelp: DynamicLibrary,
-}
-
-impl Drop for BacktraceContext {
- fn drop(&mut self) {
- unsafe {
- (self.SymCleanup)(self.handle);
- }
- }
-}
diff --git a/ctr-std/src/sys/windows/backtrace/printing/mod.rs b/ctr-std/src/sys/windows/backtrace/printing/mod.rs
deleted file mode 100644
index 251d502..0000000
--- a/ctr-std/src/sys/windows/backtrace/printing/mod.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[cfg(target_env = "msvc")]
-#[path = "msvc.rs"]
-mod printing;
-
-#[cfg(target_env = "gnu")]
-mod printing {
- pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
-
- // dummy functions to mirror those present in msvc version.
- use sys::dynamic_lib::DynamicLibrary;
- use io;
- pub struct PrintingFnsEx {}
- pub struct PrintingFns64 {}
- pub fn load_printing_fns_ex(_: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
- Ok(PrintingFnsEx{})
- }
- pub fn load_printing_fns_64(_: &DynamicLibrary) -> io::Result<PrintingFns64> {
- Ok(PrintingFns64{})
- }
-}
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-pub use self::printing::{load_printing_fns_ex, load_printing_fns_64,
- PrintingFnsEx, PrintingFns64};
diff --git a/ctr-std/src/sys/windows/backtrace/printing/msvc.rs b/ctr-std/src/sys/windows/backtrace/printing/msvc.rs
deleted file mode 100644
index c8b946b..0000000
--- a/ctr-std/src/sys/windows/backtrace/printing/msvc.rs
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use ffi::CStr;
-use io;
-use libc::{c_char, c_ulong};
-use mem;
-use sys::backtrace::BacktraceContext;
-use sys::backtrace::StackWalkVariant;
-use sys::c;
-use sys::dynamic_lib::DynamicLibrary;
-use sys_common::backtrace::Frame;
-
-// Structs holding printing functions and loaders for them
-// Two versions depending on whether dbghelp.dll has StackWalkEx or not
-// (the former being in newer Windows versions, the older being in Win7 and before)
-pub struct PrintingFnsEx {
- resolve_symname: SymFromInlineContextFn,
- sym_get_line: SymGetLineFromInlineContextFn,
-}
-pub struct PrintingFns64 {
- resolve_symname: SymFromAddrFn,
- sym_get_line: SymGetLineFromAddr64Fn,
-}
-
-pub fn load_printing_fns_ex(dbghelp: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
- Ok(PrintingFnsEx {
- resolve_symname: sym!(dbghelp, "SymFromInlineContext", SymFromInlineContextFn)?,
- sym_get_line: sym!(
- dbghelp,
- "SymGetLineFromInlineContext",
- SymGetLineFromInlineContextFn
- )?,
- })
-}
-pub fn load_printing_fns_64(dbghelp: &DynamicLibrary) -> io::Result<PrintingFns64> {
- Ok(PrintingFns64 {
- resolve_symname: sym!(dbghelp, "SymFromAddr", SymFromAddrFn)?,
- sym_get_line: sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn)?,
- })
-}
-
-type SymFromAddrFn =
- unsafe extern "system" fn(c::HANDLE, u64, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-type SymFromInlineContextFn =
- unsafe extern "system" fn(c::HANDLE, u64, c::ULONG, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-
-type SymGetLineFromAddr64Fn =
- unsafe extern "system" fn(c::HANDLE, u64, *mut u32, *mut c::IMAGEHLP_LINE64) -> c::BOOL;
-type SymGetLineFromInlineContextFn = unsafe extern "system" fn(
- c::HANDLE,
- u64,
- c::ULONG,
- u64,
- *mut c::DWORD,
- *mut c::IMAGEHLP_LINE64,
-) -> c::BOOL;
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame, callback: F, context: &BacktraceContext) -> io::Result<()>
-where
- F: FnOnce(Option<&str>) -> io::Result<()>,
-{
- match context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(_, ref fns) => resolve_symname_internal(
- |process: c::HANDLE,
- symbol_address: u64,
- inline_context: c::ULONG,
- info: *mut c::SYMBOL_INFO| unsafe {
- let mut displacement = 0u64;
- (fns.resolve_symname)(
- process,
- symbol_address,
- inline_context,
- &mut displacement,
- info,
- )
- },
- frame,
- callback,
- context,
- ),
- StackWalkVariant::StackWalk64(_, ref fns) => resolve_symname_internal(
- |process: c::HANDLE,
- symbol_address: u64,
- _inline_context: c::ULONG,
- info: *mut c::SYMBOL_INFO| unsafe {
- let mut displacement = 0u64;
- (fns.resolve_symname)(process, symbol_address, &mut displacement, info)
- },
- frame,
- callback,
- context,
- ),
- }
-}
-
-fn resolve_symname_internal<F, R>(
- mut symbol_resolver: R,
- frame: Frame,
- callback: F,
- context: &BacktraceContext,
-) -> io::Result<()>
-where
- F: FnOnce(Option<&str>) -> io::Result<()>,
- R: FnMut(c::HANDLE, u64, c::ULONG, *mut c::SYMBOL_INFO) -> c::BOOL,
-{
- unsafe {
- let mut info: c::SYMBOL_INFO = mem::zeroed();
- info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
- // the struct size in C. the value is different to
- // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
- // due to struct alignment.
- info.SizeOfStruct = 88;
-
- let ret = symbol_resolver(
- context.handle,
- frame.symbol_addr as u64,
- frame.inline_context,
- &mut info,
- );
- let valid_range = if ret == c::TRUE && frame.symbol_addr as usize >= info.Address as usize {
- if info.Size != 0 {
- (frame.symbol_addr as usize) < info.Address as usize + info.Size as usize
- } else {
- true
- }
- } else {
- false
- };
- let symname = if valid_range {
- let ptr = info.Name.as_ptr() as *const c_char;
- CStr::from_ptr(ptr).to_str().ok()
- } else {
- None
- };
- callback(symname)
- }
-}
-
-pub fn foreach_symbol_fileline<F>(
- frame: Frame,
- callback: F,
- context: &BacktraceContext,
-) -> io::Result<bool>
-where
- F: FnMut(&[u8], u32) -> io::Result<()>,
-{
- match context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(_, ref fns) => foreach_symbol_fileline_iternal(
- |process: c::HANDLE,
- frame_address: u64,
- inline_context: c::ULONG,
- line: *mut c::IMAGEHLP_LINE64| unsafe {
- let mut displacement = 0u32;
- (fns.sym_get_line)(
- process,
- frame_address,
- inline_context,
- 0,
- &mut displacement,
- line,
- )
- },
- frame,
- callback,
- context,
- ),
- StackWalkVariant::StackWalk64(_, ref fns) => foreach_symbol_fileline_iternal(
- |process: c::HANDLE,
- frame_address: u64,
- _inline_context: c::ULONG,
- line: *mut c::IMAGEHLP_LINE64| unsafe {
- let mut displacement = 0u32;
- (fns.sym_get_line)(process, frame_address, &mut displacement, line)
- },
- frame,
- callback,
- context,
- ),
- }
-}
-
-fn foreach_symbol_fileline_iternal<F, G>(
- mut line_getter: G,
- frame: Frame,
- mut callback: F,
- context: &BacktraceContext,
-) -> io::Result<bool>
-where
- F: FnMut(&[u8], u32) -> io::Result<()>,
- G: FnMut(c::HANDLE, u64, c::ULONG, *mut c::IMAGEHLP_LINE64) -> c::BOOL,
-{
- unsafe {
- let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
- line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
-
- let ret = line_getter(
- context.handle,
- frame.exact_position as u64,
- frame.inline_context,
- &mut line,
- );
- if ret == c::TRUE {
- let name = CStr::from_ptr(line.Filename).to_bytes();
- callback(name, line.LineNumber as u32)?;
- }
- Ok(false)
- }
-}