src/os/windows/vm/os_windows.cpp

Print this page




 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