971 void os::shutdown() { 972 // allow PerfMemory to attempt cleanup of any persistent resources 973 perfMemory_exit(); 974 975 // flush buffered output, finish log files 976 ostream_abort(); 977 978 // Check for abort hook 979 abort_hook_t abort_hook = Arguments::abort_hook(); 980 if (abort_hook != NULL) { 981 abort_hook(); 982 } 983 } 984 985 986 static BOOL (WINAPI *_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, 987 PMINIDUMP_EXCEPTION_INFORMATION, 988 PMINIDUMP_USER_STREAM_INFORMATION, 989 PMINIDUMP_CALLBACK_INFORMATION); 990 991 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { 992 HINSTANCE dbghelp; 993 EXCEPTION_POINTERS ep; 994 MINIDUMP_EXCEPTION_INFORMATION mei; 995 MINIDUMP_EXCEPTION_INFORMATION* pmei; 996 997 HANDLE hProcess = GetCurrentProcess(); 998 DWORD processId = GetCurrentProcessId(); 999 HANDLE dumpFile; 1000 MINIDUMP_TYPE dumpType; 1001 static const char* cwd; 1002 1003 // Default is to always create dump for debug builds, on product builds only dump on server versions of Windows. 1004 #ifndef ASSERT 1005 // If running on a client version of Windows and user has not explicitly enabled dumping 1006 if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) { 1007 VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false); 1008 return; 1009 // If running on a server version of Windows and user has explictly disabled dumping 1010 } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) { 1011 VMError::report_coredump_status("Minidump has been disabled from the command line", false); 1012 return; 1013 } 1014 #else 1015 if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) { 1016 VMError::report_coredump_status("Minidump has been disabled from the command line", false); 1017 return; 1018 } 1019 #endif 1020 1021 dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0); 1022 1023 if (dbghelp == NULL) { 1024 VMError::report_coredump_status("Failed to load dbghelp.dll", false); 1025 return; 1026 } 1027 1028 _MiniDumpWriteDump = 1029 CAST_TO_FN_PTR(BOOL(WINAPI *)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, 1030 PMINIDUMP_EXCEPTION_INFORMATION, 1031 PMINIDUMP_USER_STREAM_INFORMATION, 1032 PMINIDUMP_CALLBACK_INFORMATION), 1033 GetProcAddress(dbghelp, 1034 "MiniDumpWriteDump")); 1035 1036 if (_MiniDumpWriteDump == NULL) { 1037 VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); 1038 return; 1039 } 1040 1041 dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData); 1042 1043 // Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with 1044 // API_VERSION_NUMBER 11 or higher contains the ones we want though 1045 #if API_VERSION_NUMBER >= 11 1046 dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | 1047 MiniDumpWithUnloadedModules); 1048 #endif 1049 1050 cwd = get_current_directory(NULL, 0); 1051 jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp", cwd, current_process_id()); 1052 dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 1053 1054 if (dumpFile == INVALID_HANDLE_VALUE) { 1055 VMError::report_coredump_status("Failed to create file for dumping", false); 1056 return; 1057 } 1058 if (exceptionRecord != NULL && contextRecord != NULL) { 1059 ep.ContextRecord = (PCONTEXT) contextRecord; 1060 ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord; 1061 1062 mei.ThreadId = GetCurrentThreadId(); 1063 mei.ExceptionPointers = &ep; 1064 pmei = &mei; 1065 } else { 1066 pmei = NULL; 1067 } 1068 1069 1070 // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all 1071 // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. 1072 if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false && 1073 _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) { 1074 DWORD error = GetLastError(); 1075 LPTSTR msgbuf = NULL; 1076 1077 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 1078 FORMAT_MESSAGE_FROM_SYSTEM | 1079 FORMAT_MESSAGE_IGNORE_INSERTS, 1080 NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) { 1081 1082 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf); 1083 LocalFree(msgbuf); 1084 } else { 1085 // Call to FormatMessage failed, just include the result from GetLastError 1086 jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error); 1087 } 1088 VMError::report_coredump_status(buffer, false); 1089 } else { 1090 VMError::report_coredump_status(buffer, true); 1091 } 1092 1093 CloseHandle(dumpFile); 1094 } 1095 1096 1097 void os::abort(bool dump_core) { 1098 os::shutdown(); 1099 // no core dump on Windows 1100 win32::exit_process_or_thread(win32::EPT_PROCESS, 1); 1101 } 1102 1103 // Die immediately, no exit hook, no abort hook, no cleanup. 1104 void os::die() { 1105 win32::exit_process_or_thread(win32::EPT_PROCESS_DIE, -1); 1106 } 1107 1108 // Directory routines copied from src/win32/native/java/io/dirent_md.c 1109 // * dirent_md.c 1.15 00/02/02 1110 // 1111 // The declarations for DIR and struct dirent are in jvm_win32.h. 1112 1113 // Caller must have already run dirname through JVM_NativePath, which removes 1114 // duplicate slashes and converts all instances of '/' into '\\'. 1115 1116 DIR * os::opendir(const char *dirname) { 1117 assert(dirname != NULL, "just checking"); // hotspot change 1118 DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal); 1119 DWORD fattr; // hotspot change | 971 void os::shutdown() { 972 // allow PerfMemory to attempt cleanup of any persistent resources 973 perfMemory_exit(); 974 975 // flush buffered output, finish log files 976 ostream_abort(); 977 978 // Check for abort hook 979 abort_hook_t abort_hook = Arguments::abort_hook(); 980 if (abort_hook != NULL) { 981 abort_hook(); 982 } 983 } 984 985 986 static BOOL (WINAPI *_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, 987 PMINIDUMP_EXCEPTION_INFORMATION, 988 PMINIDUMP_USER_STREAM_INFORMATION, 989 PMINIDUMP_CALLBACK_INFORMATION); 990 991 void os::check_create_dump_limit(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { 992 // do nothing, check done in function abort below. 993 } 994 995 void os::abort(bool dump_core, void* exceptionRecord, void* contextRecord) { 996 HINSTANCE dbghelp; 997 EXCEPTION_POINTERS ep; 998 MINIDUMP_EXCEPTION_INFORMATION mei; 999 MINIDUMP_EXCEPTION_INFORMATION* pmei; 1000 1001 HANDLE hProcess = GetCurrentProcess(); 1002 DWORD processId = GetCurrentProcessId(); 1003 HANDLE dumpFile; 1004 MINIDUMP_TYPE dumpType; 1005 static const char* cwd; 1006 static char buffer[O_BUFLEN]; 1007 1008 os::shutdown(); 1009 if (!dump_core) return; 1010 1011 // Default is to always create dump for debug builds, on product builds only dump on server versions of Windows. 1012 #ifndef ASSERT 1013 // If running on a client version of Windows and user has not explicitly enabled dumping 1014 if (!os::win32::is_windows_server() && !CreateCoredumpOnCrash) { 1015 VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false); 1016 return; 1017 // If running on a server version of Windows and user has explictly disabled dumping 1018 } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) { 1019 VMError::report_coredump_status("Minidump has been disabled from the command line", false); 1020 return; 1021 } 1022 #else 1023 if (!FLAG_IS_DEFAULT(CreateCoredumpOnCrash) && !CreateCoredumpOnCrash) { 1024 VMError::report_coredump_status("Minidump has been disabled from the command line", false); 1025 return; 1026 } 1027 #endif 1028 1029 dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0); 1030 1031 if (dbghelp == NULL) { 1032 VMError::report_coredump_status("Failed to load dbghelp.dll", false); 1033 return; 1034 } 1035 1036 _MiniDumpWriteDump = 1037 CAST_TO_FN_PTR(BOOL(WINAPI *)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, 1038 PMINIDUMP_EXCEPTION_INFORMATION, 1039 PMINIDUMP_USER_STREAM_INFORMATION, 1040 PMINIDUMP_CALLBACK_INFORMATION), 1041 GetProcAddress(dbghelp, 1042 "MiniDumpWriteDump")); 1043 1044 if (_MiniDumpWriteDump == NULL) { 1045 VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); 1046 return; 1047 } 1048 1049 dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData); 1050 1051 // Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with 1052 // API_VERSION_NUMBER 11 or higher contains the ones we want though 1053 #if API_VERSION_NUMBER >= 11 1054 dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | 1055 MiniDumpWithUnloadedModules); 1056 #endif 1057 1058 cwd = get_current_directory(NULL, 0); 1059 jio_snprintf(buffer, sizeof(buffer), "%s\\hs_err_pid%u.mdmp", cwd, current_process_id()); 1060 dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 1061 1062 if (dumpFile == INVALID_HANDLE_VALUE) { 1063 VMError::report_coredump_status("Failed to create file for dumping", false); 1064 return; 1065 } 1066 1067 if (exceptionRecord != NULL && contextRecord != NULL) { 1068 ep.ContextRecord = (PCONTEXT) contextRecord; 1069 ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord; 1070 1071 mei.ThreadId = GetCurrentThreadId(); 1072 mei.ExceptionPointers = &ep; 1073 pmei = &mei; 1074 } else { 1075 pmei = NULL; 1076 } 1077 1078 1079 // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all 1080 // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. 1081 if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false && 1082 _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) { 1083 DWORD error = GetLastError(); 1084 LPTSTR msgbuf = NULL; 1085 1086 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 1087 FORMAT_MESSAGE_FROM_SYSTEM | 1088 FORMAT_MESSAGE_IGNORE_INSERTS, 1089 NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) { 1090 1091 jio_snprintf(buffer, sizeof(buffer), "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf); 1092 LocalFree(msgbuf); 1093 } else { 1094 // Call to FormatMessage failed, just include the result from GetLastError 1095 jio_snprintf(buffer, sizeof(buffer), "Call to MiniDumpWriteDump() failed (Error 0x%x)", error); 1096 } 1097 VMError::report_coredump_status(buffer, false); 1098 } else { 1099 VMError::report_coredump_status(buffer, true); 1100 } 1101 1102 CloseHandle(dumpFile); 1103 win32::exit_process_or_thread(win32::EPT_PROCESS, 1); 1104 } 1105 1106 // Die immediately, no exit hook, no abort hook, no cleanup. 1107 void os::die() { 1108 win32::exit_process_or_thread(win32::EPT_PROCESS_DIE, -1); 1109 } 1110 1111 // Directory routines copied from src/win32/native/java/io/dirent_md.c 1112 // * dirent_md.c 1.15 00/02/02 1113 // 1114 // The declarations for DIR and struct dirent are in jvm_win32.h. 1115 1116 // Caller must have already run dirname through JVM_NativePath, which removes 1117 // duplicate slashes and converts all instances of '/' into '\\'. 1118 1119 DIR * os::opendir(const char *dirname) { 1120 assert(dirname != NULL, "just checking"); // hotspot change 1121 DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal); 1122 DWORD fattr; // hotspot change |