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_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