diff src/share/vm/utilities/vmError.cpp @ 10408:836a62f43af9

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 19 Jun 2013 10:45:56 +0200
parents 89e4d67fdd2a 9ce110b1d14a
children 6b0fd0964b87
line wrap: on
line diff
--- a/src/share/vm/utilities/vmError.cpp	Tue Jun 18 14:23:29 2013 -0700
+++ b/src/share/vm/utilities/vmError.cpp	Wed Jun 19 10:45:56 2013 +0200
@@ -100,7 +100,7 @@
                  const char* message, const char * detail_msg)
 {
   _thread = thread;
-  _id = internal_error;     // Value that's not an OS exception/signal
+  _id = INTERNAL_ERROR;     // Value that's not an OS exception/signal
   _filename = filename;
   _lineno = lineno;
   _message = message;
@@ -119,9 +119,9 @@
 
 // Constructor for OOM errors
 VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size,
-                 const char* message) {
+                 VMErrorType vm_err_type, const char* message) {
     _thread = thread;
-    _id = oom_error;     // Value that's not an OS exception/signal
+    _id = vm_err_type; // Value that's not an OS exception/signal
     _filename = filename;
     _lineno = lineno;
     _message = message;
@@ -142,7 +142,7 @@
 // Constructor for non-fatal errors
 VMError::VMError(const char* message) {
     _thread = NULL;
-    _id = internal_error;     // Value that's not an OS exception/signal
+    _id = INTERNAL_ERROR;     // Value that's not an OS exception/signal
     _filename = NULL;
     _lineno = 0;
     _message = message;
@@ -351,9 +351,12 @@
   STEP(15, "(printing type of error)")
 
      switch(_id) {
-       case oom_error:
+       case OOM_MALLOC_ERROR:
+       case OOM_MMAP_ERROR:
          if (_size) {
-           st->print("# Native memory allocation (malloc) failed to allocate ");
+           st->print("# Native memory allocation ");
+           st->print((_id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " :
+                                                 "(mmap) failed to map ");
            jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
            st->print(buf);
            st->print(" bytes");
@@ -386,7 +389,7 @@
            return;  // that's enough for the screen
          }
          break;
-       case internal_error:
+       case INTERNAL_ERROR:
        default:
          break;
      }
@@ -796,6 +799,56 @@
 VMError* volatile VMError::first_error = NULL;
 volatile jlong VMError::first_error_tid = -1;
 
+/** Expand a pattern into a buffer starting at pos and open a file using constructed path */
+static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
+  int fd = -1;
+  if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) {
+    fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  }
+  return fd;
+}
+
+/**
+ * Construct file name for a log file and return it's file descriptor.
+ * Name and location depends on pattern, default_pattern params and access
+ * permissions.
+ */
+static int prepare_log_file(const char* pattern, const char* default_pattern, char* buf, size_t buflen) {
+  int fd = -1;
+
+  // If possible, use specified pattern to construct log file name
+  if (pattern != NULL) {
+    fd = expand_and_open(pattern, buf, buflen, 0);
+  }
+
+  // Either user didn't specify, or the user's location failed,
+  // so use the default name in the current directory
+  if (fd == -1) {
+    const char* cwd = os::get_current_directory(buf, buflen);
+    if (cwd != NULL) {
+      size_t pos = strlen(cwd);
+      int fsep_len = jio_snprintf(&buf[pos], buflen-pos, "%s", os::file_separator());
+      pos += fsep_len;
+      if (fsep_len > 0) {
+        fd = expand_and_open(default_pattern, buf, buflen, pos);
+      }
+    }
+  }
+
+   // try temp directory if it exists.
+   if (fd == -1) {
+     const char* tmpdir = os::get_temp_directory();
+     if (tmpdir != NULL && strlen(tmpdir) > 0) {
+       int pos = jio_snprintf(buf, buflen, "%s%s", tmpdir, os::file_separator());
+       if (pos > 0) {
+         fd = expand_and_open(default_pattern, buf, buflen, pos);
+       }
+     }
+   }
+
+  return fd;
+}
+
 void VMError::report_and_die() {
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
@@ -905,36 +958,7 @@
     // see if log file is already open
     if (!log.is_open()) {
       // open log file
-      int fd = -1;
-
-      if (ErrorFile != NULL) {
-        bool copy_ok =
-          Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer));
-        if (copy_ok) {
-          fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
-        }
-      }
-
-      if (fd == -1) {
-        const char *cwd = os::get_current_directory(buffer, sizeof(buffer));
-        size_t len = strlen(cwd);
-        // either user didn't specify, or the user's location failed,
-        // so use the default name in the current directory
-        jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log",
-                     os::file_separator(), os::current_process_id());
-        fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
-      }
-
-      if (fd == -1) {
-        const char * tmpdir = os::get_temp_directory();
-        // try temp directory if it exists.
-        if (tmpdir != NULL && tmpdir[0] != '\0') {
-          jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log",
-                       tmpdir, os::file_separator(), os::current_process_id());
-          fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
-        }
-      }
-
+      int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));
       if (fd != -1) {
         out.print_raw("# An error report file with more information is saved as:\n# ");
         out.print_raw_cr(buffer);
@@ -958,7 +982,7 @@
     // Run error reporting to determine whether or not to report the crash.
     if (!transmit_report_done && should_report_bug(first_error->_id)) {
       transmit_report_done = true;
-      FILE* hs_err = ::fdopen(log.fd(), "r");
+      FILE* hs_err = os::open(log.fd(), "r");
       if (NULL != hs_err) {
         ErrorReporter er;
         er.call(hs_err, buffer, O_BUFLEN);
@@ -1008,7 +1032,19 @@
     skip_replay = true;
     ciEnv* env = ciEnv::current();
     if (env != NULL) {
-      env->dump_replay_data();
+      int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", buffer, sizeof(buffer));
+      if (fd != -1) {
+        FILE* replay_data_file = os::open(fd, "w");
+        if (replay_data_file != NULL) {
+          fileStream replay_data_stream(replay_data_file, /*need_close=*/true);
+          env->dump_replay_data(&replay_data_stream);
+          out.print_raw("#\n# Compiler replay data is saved as:\n# ");
+          out.print_raw_cr(buffer);
+        } else {
+          out.print_raw("#\n# Can't open file to dump replay data. Error: ");
+          out.print_raw_cr(strerror(os::get_last_error()));
+        }
+      }
     }
   }