1.1 --- a/src/os/windows/vm/os_windows.cpp Thu Aug 01 03:44:03 2019 +0100 1.2 +++ b/src/os/windows/vm/os_windows.cpp Mon Aug 12 18:30:40 2019 +0300 1.3 @@ -1669,6 +1669,50 @@ 1.4 enumerate_modules(pid, _print_module, (void *)st); 1.5 } 1.6 1.7 +int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { 1.8 + HANDLE hProcess; 1.9 + 1.10 +# define MAX_NUM_MODULES 128 1.11 + HMODULE modules[MAX_NUM_MODULES]; 1.12 + static char filename[MAX_PATH]; 1.13 + int result = 0; 1.14 + 1.15 + int pid = os::current_process_id(); 1.16 + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 1.17 + FALSE, pid); 1.18 + if (hProcess == NULL) return 0; 1.19 + 1.20 + DWORD size_needed; 1.21 + if (!EnumProcessModules(hProcess, modules, sizeof(modules), &size_needed)) { 1.22 + CloseHandle(hProcess); 1.23 + return 0; 1.24 + } 1.25 + 1.26 + // number of modules that are currently loaded 1.27 + int num_modules = size_needed / sizeof(HMODULE); 1.28 + 1.29 + for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { 1.30 + // Get Full pathname: 1.31 + if (!GetModuleFileNameEx(hProcess, modules[i], filename, sizeof(filename))) { 1.32 + filename[0] = '\0'; 1.33 + } 1.34 + 1.35 + MODULEINFO modinfo; 1.36 + if (!GetModuleInformation(hProcess, modules[i], &modinfo, sizeof(modinfo))) { 1.37 + modinfo.lpBaseOfDll = NULL; 1.38 + modinfo.SizeOfImage = 0; 1.39 + } 1.40 + 1.41 + // Invoke callback function 1.42 + result = callback(filename, (address)modinfo.lpBaseOfDll, 1.43 + (address)((u8)modinfo.lpBaseOfDll + (u8)modinfo.SizeOfImage), param); 1.44 + if (result) break; 1.45 + } 1.46 + 1.47 + CloseHandle(hProcess); 1.48 + return result; 1.49 +} 1.50 + 1.51 void os::print_os_info_brief(outputStream* st) { 1.52 os::print_os_info(st); 1.53 } 1.54 @@ -4352,6 +4396,22 @@ 1.55 return (jlong) ::_lseeki64(fd, offset, whence); 1.56 } 1.57 1.58 +size_t os::read_at(int fd, void *buf, unsigned int nBytes, jlong offset) { 1.59 + OVERLAPPED ov; 1.60 + DWORD nread; 1.61 + BOOL result; 1.62 + 1.63 + ZeroMemory(&ov, sizeof(ov)); 1.64 + ov.Offset = (DWORD)offset; 1.65 + ov.OffsetHigh = (DWORD)(offset >> 32); 1.66 + 1.67 + HANDLE h = (HANDLE)::_get_osfhandle(fd); 1.68 + 1.69 + result = ReadFile(h, (LPVOID)buf, nBytes, &nread, &ov); 1.70 + 1.71 + return result ? nread : 0; 1.72 +} 1.73 + 1.74 // This method is a slightly reworked copy of JDK's sysNativePath 1.75 // from src/windows/hpi/src/path_md.c 1.76 1.77 @@ -4811,6 +4871,40 @@ 1.78 } 1.79 } 1.80 1.81 +Thread* os::ThreadCrashProtection::_protected_thread = NULL; 1.82 +os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL; 1.83 +volatile intptr_t os::ThreadCrashProtection::_crash_mux = 0; 1.84 + 1.85 +os::ThreadCrashProtection::ThreadCrashProtection() { 1.86 +} 1.87 + 1.88 +// See the caveats for this class in os_windows.hpp 1.89 +// Protects the callback call so that raised OS EXCEPTIONS causes a jump back 1.90 +// into this method and returns false. If no OS EXCEPTION was raised, returns 1.91 +// true. 1.92 +// The callback is supposed to provide the method that should be protected. 1.93 +// 1.94 +bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) { 1.95 + 1.96 + Thread::muxAcquire(&_crash_mux, "CrashProtection"); 1.97 + 1.98 + _protected_thread = ThreadLocalStorage::thread(); 1.99 + assert(_protected_thread != NULL, "Cannot crash protect a NULL thread"); 1.100 + 1.101 + bool success = true; 1.102 + __try { 1.103 + _crash_protection = this; 1.104 + cb.call(); 1.105 + } __except(EXCEPTION_EXECUTE_HANDLER) { 1.106 + // only for protection, nothing to do 1.107 + success = false; 1.108 + } 1.109 + _crash_protection = NULL; 1.110 + _protected_thread = NULL; 1.111 + Thread::muxRelease(&_crash_mux); 1.112 + return success; 1.113 +} 1.114 + 1.115 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { 1.116 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); 1.117 }