Wed, 09 Jan 2013 14:46:55 -0500
7152671: RFE: Windows decoder should add some std dirs to the symbol search path
Summary: Added JRE/JDK bin directories to decoder's symbol search path
Reviewed-by: dcubed, sla
src/os/windows/vm/decoder_windows.cpp | file | annotate | diff | comparison | revisions | |
src/os/windows/vm/decoder_windows.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/os/windows/vm/decoder_windows.cpp Mon Jan 07 15:32:51 2013 -0500 1.2 +++ b/src/os/windows/vm/decoder_windows.cpp Wed Jan 09 14:46:55 2013 -0500 1.3 @@ -49,7 +49,7 @@ 1.4 pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions"); 1.5 pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize"); 1.6 _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64"); 1.7 - _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName"); 1.8 + _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); 1.9 1.10 if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { 1.11 _pfnSymGetSymFromAddr64 = NULL; 1.12 @@ -60,8 +60,9 @@ 1.13 return; 1.14 } 1.15 1.16 - _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); 1.17 - if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) { 1.18 + HANDLE hProcess = ::GetCurrentProcess(); 1.19 + _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); 1.20 + if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { 1.21 _pfnSymGetSymFromAddr64 = NULL; 1.22 _pfnUndecorateSymbolName = NULL; 1.23 ::FreeLibrary(handle); 1.24 @@ -70,6 +71,77 @@ 1.25 return; 1.26 } 1.27 1.28 + // set pdb search paths 1.29 + pfn_SymSetSearchPath _pfn_SymSetSearchPath = 1.30 + (pfn_SymSetSearchPath)::GetProcAddress(handle, "SymSetSearchPath"); 1.31 + pfn_SymGetSearchPath _pfn_SymGetSearchPath = 1.32 + (pfn_SymGetSearchPath)::GetProcAddress(handle, "SymGetSearchPath"); 1.33 + if (_pfn_SymSetSearchPath != NULL && _pfn_SymGetSearchPath != NULL) { 1.34 + char paths[MAX_PATH]; 1.35 + int len = sizeof(paths); 1.36 + if (!_pfn_SymGetSearchPath(hProcess, paths, len)) { 1.37 + paths[0] = '\0'; 1.38 + } else { 1.39 + // available spaces in path buffer 1.40 + len -= (int)strlen(paths); 1.41 + } 1.42 + 1.43 + char tmp_path[MAX_PATH]; 1.44 + DWORD dwSize; 1.45 + HMODULE hJVM = ::GetModuleHandle("jvm.dll"); 1.46 + tmp_path[0] = '\0'; 1.47 + // append the path where jvm.dll is located 1.48 + if (hJVM != NULL && (dwSize = ::GetModuleFileName(hJVM, tmp_path, sizeof(tmp_path))) > 0) { 1.49 + while (dwSize > 0 && tmp_path[dwSize] != '\\') { 1.50 + dwSize --; 1.51 + } 1.52 + 1.53 + tmp_path[dwSize] = '\0'; 1.54 + 1.55 + if (dwSize > 0 && len > (int)dwSize + 1) { 1.56 + strncat(paths, os::path_separator(), 1); 1.57 + strncat(paths, tmp_path, dwSize); 1.58 + len -= dwSize + 1; 1.59 + } 1.60 + } 1.61 + 1.62 + // append $JRE/bin. Arguments::get_java_home actually returns $JRE 1.63 + // path 1.64 + char *p = Arguments::get_java_home(); 1.65 + assert(p != NULL, "empty java home"); 1.66 + size_t java_home_len = strlen(p); 1.67 + if (len > (int)java_home_len + 5) { 1.68 + strncat(paths, os::path_separator(), 1); 1.69 + strncat(paths, p, java_home_len); 1.70 + strncat(paths, "\\bin", 4); 1.71 + len -= (int)(java_home_len + 5); 1.72 + } 1.73 + 1.74 + // append $JDK/bin path if it exists 1.75 + assert(java_home_len < MAX_PATH, "Invalid path length"); 1.76 + // assume $JRE is under $JDK, construct $JDK/bin path and 1.77 + // see if it exists or not 1.78 + if (strncmp(&p[java_home_len - 3], "jre", 3) == 0) { 1.79 + strncpy(tmp_path, p, java_home_len - 3); 1.80 + tmp_path[java_home_len - 3] = '\0'; 1.81 + strncat(tmp_path, "bin", 3); 1.82 + 1.83 + // if the directory exists 1.84 + DWORD dwAttrib = GetFileAttributes(tmp_path); 1.85 + if (dwAttrib != INVALID_FILE_ATTRIBUTES && 1.86 + (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { 1.87 + // tmp_path should have the same length as java_home_len, since we only 1.88 + // replaced 'jre' with 'bin' 1.89 + if (len > (int)java_home_len + 1) { 1.90 + strncat(paths, os::path_separator(), 1); 1.91 + strncat(paths, tmp_path, java_home_len); 1.92 + } 1.93 + } 1.94 + } 1.95 + 1.96 + _pfn_SymSetSearchPath(hProcess, paths); 1.97 + } 1.98 + 1.99 // find out if jvm.dll contains private symbols, by decoding 1.100 // current function and comparing the result 1.101 address addr = (address)Decoder::demangle;
2.1 --- a/src/os/windows/vm/decoder_windows.hpp Mon Jan 07 15:32:51 2013 -0500 2.2 +++ b/src/os/windows/vm/decoder_windows.hpp Wed Jan 09 14:46:55 2013 -0500 2.3 @@ -35,6 +35,8 @@ 2.4 typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL); 2.5 typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64); 2.6 typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD); 2.7 +typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR); 2.8 +typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int); 2.9 2.10 class WindowsDecoder : public AbstractDecoder { 2.11