#![allow(bad_style)]
-use std::mem;
-use winapi::ctypes::*;
+use core::mem;
+use core::prelude::v1::*;
+
use winapi::shared::minwindef::*;
use winapi::um::processthreadsapi;
use winapi::um::winnt::{self, CONTEXT};
use winapi::um::dbghelp;
use winapi::um::dbghelp::*;
+use types::c_void;
+
pub struct Frame {
inner: STACKFRAME64,
}
}
}
-#[inline(always)]
-pub fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
- // According to windows documentation, all dbghelp functions are
- // single-threaded.
- let _g = ::lock::lock();
+#[repr(C, align(16))] // required by `CONTEXT`, is a FIXME in winapi right now
+struct MyContext(CONTEXT);
- unsafe {
- // Allocate necessary structures for doing the stack walk
- let process = processthreadsapi::GetCurrentProcess();
- let thread = processthreadsapi::GetCurrentThread();
+#[inline(always)]
+pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
+ // Allocate necessary structures for doing the stack walk
+ let process = processthreadsapi::GetCurrentProcess();
+ let thread = processthreadsapi::GetCurrentThread();
- // The CONTEXT structure needs to be aligned on a 16-byte boundary for
- // 64-bit Windows, but currently we don't have a way to express that in
- // Rust. Allocations are generally aligned to 16-bytes, though, so we
- // box this up.
- let mut context = Box::new(mem::zeroed::<CONTEXT>());
- winnt::RtlCaptureContext(&mut *context);
- let mut frame = super::Frame {
- inner: Frame { inner: mem::zeroed() },
- };
- let image = init_frame(&mut frame.inner.inner, &context);
+ let mut context = mem::zeroed::<MyContext>();
+ winnt::RtlCaptureContext(&mut context.0);
+ let mut frame = super::Frame {
+ inner: Frame { inner: mem::zeroed() },
+ };
+ let image = init_frame(&mut frame.inner.inner, &context.0);
- // Initialize this process's symbols
- let _c = ::dbghelp_init();
+ // Initialize this process's symbols
+ let _c = ::dbghelp_init();
- // And now that we're done with all the setup, do the stack walking!
- while dbghelp::StackWalk64(image as DWORD,
- process,
- thread,
- &mut frame.inner.inner,
- &mut *context as *mut _ as *mut _,
- None,
- Some(dbghelp::SymFunctionTableAccess64),
- Some(dbghelp::SymGetModuleBase64),
- None) == TRUE {
- if frame.inner.inner.AddrPC.Offset == frame.inner.inner.AddrReturn.Offset ||
- frame.inner.inner.AddrPC.Offset == 0 ||
- frame.inner.inner.AddrReturn.Offset == 0 {
- break
- }
+ // And now that we're done with all the setup, do the stack walking!
+ while dbghelp::StackWalk64(image as DWORD,
+ process,
+ thread,
+ &mut frame.inner.inner,
+ &mut context.0 as *mut CONTEXT as *mut _,
+ None,
+ Some(dbghelp::SymFunctionTableAccess64),
+ Some(dbghelp::SymGetModuleBase64),
+ None) == TRUE {
+ if frame.inner.inner.AddrPC.Offset == frame.inner.inner.AddrReturn.Offset ||
+ frame.inner.inner.AddrPC.Offset == 0 ||
+ frame.inner.inner.AddrReturn.Offset == 0 {
+ break
+ }
- if !cb(&frame) {
- break
- }
+ if !cb(&frame) {
+ break
}
}
}