src/os/windows/vm/decoder_windows.cpp

Fri, 03 Feb 2012 12:08:55 -0800

author
jcoomes
date
Fri, 03 Feb 2012 12:08:55 -0800
changeset 3502
379b22e03c32
parent 3430
d7e3846464d0
child 3961
3b01d0321dfa
permissions
-rw-r--r--

Merge

zgu@2364 1 /*
zgu@3430 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
zgu@2364 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
zgu@2364 4 *
zgu@2364 5 * This code is free software; you can redistribute it and/or modify it
zgu@2364 6 * under the terms of the GNU General Public License version 2 only, as
zgu@2364 7 * published by the Free Software Foundation.
zgu@2364 8 *
zgu@2364 9 * This code is distributed in the hope that it will be useful, but WITHOUT
zgu@2364 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
zgu@2364 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
zgu@2364 12 * version 2 for more details (a copy is included in the LICENSE file that
zgu@2364 13 * accompanied this code).
zgu@2364 14 *
zgu@2364 15 * You should have received a copy of the GNU General Public License version
zgu@2364 16 * 2 along with this work; if not, write to the Free Software Foundation,
zgu@2364 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
zgu@2364 18 *
zgu@2364 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
zgu@2364 20 * or visit www.oracle.com if you need additional information or have any
zgu@2364 21 * questions.
zgu@2364 22 *
zgu@2364 23 */
zgu@2364 24
zgu@2364 25 #include "precompiled.hpp"
zgu@2364 26 #include "prims/jvm.h"
zgu@3430 27 #include "decoder_windows.hpp"
zgu@2364 28
zgu@3430 29 WindowsDecoder::WindowsDecoder() {
zgu@3430 30 _dbghelp_handle = NULL;
zgu@3430 31 _can_decode_in_vm = false;
zgu@3430 32 _pfnSymGetSymFromAddr64 = NULL;
zgu@3430 33 _pfnUndecorateSymbolName = NULL;
zgu@2364 34
zgu@3430 35 _decoder_status = no_error;
zgu@3430 36 initialize();
zgu@3430 37 }
zgu@2364 38
zgu@3430 39 void WindowsDecoder::initialize() {
zgu@3430 40 if (!has_error() && _dbghelp_handle == NULL) {
zgu@3430 41 HMODULE handle = ::LoadLibrary("dbghelp.dll");
zgu@2364 42 if (!handle) {
zgu@2364 43 _decoder_status = helper_not_found;
zgu@3430 44 return;
zgu@2364 45 }
zgu@2364 46
zgu@2364 47 _dbghelp_handle = handle;
zgu@2364 48
zgu@2364 49 pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
zgu@2364 50 pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
zgu@2364 51 _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
zgu@2364 52 _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName");
zgu@2364 53
zgu@2364 54 if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
zgu@2364 55 _pfnSymGetSymFromAddr64 = NULL;
zgu@2364 56 _pfnUndecorateSymbolName = NULL;
zgu@2364 57 ::FreeLibrary(handle);
zgu@2364 58 _dbghelp_handle = NULL;
zgu@2364 59 _decoder_status = helper_func_error;
zgu@2364 60 return;
zgu@2364 61 }
zgu@2364 62
zgu@2364 63 _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
zgu@2364 64 if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) {
zgu@2364 65 _pfnSymGetSymFromAddr64 = NULL;
zgu@2364 66 _pfnUndecorateSymbolName = NULL;
zgu@2364 67 ::FreeLibrary(handle);
zgu@2364 68 _dbghelp_handle = NULL;
zgu@2364 69 _decoder_status = helper_init_error;
zgu@2364 70 return;
zgu@2364 71 }
zgu@2364 72
zgu@2364 73 // find out if jvm.dll contains private symbols, by decoding
zgu@2364 74 // current function and comparing the result
zgu@3430 75 address addr = (address)Decoder::decode;
zgu@2364 76 char buf[MAX_PATH];
zgu@3430 77 if (decode(addr, buf, sizeof(buf), NULL)) {
zgu@3430 78 _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
zgu@2364 79 }
zgu@2364 80 }
zgu@2364 81 }
zgu@2364 82
zgu@3430 83 void WindowsDecoder::uninitialize() {
zgu@2364 84 _pfnSymGetSymFromAddr64 = NULL;
zgu@2364 85 _pfnUndecorateSymbolName = NULL;
zgu@2364 86 if (_dbghelp_handle != NULL) {
zgu@2364 87 ::FreeLibrary(_dbghelp_handle);
zgu@2364 88 }
zgu@3430 89 _dbghelp_handle = NULL;
zgu@2364 90 }
zgu@2364 91
zgu@3430 92 bool WindowsDecoder::can_decode_C_frame_in_vm() const {
zgu@3430 93 return (!has_error() && _can_decode_in_vm);
zgu@2364 94 }
zgu@2364 95
zgu@2364 96
zgu@3430 97 bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath) {
zgu@2364 98 if (_pfnSymGetSymFromAddr64 != NULL) {
zgu@2364 99 PIMAGEHLP_SYMBOL64 pSymbol;
zgu@2364 100 char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
zgu@2364 101 pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo;
zgu@2364 102 pSymbol->MaxNameLength = MAX_PATH;
zgu@2364 103 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
zgu@2364 104 DWORD64 displacement;
zgu@2364 105 if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
zgu@2364 106 if (buf != NULL) {
zgu@3430 107 if (demangle(pSymbol->Name, buf, buflen)) {
zgu@2364 108 jio_snprintf(buf, buflen, "%s", pSymbol->Name);
zgu@2364 109 }
zgu@2364 110 }
zgu@3430 111 if(offset != NULL) *offset = (int)displacement;
zgu@3430 112 return true;
zgu@2364 113 }
zgu@2364 114 }
zgu@3430 115 if (buf != NULL && buflen > 0) buf[0] = '\0';
zgu@3430 116 if (offset != NULL) *offset = -1;
zgu@3430 117 return false;
zgu@2364 118 }
zgu@2364 119
zgu@3430 120 bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
zgu@2364 121 return _pfnUndecorateSymbolName != NULL &&
zgu@2364 122 _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
zgu@2364 123 }
zgu@2364 124

mercurial