Skip to content

Commit 6145fe6

Browse files
authored
Merge pull request #578 from roblabla/fix-win7
Fix panic in backtrace symbolication on win7
2 parents aa0a5e2 + b891125 commit 6145fe6

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

src/dbghelp.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ use core::ptr;
3434
mod dbghelp {
3535
use crate::windows::*;
3636
pub use winapi::um::dbghelp::{
37-
StackWalk64, StackWalkEx, SymFunctionTableAccess64, SymGetModuleBase64, SymGetOptions,
38-
SymInitializeW, SymSetOptions,
37+
StackWalk64, StackWalkEx, SymFromAddrW, SymFunctionTableAccess64, SymGetLineFromAddrW64,
38+
SymGetModuleBase64, SymGetOptions, SymInitializeW, SymSetOptions,
3939
};
4040

4141
extern "system" {
@@ -233,6 +233,18 @@ dbghelp! {
233233
CurContext: LPDWORD,
234234
CurFrameIndex: LPDWORD
235235
) -> BOOL;
236+
fn SymFromAddrW(
237+
hProcess: HANDLE,
238+
Address: DWORD64,
239+
Displacement: PDWORD64,
240+
Symbol: PSYMBOL_INFOW
241+
) -> BOOL;
242+
fn SymGetLineFromAddrW64(
243+
hProcess: HANDLE,
244+
dwAddr: DWORD64,
245+
pdwDisplacement: PDWORD,
246+
Line: PIMAGEHLP_LINEW64
247+
) -> BOOL;
236248
}
237249
}
238250

src/symbolize/dbghelp.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,45 @@ pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))
7878
Err(()) => return, // oh well...
7979
};
8080

81+
let resolve_inner = if (*dbghelp.dbghelp()).SymAddrIncludeInlineTrace().is_some() {
82+
// We are on a version of dbghelp 6.2+, which contains the more modern
83+
// Inline APIs.
84+
resolve_with_inline
85+
} else {
86+
// We are on an older version of dbghelp which doesn't contain the Inline
87+
// APIs.
88+
resolve_legacy
89+
};
8190
match what {
82-
ResolveWhat::Address(_) => resolve_with_inline(&dbghelp, what.address_or_ip(), None, cb),
91+
ResolveWhat::Address(_) => resolve_inner(&dbghelp, what.address_or_ip(), None, cb),
8392
ResolveWhat::Frame(frame) => {
84-
resolve_with_inline(&dbghelp, frame.ip(), frame.inner.inline_context(), cb)
93+
resolve_inner(&dbghelp, frame.ip(), frame.inner.inline_context(), cb)
8594
}
8695
}
8796
}
8897

98+
/// Resolve the address using the legacy dbghelp API.
99+
///
100+
/// This should work all the way down to Windows XP. The inline context is
101+
/// ignored, since this concept was only introduced in dbghelp 6.2+.
102+
unsafe fn resolve_legacy(
103+
dbghelp: &dbghelp::Init,
104+
addr: *mut c_void,
105+
_inline_context: Option<DWORD>,
106+
cb: &mut dyn FnMut(&super::Symbol),
107+
) {
108+
let addr = super::adjust_ip(addr) as DWORD64;
109+
do_resolve(
110+
|info| dbghelp.SymFromAddrW()(GetCurrentProcess(), addr, &mut 0, info),
111+
|line| dbghelp.SymGetLineFromAddrW64()(GetCurrentProcess(), addr, &mut 0, line),
112+
cb,
113+
)
114+
}
115+
116+
/// Resolve the address using the modern dbghelp APIs.
117+
///
118+
/// Note that calling this function requires having dbghelp 6.2+ loaded - and
119+
/// will panic otherwise.
89120
unsafe fn resolve_with_inline(
90121
dbghelp: &dbghelp::Init,
91122
addr: *mut c_void,

0 commit comments

Comments
 (0)