@@ -93,6 +93,31 @@ pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
93
93
Err ( ( ) ) => return , // oh well...
94
94
} ;
95
95
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
+
96
121
// Attempt to use `StackWalkEx` if we can, but fall back to `StackWalk64`
97
122
// since it's in theory supported on more systems.
98
123
match ( * dbghelp. dbghelp ( ) ) . StackWalkEx ( ) {
@@ -113,8 +138,8 @@ pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
113
138
frame_ptr,
114
139
& mut context. 0 as * mut CONTEXT as * mut _ ,
115
140
None ,
116
- Some ( dbghelp . SymFunctionTableAccess64 ( ) ) ,
117
- Some ( dbghelp . SymGetModuleBase64 ( ) ) ,
141
+ Some ( function_table_access ) ,
142
+ Some ( get_module_base ) ,
118
143
None ,
119
144
0 ,
120
145
) == TRUE
@@ -141,8 +166,8 @@ pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) {
141
166
frame_ptr,
142
167
& mut context. 0 as * mut CONTEXT as * mut _ ,
143
168
None ,
144
- Some ( dbghelp . SymFunctionTableAccess64 ( ) ) ,
145
- Some ( dbghelp . SymGetModuleBase64 ( ) ) ,
169
+ Some ( function_table_access ) ,
170
+ Some ( get_module_base ) ,
146
171
None ,
147
172
) == TRUE
148
173
{
0 commit comments