Mercurial > hg > truffle
comparison src/os/windows/vm/decoder_windows.cpp @ 12199:38f750491293
8022335: Native stack walk while generating hs_err does not work on Windows x64
Summary: Use WinDbg API StackWalk64()
Reviewed-by: zgu, dholmes
author | iklam |
---|---|
date | Fri, 06 Sep 2013 08:42:42 -0700 |
parents | 63e54c37ac64 |
children |
comparison
equal
deleted
inserted
replaced
12198:baa7927dfbd2 | 12199:38f750491293 |
---|---|
30 WindowsDecoder::WindowsDecoder() { | 30 WindowsDecoder::WindowsDecoder() { |
31 _dbghelp_handle = NULL; | 31 _dbghelp_handle = NULL; |
32 _can_decode_in_vm = false; | 32 _can_decode_in_vm = false; |
33 _pfnSymGetSymFromAddr64 = NULL; | 33 _pfnSymGetSymFromAddr64 = NULL; |
34 _pfnUndecorateSymbolName = NULL; | 34 _pfnUndecorateSymbolName = NULL; |
35 | 35 #ifdef AMD64 |
36 _pfnStackWalk64 = NULL; | |
37 _pfnSymFunctionTableAccess64 = NULL; | |
38 _pfnSymGetModuleBase64 = NULL; | |
39 #endif | |
36 _decoder_status = no_error; | 40 _decoder_status = no_error; |
37 initialize(); | 41 initialize(); |
38 } | 42 } |
39 | 43 |
40 void WindowsDecoder::initialize() { | 44 void WindowsDecoder::initialize() { |
51 pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize"); | 55 pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize"); |
52 _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64"); | 56 _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64"); |
53 _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); | 57 _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); |
54 | 58 |
55 if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { | 59 if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { |
56 _pfnSymGetSymFromAddr64 = NULL; | 60 uninitialize(); |
57 _pfnUndecorateSymbolName = NULL; | |
58 ::FreeLibrary(handle); | |
59 _dbghelp_handle = NULL; | |
60 _decoder_status = helper_func_error; | 61 _decoder_status = helper_func_error; |
61 return; | 62 return; |
62 } | 63 } |
64 | |
65 #ifdef AMD64 | |
66 _pfnStackWalk64 = (pfn_StackWalk64)::GetProcAddress(handle, "StackWalk64"); | |
67 _pfnSymFunctionTableAccess64 = (pfn_SymFunctionTableAccess64)::GetProcAddress(handle, "SymFunctionTableAccess64"); | |
68 _pfnSymGetModuleBase64 = (pfn_SymGetModuleBase64)::GetProcAddress(handle, "SymGetModuleBase64"); | |
69 if (_pfnStackWalk64 == NULL || _pfnSymFunctionTableAccess64 == NULL || _pfnSymGetModuleBase64 == NULL) { | |
70 // We can't call StackWalk64 to walk the stack, but we are still | |
71 // able to decode the symbols. Let's limp on. | |
72 _pfnStackWalk64 = NULL; | |
73 _pfnSymFunctionTableAccess64 = NULL; | |
74 _pfnSymGetModuleBase64 = NULL; | |
75 } | |
76 #endif | |
63 | 77 |
64 HANDLE hProcess = ::GetCurrentProcess(); | 78 HANDLE hProcess = ::GetCurrentProcess(); |
65 _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); | 79 _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); |
66 if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { | 80 if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { |
67 _pfnSymGetSymFromAddr64 = NULL; | 81 _pfnSymGetSymFromAddr64 = NULL; |
154 } | 168 } |
155 | 169 |
156 void WindowsDecoder::uninitialize() { | 170 void WindowsDecoder::uninitialize() { |
157 _pfnSymGetSymFromAddr64 = NULL; | 171 _pfnSymGetSymFromAddr64 = NULL; |
158 _pfnUndecorateSymbolName = NULL; | 172 _pfnUndecorateSymbolName = NULL; |
173 #ifdef AMD64 | |
174 _pfnStackWalk64 = NULL; | |
175 _pfnSymFunctionTableAccess64 = NULL; | |
176 _pfnSymGetModuleBase64 = NULL; | |
177 #endif | |
159 if (_dbghelp_handle != NULL) { | 178 if (_dbghelp_handle != NULL) { |
160 ::FreeLibrary(_dbghelp_handle); | 179 ::FreeLibrary(_dbghelp_handle); |
161 } | 180 } |
162 _dbghelp_handle = NULL; | 181 _dbghelp_handle = NULL; |
163 } | 182 } |
193 bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) { | 212 bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) { |
194 return _pfnUndecorateSymbolName != NULL && | 213 return _pfnUndecorateSymbolName != NULL && |
195 _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); | 214 _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); |
196 } | 215 } |
197 | 216 |
217 #ifdef AMD64 | |
218 BOOL WindowsDbgHelp::StackWalk64(DWORD MachineType, | |
219 HANDLE hProcess, | |
220 HANDLE hThread, | |
221 LPSTACKFRAME64 StackFrame, | |
222 PVOID ContextRecord, | |
223 PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, | |
224 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, | |
225 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, | |
226 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress) { | |
227 DecoderLocker locker; | |
228 WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); | |
229 | |
230 if (!wd->has_error() && wd->_pfnStackWalk64) { | |
231 return wd->_pfnStackWalk64(MachineType, | |
232 hProcess, | |
233 hThread, | |
234 StackFrame, | |
235 ContextRecord, | |
236 ReadMemoryRoutine, | |
237 FunctionTableAccessRoutine, | |
238 GetModuleBaseRoutine, | |
239 TranslateAddress); | |
240 } else { | |
241 return false; | |
242 } | |
243 } | |
244 | |
245 PVOID WindowsDbgHelp::SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) { | |
246 DecoderLocker locker; | |
247 WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); | |
248 | |
249 if (!wd->has_error() && wd->_pfnSymFunctionTableAccess64) { | |
250 return wd->_pfnSymFunctionTableAccess64(hProcess, AddrBase); | |
251 } else { | |
252 return NULL; | |
253 } | |
254 } | |
255 | |
256 pfn_SymFunctionTableAccess64 WindowsDbgHelp::pfnSymFunctionTableAccess64() { | |
257 DecoderLocker locker; | |
258 WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); | |
259 | |
260 if (!wd->has_error()) { | |
261 return wd->_pfnSymFunctionTableAccess64; | |
262 } else { | |
263 return NULL; | |
264 } | |
265 } | |
266 | |
267 pfn_SymGetModuleBase64 WindowsDbgHelp::pfnSymGetModuleBase64() { | |
268 DecoderLocker locker; | |
269 WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); | |
270 | |
271 if (!wd->has_error()) { | |
272 return wd->_pfnSymGetModuleBase64; | |
273 } else { | |
274 return NULL; | |
275 } | |
276 } | |
277 | |
278 #endif // AMD64 |