Skip to content

Commit

Permalink
Merge pull request #578 from roblabla/fix-win7
Browse files Browse the repository at this point in the history
Fix panic in backtrace symbolication on win7
  • Loading branch information
ChrisDenton authored Nov 21, 2023
2 parents aa0a5e2 + b891125 commit 6145fe6
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
16 changes: 14 additions & 2 deletions src/dbghelp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ use core::ptr;
mod dbghelp {
use crate::windows::*;
pub use winapi::um::dbghelp::{
StackWalk64, StackWalkEx, SymFunctionTableAccess64, SymGetModuleBase64, SymGetOptions,
SymInitializeW, SymSetOptions,
StackWalk64, StackWalkEx, SymFromAddrW, SymFunctionTableAccess64, SymGetLineFromAddrW64,
SymGetModuleBase64, SymGetOptions, SymInitializeW, SymSetOptions,
};

extern "system" {
Expand Down Expand Up @@ -233,6 +233,18 @@ dbghelp! {
CurContext: LPDWORD,
CurFrameIndex: LPDWORD
) -> BOOL;
fn SymFromAddrW(
hProcess: HANDLE,
Address: DWORD64,
Displacement: PDWORD64,
Symbol: PSYMBOL_INFOW
) -> BOOL;
fn SymGetLineFromAddrW64(
hProcess: HANDLE,
dwAddr: DWORD64,
pdwDisplacement: PDWORD,
Line: PIMAGEHLP_LINEW64
) -> BOOL;
}
}

Expand Down
35 changes: 33 additions & 2 deletions src/symbolize/dbghelp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,45 @@ pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))
Err(()) => return, // oh well...
};

let resolve_inner = if (*dbghelp.dbghelp()).SymAddrIncludeInlineTrace().is_some() {
// We are on a version of dbghelp 6.2+, which contains the more modern
// Inline APIs.
resolve_with_inline
} else {
// We are on an older version of dbghelp which doesn't contain the Inline
// APIs.
resolve_legacy
};
match what {
ResolveWhat::Address(_) => resolve_with_inline(&dbghelp, what.address_or_ip(), None, cb),
ResolveWhat::Address(_) => resolve_inner(&dbghelp, what.address_or_ip(), None, cb),
ResolveWhat::Frame(frame) => {
resolve_with_inline(&dbghelp, frame.ip(), frame.inner.inline_context(), cb)
resolve_inner(&dbghelp, frame.ip(), frame.inner.inline_context(), cb)
}
}
}

/// Resolve the address using the legacy dbghelp API.
///
/// This should work all the way down to Windows XP. The inline context is
/// ignored, since this concept was only introduced in dbghelp 6.2+.
unsafe fn resolve_legacy(
dbghelp: &dbghelp::Init,
addr: *mut c_void,
_inline_context: Option<DWORD>,
cb: &mut dyn FnMut(&super::Symbol),
) {
let addr = super::adjust_ip(addr) as DWORD64;
do_resolve(
|info| dbghelp.SymFromAddrW()(GetCurrentProcess(), addr, &mut 0, info),
|line| dbghelp.SymGetLineFromAddrW64()(GetCurrentProcess(), addr, &mut 0, line),
cb,
)
}

/// Resolve the address using the modern dbghelp APIs.
///
/// Note that calling this function requires having dbghelp 6.2+ loaded - and
/// will panic otherwise.
unsafe fn resolve_with_inline(
dbghelp: &dbghelp::Init,
addr: *mut c_void,
Expand Down

0 comments on commit 6145fe6

Please sign in to comment.