hotspot/src/os/windows/vm/os_windows.cpp
changeset 8119 81eef1b06988
parent 7901 ea3d83447861
child 8120 647514d55e9d
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Tue Feb 08 22:27:57 2011 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Feb 09 11:08:10 2011 +0100
@@ -1,5 +1,5 @@
 /*
- * CopyrighT (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -915,6 +915,80 @@
   }
 }
 
+
+static BOOL  (WINAPI *_MiniDumpWriteDump)  ( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
+                                            PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);
+
+void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
+  HINSTANCE dbghelp;
+  EXCEPTION_POINTERS ep;
+  MINIDUMP_EXCEPTION_INFORMATION mei;
+  HANDLE hProcess = GetCurrentProcess();
+  DWORD processId = GetCurrentProcessId();
+  HANDLE dumpFile;
+  MINIDUMP_TYPE dumpType;
+  static const char* cwd;
+
+  // If running on a client version of Windows and user has not explicitly enabled dumping
+  if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
+    VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
+    return;
+    // If running on a server version of Windows and user has explictly disabled dumping
+  } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
+    VMError::report_coredump_status("Minidump has been disabled from the command line", false);
+    return;
+  }
+
+  dbghelp = LoadLibrary("DBGHELP.DLL");
+
+  if (dbghelp == NULL) {
+    VMError::report_coredump_status("Failed to load dbghelp.dll", false);
+    return;
+  }
+
+  _MiniDumpWriteDump = CAST_TO_FN_PTR(
+    BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
+    PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION),
+    GetProcAddress(dbghelp, "MiniDumpWriteDump"));
+
+  if (_MiniDumpWriteDump == NULL) {
+    VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false);
+    return;
+  }
+
+  dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo |
+    MiniDumpWithHandleData | MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules);
+
+
+  cwd = get_current_directory(NULL, 0);
+  jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp",cwd, current_process_id());
+  dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+  if (dumpFile == INVALID_HANDLE_VALUE) {
+    VMError::report_coredump_status("Failed to create file for dumping", false);
+    return;
+  }
+
+  ep.ContextRecord = (PCONTEXT) contextRecord;
+  ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord;
+
+  mei.ThreadId = GetCurrentThreadId();
+  mei.ExceptionPointers = &ep;
+
+  // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all
+  // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
+  if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, &mei, NULL, NULL) == false &&
+      _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, &mei, NULL, NULL) == false) {
+    VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false);
+  } else {
+    VMError::report_coredump_status(buffer, true);
+  }
+
+  CloseHandle(dumpFile);
+}
+
+
+
 void os::abort(bool dump_core)
 {
   os::shutdown();
@@ -3274,7 +3348,7 @@
 
 bool   os::win32::_is_nt              = false;
 bool   os::win32::_is_windows_2003    = false;
-
+bool   os::win32::_is_windows_server  = false;
 
 void os::win32::initialize_system_info() {
   SYSTEM_INFO si;
@@ -3293,9 +3367,9 @@
   GlobalMemoryStatusEx(&ms);
   _physical_memory = ms.ullTotalPhys;
 
-  OSVERSIONINFO oi;
-  oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-  GetVersionEx(&oi);
+  OSVERSIONINFOEX oi;
+  oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+  GetVersionEx((OSVERSIONINFO*)&oi);
   switch(oi.dwPlatformId) {
     case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break;
     case VER_PLATFORM_WIN32_NT:
@@ -3305,6 +3379,10 @@
         if (os_vers == 5002) {
           _is_windows_2003 = true;
         }
+        if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER ||
+          oi.wProductType == VER_NT_SERVER) {
+            _is_windows_server = true;
+        }
       }
       break;
     default: fatal("Unknown platform");