comparison src/os/windows/vm/decoder_windows.cpp @ 4803:d7e3846464d0

7071311: Decoder enhancement Summary: Made decoder thread-safe Reviewed-by: coleenp, kamg
author zgu
date Tue, 17 Jan 2012 13:08:52 -0500
parents b1cbb0907b36
children 3b01d0321dfa
comparison
equal deleted inserted replaced
4801:4f3ce9284781 4803:d7e3846464d0
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "prims/jvm.h" 26 #include "prims/jvm.h"
27 #include "runtime/os.hpp" 27 #include "decoder_windows.hpp"
28 #include "utilities/decoder.hpp"
29 28
30 HMODULE Decoder::_dbghelp_handle = NULL; 29 WindowsDecoder::WindowsDecoder() {
31 bool Decoder::_can_decode_in_vm = false; 30 _dbghelp_handle = NULL;
32 pfn_SymGetSymFromAddr64 Decoder::_pfnSymGetSymFromAddr64 = NULL; 31 _can_decode_in_vm = false;
33 pfn_UndecorateSymbolName Decoder::_pfnUndecorateSymbolName = NULL; 32 _pfnSymGetSymFromAddr64 = NULL;
33 _pfnUndecorateSymbolName = NULL;
34 34
35 void Decoder::initialize() { 35 _decoder_status = no_error;
36 if (!_initialized) { 36 initialize();
37 _initialized = true; 37 }
38 38
39 HINSTANCE handle = os::win32::load_Windows_dll("dbghelp.dll", NULL, 0); 39 void WindowsDecoder::initialize() {
40 if (!has_error() && _dbghelp_handle == NULL) {
41 HMODULE handle = ::LoadLibrary("dbghelp.dll");
40 if (!handle) { 42 if (!handle) {
41 _decoder_status = helper_not_found; 43 _decoder_status = helper_not_found;
42 return; 44 return;
43 } 45 }
44 46
45 _dbghelp_handle = handle; 47 _dbghelp_handle = handle;
46 48
47 pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions"); 49 pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
68 return; 70 return;
69 } 71 }
70 72
71 // find out if jvm.dll contains private symbols, by decoding 73 // find out if jvm.dll contains private symbols, by decoding
72 // current function and comparing the result 74 // current function and comparing the result
73 address addr = (address)Decoder::initialize; 75 address addr = (address)Decoder::decode;
74 char buf[MAX_PATH]; 76 char buf[MAX_PATH];
75 if (decode(addr, buf, sizeof(buf), NULL) == no_error) { 77 if (decode(addr, buf, sizeof(buf), NULL)) {
76 _can_decode_in_vm = !strcmp(buf, "Decoder::initialize"); 78 _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
77 } 79 }
78 } 80 }
79 } 81 }
80 82
81 void Decoder::uninitialize() { 83 void WindowsDecoder::uninitialize() {
82 assert(_initialized, "Decoder not yet initialized");
83 _pfnSymGetSymFromAddr64 = NULL; 84 _pfnSymGetSymFromAddr64 = NULL;
84 _pfnUndecorateSymbolName = NULL; 85 _pfnUndecorateSymbolName = NULL;
85 if (_dbghelp_handle != NULL) { 86 if (_dbghelp_handle != NULL) {
86 ::FreeLibrary(_dbghelp_handle); 87 ::FreeLibrary(_dbghelp_handle);
87 } 88 }
88 _initialized = false; 89 _dbghelp_handle = NULL;
89 } 90 }
90 91
91 bool Decoder::can_decode_C_frame_in_vm() { 92 bool WindowsDecoder::can_decode_C_frame_in_vm() const {
92 initialize(); 93 return (!has_error() && _can_decode_in_vm);
93 return _can_decode_in_vm;
94 } 94 }
95 95
96 96
97 Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) { 97 bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath) {
98 assert(_initialized, "Decoder not yet initialized");
99 if (_pfnSymGetSymFromAddr64 != NULL) { 98 if (_pfnSymGetSymFromAddr64 != NULL) {
100 PIMAGEHLP_SYMBOL64 pSymbol; 99 PIMAGEHLP_SYMBOL64 pSymbol;
101 char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)]; 100 char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
102 pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo; 101 pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo;
103 pSymbol->MaxNameLength = MAX_PATH; 102 pSymbol->MaxNameLength = MAX_PATH;
104 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); 103 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
105 DWORD64 displacement; 104 DWORD64 displacement;
106 if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) { 105 if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
107 if (buf != NULL) { 106 if (buf != NULL) {
108 if (!demangle(pSymbol->Name, buf, buflen)) { 107 if (demangle(pSymbol->Name, buf, buflen)) {
109 jio_snprintf(buf, buflen, "%s", pSymbol->Name); 108 jio_snprintf(buf, buflen, "%s", pSymbol->Name);
110 } 109 }
111 } 110 }
112 if (offset != NULL) *offset = (int)displacement; 111 if(offset != NULL) *offset = (int)displacement;
113 return no_error; 112 return true;
114 } 113 }
115 } 114 }
116 return helper_not_found; 115 if (buf != NULL && buflen > 0) buf[0] = '\0';
116 if (offset != NULL) *offset = -1;
117 return false;
117 } 118 }
118 119
119 bool Decoder::demangle(const char* symbol, char *buf, int buflen) { 120 bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
120 assert(_initialized, "Decoder not yet initialized");
121 return _pfnUndecorateSymbolName != NULL && 121 return _pfnUndecorateSymbolName != NULL &&
122 _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); 122 _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
123 } 123 }
124 124