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