Skip to content

Commit 7008740

Browse files
authored
Merge pull request #735 from workingjubilee/get-current-process-once
GetCurrentProcess only once in win32 backtrace
2 parents 7b1be4c + d4738cc commit 7008740

File tree

1 file changed

+42
-36
lines changed

1 file changed

+42
-36
lines changed

src/backtrace/win32.rs

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//!
99
//! Note that all dbghelp support is loaded dynamically, see `src/dbghelp.rs`
1010
//! for more information about that.
11+
#![deny(unsafe_op_in_unsafe_fn)]
1112

1213
use super::super::{dbghelp, windows_sys::*};
1314
use core::ffi::c_void;
@@ -97,11 +98,12 @@ struct MyContext(CONTEXT);
9798
#[inline(always)]
9899
pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
99100
// Allocate necessary structures for doing the stack walk
100-
let process = GetCurrentProcess();
101-
let thread = GetCurrentThread();
101+
let process = unsafe { GetCurrentProcess() };
102+
let thread = unsafe { GetCurrentThread() };
102103

103-
let mut context = mem::zeroed::<MyContext>();
104-
RtlCaptureContext(&mut context.0);
104+
// This is a classic C-style out-ptr struct. Zero it to start.
105+
let mut context = unsafe { mem::zeroed::<MyContext>() };
106+
unsafe { RtlCaptureContext(&mut context.0) };
105107

106108
// Ensure this process's symbols are initialized
107109
let dbghelp = match dbghelp::init() {
@@ -112,14 +114,13 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
112114
let function_table_access = dbghelp.SymFunctionTableAccess64();
113115
let get_module_base = dbghelp.SymGetModuleBase64();
114116

115-
let process_handle = GetCurrentProcess();
116-
117117
// Attempt to use `StackWalkEx` if we can, but fall back to `StackWalk64`
118118
// since it's in theory supported on more systems.
119-
match (*dbghelp.dbghelp()).StackWalkEx() {
119+
match unsafe { (*dbghelp.dbghelp()).StackWalkEx() } {
120120
#[allow(non_snake_case)]
121121
Some(StackWalkEx) => {
122-
let mut inner: STACKFRAME_EX = mem::zeroed();
122+
// This is a classic C-style out-ptr struct. Zero it to start.
123+
let mut inner: STACKFRAME_EX = unsafe { mem::zeroed() };
123124
inner.StackFrameSize = mem::size_of::<STACKFRAME_EX>() as u32;
124125
let mut frame = super::Frame {
125126
inner: Frame {
@@ -133,20 +134,22 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
133134
_ => unreachable!(),
134135
};
135136

136-
while StackWalkEx(
137-
image as u32,
138-
process,
139-
thread,
140-
frame_ptr,
141-
&mut context.0 as *mut CONTEXT as *mut _,
142-
None,
143-
Some(function_table_access),
144-
Some(get_module_base),
145-
None,
146-
0,
147-
) == TRUE
148-
{
149-
frame.inner.base_address = get_module_base(process_handle, frame.ip() as _) as _;
137+
while unsafe {
138+
StackWalkEx(
139+
image as u32,
140+
process,
141+
thread,
142+
frame_ptr,
143+
&mut context.0 as *mut CONTEXT as *mut _,
144+
None,
145+
Some(function_table_access),
146+
Some(get_module_base),
147+
None,
148+
0,
149+
) == TRUE
150+
} {
151+
frame.inner.base_address =
152+
unsafe { get_module_base(process, frame.ip() as _) as _ };
150153

151154
if !cb(&frame) {
152155
break;
@@ -156,7 +159,8 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
156159
None => {
157160
let mut frame = super::Frame {
158161
inner: Frame {
159-
stack_frame: StackFrame::Old(mem::zeroed()),
162+
// This is a classic C-style out-ptr struct. Zero it to start.
163+
stack_frame: StackFrame::Old(unsafe { mem::zeroed() }),
160164
base_address: 0 as _,
161165
},
162166
};
@@ -166,19 +170,21 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
166170
_ => unreachable!(),
167171
};
168172

169-
while dbghelp.StackWalk64()(
170-
image as u32,
171-
process,
172-
thread,
173-
frame_ptr,
174-
&mut context.0 as *mut CONTEXT as *mut _,
175-
None,
176-
Some(function_table_access),
177-
Some(get_module_base),
178-
None,
179-
) == TRUE
180-
{
181-
frame.inner.base_address = get_module_base(process_handle, frame.ip() as _) as _;
173+
while unsafe {
174+
dbghelp.StackWalk64()(
175+
image as u32,
176+
process,
177+
thread,
178+
frame_ptr,
179+
&mut context.0 as *mut CONTEXT as *mut _,
180+
None,
181+
Some(function_table_access),
182+
Some(get_module_base),
183+
None,
184+
) == TRUE
185+
} {
186+
frame.inner.base_address =
187+
unsafe { get_module_base(process, frame.ip() as _) as _ };
182188

183189
if !cb(&frame) {
184190
break;

0 commit comments

Comments
 (0)