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