@@ -93,6 +93,31 @@ pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
9393 Err ( ( ) ) => return , // oh well...
9494 } ;
9595
96+ // On x86_64 and ARM64 we opt to not use the default `Sym*` functions from
97+ // dbghelp for getting the function table and module base. Instead we use
98+ // the `RtlLookupFunctionEntry` function in kernel32 which will account for
99+ // JIT compiler frames as well. These should be equivalent, but using
100+ // `Rtl*` allows us to backtrace through JIT frames.
101+ cfg_if:: cfg_if! {
102+ if #[ cfg( target_pointer_width = "64" ) ] {
103+ use core:: ptr;
104+
105+ unsafe extern "system" fn function_table_access( _process: HANDLE , addr: DWORD64 ) -> PVOID {
106+ let mut base = 0 ;
107+ RtlLookupFunctionEntry ( addr, & mut base, ptr:: null_mut( ) ) . cast( )
108+ }
109+
110+ unsafe extern "system" fn get_module_base( _process: HANDLE , addr: DWORD64 ) -> DWORD64 {
111+ let mut base = 0 ;
112+ RtlLookupFunctionEntry ( addr, & mut base, ptr:: null_mut( ) ) ;
113+ base
114+ }
115+ } else {
116+ let function_table_access = dbghelp. SymFunctionTableAccess64 ( ) ;
117+ let get_module_base = dbghelp. SymGetModuleBase64 ( ) ;
118+ }
119+ }
120+
96121 // Attempt to use `StackWalkEx` if we can, but fall back to `StackWalk64`
97122 // since it's in theory supported on more systems.
98123 match ( * dbghelp. dbghelp ( ) ) . StackWalkEx ( ) {
@@ -113,8 +138,8 @@ pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
113138 frame_ptr,
114139 & mut context. 0 as * mut CONTEXT as * mut _ ,
115140 None ,
116- Some ( dbghelp . SymFunctionTableAccess64 ( ) ) ,
117- Some ( dbghelp . SymGetModuleBase64 ( ) ) ,
141+ Some ( function_table_access ) ,
142+ Some ( get_module_base ) ,
118143 None ,
119144 0 ,
120145 ) == TRUE
@@ -141,8 +166,8 @@ pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
141166 frame_ptr,
142167 & mut context. 0 as * mut CONTEXT as * mut _ ,
143168 None ,
144- Some ( dbghelp . SymFunctionTableAccess64 ( ) ) ,
145- Some ( dbghelp . SymGetModuleBase64 ( ) ) ,
169+ Some ( function_table_access ) ,
170+ Some ( get_module_base ) ,
146171 None ,
147172 ) == TRUE
148173 {
0 commit comments