< prev index next >

src/share/vm/utilities/vmError.cpp

Print this page

        

@@ -69,112 +69,10 @@
   "OS", "PROCESSOR_IDENTIFIER", "_ALT_JAVA_HOME_DIR",
 
   (const char *)0
 };
 
-// Fatal error handler for internal errors and crashes.
-//
-// The default behavior of fatal error handler is to print a brief message
-// to standard out (defaultStream::output_fd()), then save detailed information
-// into an error report file (hs_err_pid<pid>.log) and abort VM. If multiple
-// threads are having troubles at the same time, only one error is reported.
-// The thread that is reporting error will abort VM when it is done, all other
-// threads are blocked forever inside report_and_die().
-
-// Constructor for crashes
-VMError::VMError(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context) {
-    _thread = thread;
-    _id = sig;
-    _pc   = pc;
-    _siginfo = siginfo;
-    _context = context;
-
-    _verbose = false;
-    _current_step = 0;
-    _current_step_info = NULL;
-
-    _message = NULL;
-    _detail_msg = NULL;
-    _filename = NULL;
-    _lineno = 0;
-
-    _size = 0;
-}
-
-// Constructor for internal errors
-VMError::VMError(Thread* thread, const char* filename, int lineno,
-                 const char* message, const char * detail_msg)
-{
-  _thread = thread;
-  _id = INTERNAL_ERROR;     // Value that's not an OS exception/signal
-  _filename = filename;
-  _lineno = lineno;
-  _message = message;
-  _detail_msg = detail_msg;
-
-  _verbose = false;
-  _current_step = 0;
-  _current_step_info = NULL;
-
-  _pc = NULL;
-  _siginfo = NULL;
-  _context = NULL;
-
-  _size = 0;
-}
-
-// Constructor for OOM errors
-VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size,
-                 VMErrorType vm_err_type, const char* message) {
-    _thread = thread;
-    _id = vm_err_type; // Value that's not an OS exception/signal
-    _filename = filename;
-    _lineno = lineno;
-    _message = message;
-    _detail_msg = NULL;
-
-    _verbose = false;
-    _current_step = 0;
-    _current_step_info = NULL;
-
-    _pc = NULL;
-    _siginfo = NULL;
-    _context = NULL;
-
-    _size = size;
-}
-
-
-// Constructor for non-fatal errors
-VMError::VMError(const char* message) {
-    _thread = NULL;
-    _id = INTERNAL_ERROR;     // Value that's not an OS exception/signal
-    _filename = NULL;
-    _lineno = 0;
-    _message = message;
-    _detail_msg = NULL;
-
-    _verbose = false;
-    _current_step = 0;
-    _current_step_info = NULL;
-
-    _pc = NULL;
-    _siginfo = NULL;
-    _context = NULL;
-
-    _size = 0;
-}
-
-// -XX:OnError=<string>, where <string> can be a list of commands, separated
-// by ';'. "%p" is replaced by current process id (pid); "%%" is replaced by
-// a single "%". Some examples:
-//
-// -XX:OnError="pmap %p"                // show memory map
-// -XX:OnError="gcore %p; dbx - %p"     // dump core and launch debugger
-// -XX:OnError="cat hs_err_pid%p.log | mail my_email@sun.com"
-// -XX:OnError="kill -9 %p"             // ?#!@#
-
 // A simple parser for -XX:OnError, usage:
 //  ptr = OnError;
 //  while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr) != NULL)
 //     ... ...
 static char* next_OnError_command(char* buf, int buflen, const char** ptr) {

@@ -194,11 +92,10 @@
 
   *ptr = (*cmdend == '\0' ? cmdend : cmdend + 1);
   return buf;
 }
 
-
 static void print_bug_submit_message(outputStream *out, Thread *thread) {
   if (out == NULL) return;
   out->print_raw_cr("# If you would like to submit a bug report, please visit:");
   out->print_raw   ("#   ");
   out->print_raw_cr(Arguments::java_vendor_url_bug());

@@ -221,42 +118,48 @@
   coredump_status = status;
   strncpy(coredump_message, message, sizeof(coredump_message));
   coredump_message[sizeof(coredump_message)-1] = 0;
 }
 
-
 // Return a string to describe the error
-char* VMError::error_string(char* buf, int buflen) {
+char* VMError::error_string(char* buf, int buflen, int id, const char* message, const char* detail_fmt,
+                            va_list detail_args, address pc, const char* filename, int lineno)
+{
   char signame_buf[64];
-  const char *signame = os::exception_name(_id, signame_buf, sizeof(signame_buf));
+  const char *signame = os::exception_name(id, signame_buf, sizeof(signame_buf));
 
   if (signame) {
     jio_snprintf(buf, buflen,
                  "%s (0x%x) at pc=" PTR_FORMAT ", pid=%d, tid=" UINTX_FORMAT,
-                 signame, _id, _pc,
+                 signame, id, pc,
                  os::current_process_id(), os::current_thread_id());
-  } else if (_filename != NULL && _lineno > 0) {
+  } else if (filename != NULL && lineno > 0) {
     // skip directory names
     char separator = os::file_separator()[0];
-    const char *p = strrchr(_filename, separator);
+    const char *p = strrchr(filename, separator);
     int n = jio_snprintf(buf, buflen,
                          "Internal Error at %s:%d, pid=%d, tid=" UINTX_FORMAT,
-                         p ? p + 1 : _filename, _lineno,
+                         p ? p + 1 : filename, lineno,
                          os::current_process_id(), os::current_thread_id());
-    if (n >= 0 && n < buflen && _message) {
-      if (_detail_msg) {
-        jio_snprintf(buf + n, buflen - n, "%s%s: %s",
-                     os::line_separator(), _message, _detail_msg);
+    if (n >= 0 && n < buflen && message) {
+      if (detail_fmt) {
+        int d = jio_snprintf(buf + n, buflen - n, "%s%s: ", os::line_separator(), message);
+        if (d >= 0) {
+          n += d;
+          if (n < buflen) {
+            jio_vsnprintf(buf + n, buflen - n, detail_fmt, detail_args);
+          }
+        }
       } else {
         jio_snprintf(buf + n, buflen - n, "%sError: %s",
-                     os::line_separator(), _message);
+                     os::line_separator(), message);
       }
     }
   } else {
     jio_snprintf(buf, buflen,
                  "Internal Error (0x%x), pid=%d, tid=" UINTX_FORMAT,
-                 _id, os::current_process_id(), os::current_thread_id());
+                 id, os::current_process_id(), os::current_thread_id());
   }
 
   return buf;
 }
 

@@ -355,11 +258,17 @@
 // when stack space is already low. Making things even worse is that there
 // could be nested report_and_die() calls on stack (see above). Only one
 // thread can report error, so large buffers are statically allocated in data
 // segment.
 
-void VMError::report(outputStream* st) {
+int          VMError::_current_step;
+const char*  VMError::_current_step_info;
+int          VMError::_verbose;
+
+void VMError::report(outputStream* st, int id, const char* message, const char* detail_fmt,
+                     va_list detail_args, Thread* thread, address pc, void* siginfo, void* context,
+                     const char* filename, int lineno, size_t size) {
 # define BEGIN if (_current_step == 0) { _current_step = 1;
 # define STEP(n, s) } if (_current_step < n) { _current_step = n; _current_step_info = s;
 # define END }
 
   // don't allocate large buffer on stack

@@ -368,11 +277,11 @@
   BEGIN
 
   STEP(10, "(printing fatal error message)")
 
     st->print_cr("#");
-    if (should_report_bug(_id)) {
+    if (should_report_bug(id)) {
       st->print_cr("# A fatal error has been detected by the Java Runtime Environment:");
     } else {
       st->print_cr("# There is insufficient memory for the Java "
                    "Runtime Environment to continue.");
     }

@@ -417,29 +326,29 @@
     }
 #endif // PRODUCT
 
   STEP(50, "(printing type of error)")
 
-     switch(_id) {
+     switch(id) {
        case OOM_MALLOC_ERROR:
        case OOM_MMAP_ERROR:
-         if (_size) {
+         if (size) {
            st->print("# Native memory allocation ");
-           st->print((_id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " :
+           st->print((id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " :
                                                  "(mmap) failed to map ");
-           jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
+           jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, size);
            st->print("%s", buf);
            st->print(" bytes");
-           if (_message != NULL) {
+           if (detail_fmt != NULL) {
              st->print(" for ");
-             st->print("%s", _message);
+             st->vprint(detail_fmt, detail_args);
            }
            st->cr();
          } else {
-           if (_message != NULL) {
+           if (detail_fmt != NULL) {
              st->print("# ");
-             st->print_cr("%s", _message);
+             st->vprint_cr(detail_fmt, detail_args);
            }
          }
          // In error file give some solutions
          if (_verbose) {
            print_oom_reasons(st);

@@ -455,32 +364,32 @@
   STEP(60, "(printing exception/signal name)")
 
      st->print_cr("#");
      st->print("#  ");
      // Is it an OS exception/signal?
-     if (os::exception_name(_id, buf, sizeof(buf))) {
+     if (os::exception_name(id, buf, sizeof(buf))) {
        st->print("%s", buf);
-       st->print(" (0x%x)", _id);                // signal number
-       st->print(" at pc=" PTR_FORMAT, _pc);
+       st->print(" (0x%x)", id);                // signal number
+       st->print(" at pc=" PTR_FORMAT, pc);
      } else {
-       if (should_report_bug(_id)) {
+       if (should_report_bug(id)) {
          st->print("Internal Error");
        } else {
          st->print("Out of Memory Error");
        }
-       if (_filename != NULL && _lineno > 0) {
+       if (filename != NULL && lineno > 0) {
 #ifdef PRODUCT
          // In product mode chop off pathname?
          char separator = os::file_separator()[0];
-         const char *p = strrchr(_filename, separator);
-         const char *file = p ? p+1 : _filename;
+         const char *p = strrchr(filename, separator);
+         const char *file = p ? p+1 : filename;
 #else
-         const char *file = _filename;
+         const char *file = filename;
 #endif
-         st->print(" (%s:%d)", file, _lineno);
+         st->print(" (%s:%d)", file, lineno);
        } else {
-         st->print(" (0x%x)", _id);
+         st->print(" (0x%x)", id);
        }
      }
 
   STEP(70, "(printing current thread and pid)")
 

@@ -489,16 +398,17 @@
      st->print(", tid=" UINTX_FORMAT, os::current_thread_id());
      st->cr();
 
   STEP(80, "(printing error message)")
 
-     if (should_report_bug(_id)) {  // already printed the message.
+     if (should_report_bug(id)) {  // already printed the message.
        // error message
-       if (_detail_msg) {
-         st->print_cr("#  %s: %s", _message ? _message : "Error", _detail_msg);
-       } else if (_message) {
-         st->print_cr("#  Error: %s", _message);
+       if (detail_fmt) {
+         st->print("#  %s: ", message ? message : "Error");
+         st->vprint_cr(detail_fmt, detail_args);
+       } else if (message) {
+         st->print_cr("#  Error: %s", message);
        }
     }
 
   STEP(90, "(printing Java version string)")
 

@@ -522,14 +432,14 @@
                  );
 
   STEP(100, "(printing problematic frame)")
 
      // Print current frame if we have a context (i.e. it's a crash)
-     if (_context) {
+     if (context) {
        st->print_cr("# Problematic frame:");
        st->print("# ");
-       frame fr = os::fetch_frame_from_context(_context);
+       frame fr = os::fetch_frame_from_context(context);
        fr.print_on_error(st, buf, sizeof(buf));
        st->cr();
        st->print_cr("#");
      }
 

@@ -547,12 +457,12 @@
     st->cr();
     st->print_cr("#");
 
   STEP(120, "(printing bug submit message)")
 
-     if (should_report_bug(_id) && _verbose) {
-       print_bug_submit_message(st, _thread);
+     if (should_report_bug(id) && _verbose) {
+       print_bug_submit_message(st, thread);
      }
 
   STEP(130, "(printing summary)" )
 
      if (_verbose) {

@@ -592,24 +502,24 @@
 
   STEP(180, "(printing current thread)" )
 
      // current thread
      if (_verbose) {
-       if (_thread) {
-         st->print("Current thread (" PTR_FORMAT "):  ", _thread);
-         _thread->print_on_error(st, buf, sizeof(buf));
+       if (thread) {
+         st->print("Current thread (" PTR_FORMAT "):  ", thread);
+         thread->print_on_error(st, buf, sizeof(buf));
          st->cr();
        } else {
          st->print_cr("Current thread is native thread");
        }
        st->cr();
      }
 
   STEP(190, "(printing current compile task)" )
 
-     if (_verbose && _thread && _thread->is_Compiler_thread()) {
-        CompilerThread* t = (CompilerThread*)_thread;
+     if (_verbose && thread && thread->is_Compiler_thread()) {
+        CompilerThread* t = (CompilerThread*)thread;
         if (t->task()) {
            st->cr();
            st->print_cr("Current CompileTask:");
            t->task()->print_line_on_error(st, buf, sizeof(buf));
            st->cr();

@@ -623,22 +533,22 @@
        st->print("Stack: ");
 
        address stack_top;
        size_t stack_size;
 
-       if (_thread) {
-          stack_top = _thread->stack_base();
-          stack_size = _thread->stack_size();
+       if (thread) {
+          stack_top = thread->stack_base();
+          stack_size = thread->stack_size();
        } else {
           stack_top = os::current_stack_base();
           stack_size = os::current_stack_size();
        }
 
        address stack_bottom = stack_top - stack_size;
        st->print("[" PTR_FORMAT "," PTR_FORMAT "]", stack_bottom, stack_top);
 
-       frame fr = _context ? os::fetch_frame_from_context(_context)
+       frame fr = context ? os::fetch_frame_from_context(context)
                            : os::current_frame();
 
        if (fr.sp()) {
          st->print(",  sp=" PTR_FORMAT, fr.sp());
          size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024);

@@ -649,67 +559,67 @@
      }
 
   STEP(210, "(printing native stack)" )
 
    if (_verbose) {
-     if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) {
+     if (os::platform_print_native_stack(st, context, buf, sizeof(buf))) {
        // We have printed the native stack in platform-specific code
        // Windows/x64 needs special handling.
      } else {
-       frame fr = _context ? os::fetch_frame_from_context(_context)
+       frame fr = context ? os::fetch_frame_from_context(context)
                            : os::current_frame();
 
-       print_native_stack(st, fr, _thread, buf, sizeof(buf));
+       print_native_stack(st, fr, thread, buf, sizeof(buf));
      }
    }
 
   STEP(220, "(printing Java stack)" )
 
-     if (_verbose && _thread && _thread->is_Java_thread()) {
-       print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf));
+     if (_verbose && thread && thread->is_Java_thread()) {
+       print_stack_trace(st, (JavaThread*)thread, buf, sizeof(buf));
      }
 
   STEP(230, "(printing target Java thread stack)" )
 
      // printing Java thread stack trace if it is involved in GC crash
-     if (_verbose && _thread && (_thread->is_Named_thread())) {
-       JavaThread*  jt = ((NamedThread *)_thread)->processed_thread();
+     if (_verbose && thread && (thread->is_Named_thread())) {
+       JavaThread*  jt = ((NamedThread *)thread)->processed_thread();
        if (jt != NULL) {
          st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id());
          print_stack_trace(st, jt, buf, sizeof(buf), true);
        }
      }
 
   STEP(240, "(printing siginfo)" )
 
      // signal no, signal code, address that caused the fault
-     if (_verbose && _siginfo) {
+     if (_verbose && siginfo) {
        st->cr();
-       os::print_siginfo(st, _siginfo);
+       os::print_siginfo(st, siginfo);
        st->cr();
      }
 
   STEP(250, "(printing register info)")
 
      // decode register contents if possible
-     if (_verbose && _context && Universe::is_fully_initialized()) {
-       os::print_register_info(st, _context);
+     if (_verbose && context && Universe::is_fully_initialized()) {
+       os::print_register_info(st, context);
        st->cr();
      }
 
   STEP(260, "(printing registers, top of stack, instructions near pc)")
 
      // registers, top of stack, instructions near pc
-     if (_verbose && _context) {
-       os::print_context(st, _context);
+     if (_verbose && context) {
+       os::print_context(st, context);
        st->cr();
      }
 
   STEP(270, "(printing VM operation)" )
 
-     if (_verbose && _thread && _thread->is_VM_thread()) {
-        VMThread* t = (VMThread*)_thread;
+     if (_verbose && thread && thread->is_VM_thread()) {
+        VMThread* t = (VMThread*)thread;
         VM_Operation* op = t->vm_operation();
         if (op) {
           op->print_on_error(st);
           st->cr();
           st->cr();

@@ -725,12 +635,12 @@
      }
 
   STEP(290, "(printing all threads)" )
 
      // all threads
-     if (_verbose && _thread) {
-       Threads::print_on_error(st, _thread, buf, sizeof(buf));
+     if (_verbose && thread) {
+       Threads::print_on_error(st, thread, buf, sizeof(buf));
        st->cr();
      }
 
   STEP(300, "(printing VM state)" )
 

@@ -894,11 +804,10 @@
 # undef BEGIN
 # undef STEP
 # undef END
 }
 
-VMError* volatile VMError::first_error = NULL;
 volatile jlong VMError::first_error_tid = -1;
 
 // An error could happen before tty is initialized or after it has been
 // destroyed. Here we use a very simple unbuffered fdStream for printing.
 // Only out.print_raw() and out.print_raw_cr() should be used, as other

@@ -956,11 +865,52 @@
    }
 
   return fd;
 }
 
-void VMError::report_and_die() {
+void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo,
+                             void* context, const char* detail_fmt, ...)
+{
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  report_and_die(sig, NULL, detail_fmt, detail_args, thread, pc, siginfo, context, NULL, 0, 0);
+  va_end(detail_args);
+}
+
+void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context)
+{
+  report_and_die(thread, sig, pc, siginfo, context, "%s", "");
+}
+
+void VMError::report_and_die(const char* message, const char* detail_fmt, ...)
+{
+  va_list detail_args;
+  va_start(detail_args, detail_fmt);
+  report_and_die(INTERNAL_ERROR, message, detail_fmt, detail_args, NULL, NULL, NULL, NULL, NULL, 0, 0);
+  va_end(detail_args);
+}
+
+void VMError::report_and_die(const char* message)
+{
+  report_and_die(message, "%s", "");
+}
+
+void VMError::report_and_die(Thread* thread, const char* filename, int lineno, const char* message,
+                             const char* detail_fmt, va_list detail_args)
+{
+  report_and_die(INTERNAL_ERROR, message, detail_fmt, detail_args, thread, NULL, NULL, NULL, filename, lineno, 0);
+}
+
+void VMError::report_and_die(Thread* thread, const char* filename, int lineno, size_t size,
+                             VMErrorType vm_err_type, const char* detail_fmt, va_list detail_args) {
+  report_and_die(vm_err_type, NULL, detail_fmt, detail_args, thread, NULL, NULL, NULL, filename, lineno, size);
+}
+
+void VMError::report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
+                             Thread* thread, address pc, void* siginfo, void* context, const char* filename,
+                             int lineno, size_t size)
+{
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
 
   // How many errors occurred in error handler when reporting first_error.
   static int recursive_error_count;

@@ -973,19 +923,21 @@
 
   if (SuppressFatalErrorMessage) {
       os::abort(CreateCoredumpOnCrash);
   }
   jlong mytid = os::current_thread_id();
-  if (first_error == NULL &&
-      Atomic::cmpxchg_ptr(this, &first_error, NULL) == NULL) {
+  if (first_error_tid == -1 &&
+      Atomic::cmpxchg(mytid, &first_error_tid, -1) == -1) {
 
     // first time
-    first_error_tid = mytid;
     set_error_reported();
 
     if (ShowMessageBoxOnError || PauseAtExit) {
-      show_message_box(buffer, sizeof(buffer));
+      va_list tmp_args;
+      va_copy(tmp_args, detail_args);
+      show_message_box(buffer, sizeof(buffer), id, message, detail_fmt, tmp_args, pc, filename, lineno);
+      va_end(tmp_args);
 
       // User has asked JVM to abort. Reset ShowMessageBoxOnError so the
       // WatcherThread can kill JVM if the error handler hangs.
       ShowMessageBoxOnError = false;
     }

@@ -1020,12 +972,11 @@
         os::die();
       }
 
       jio_snprintf(buffer, sizeof(buffer),
                    "[error occurred during error reporting %s, id 0x%x]",
-                   first_error ? first_error->_current_step_info : "",
-                   _id);
+                   _current_step_info, id);
       if (log.is_open()) {
         log.cr();
         log.print_raw_cr(buffer);
         log.cr();
       } else {

@@ -1036,24 +987,27 @@
     }
   }
 
   // print to screen
   if (!out_done) {
-    first_error->_verbose = false;
+    _verbose = false;
 
     staticBufferStream sbs(buffer, sizeof(buffer), &out);
-    first_error->report(&sbs);
+    va_list tmp_args;
+    va_copy(tmp_args, detail_args);
+    report(&sbs, id, message, detail_fmt, tmp_args, thread, pc, siginfo, context, filename, lineno, size);
+    va_end(tmp_args);
 
     out_done = true;
 
-    first_error->_current_step = 0;         // reset current_step
-    first_error->_current_step_info = "";   // reset current_step string
+    _current_step = 0;         // reset current_step
+    _current_step_info = "";   // reset current_step string
   }
 
   // print to error log file
   if (!log_done) {
-    first_error->_verbose = true;
+    _verbose = true;
 
     // see if log file is already open
     if (!log.is_open()) {
       // open log file
       int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));

@@ -1070,16 +1024,19 @@
         transmit_report_done = true;
       }
     }
 
     staticBufferStream sbs(buffer, O_BUFLEN, &log);
-    first_error->report(&sbs);
-    first_error->_current_step = 0;         // reset current_step
-    first_error->_current_step_info = "";   // reset current_step string
+    va_list tmp_args;
+    va_copy(tmp_args, detail_args);
+    report(&sbs, id, message, detail_fmt, tmp_args, thread, pc, siginfo, context, filename, lineno, size);
+    va_end(tmp_args);
+    _current_step = 0;         // reset current_step
+    _current_step_info = "";   // reset current_step string
 
     // Run error reporting to determine whether or not to report the crash.
-    if (!transmit_report_done && should_report_bug(first_error->_id)) {
+    if (!transmit_report_done && should_report_bug(id)) {
       transmit_report_done = true;
       const int fd2 = ::dup(log.fd());
       FILE* const hs_err = ::fdopen(fd2, "r");
       if (NULL != hs_err) {
         ErrorReporter er;

@@ -1127,11 +1084,11 @@
     // done with OnError
     OnError = NULL;
   }
 
   static bool skip_replay = ReplayCompiles; // Do not overwrite file during replay
-  if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) {
+  if (DumpReplayDataOnError && thread && thread->is_Compiler_thread() && !skip_replay) {
     skip_replay = true;
     ciEnv* env = ciEnv::current();
     if (env != NULL) {
       int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", buffer, sizeof(buffer));
       if (fd != -1) {

@@ -1147,25 +1104,25 @@
         }
       }
     }
   }
 
-  static bool skip_bug_url = !should_report_bug(first_error->_id);
+  static bool skip_bug_url = !should_report_bug(id);
   if (!skip_bug_url) {
     skip_bug_url = true;
 
     out.print_raw_cr("#");
-    print_bug_submit_message(&out, _thread);
+    print_bug_submit_message(&out, thread);
   }
 
   if (!UseOSErrorReporting) {
     // os::abort() will call abort hooks, try it first.
     static bool skip_os_abort = false;
     if (!skip_os_abort) {
       skip_os_abort = true;
-      bool dump_core = should_report_bug(first_error->_id);
-      os::abort(dump_core && CreateCoredumpOnCrash, _siginfo, _context);
+      bool dump_core = should_report_bug(id);
+      os::abort(dump_core && CreateCoredumpOnCrash, siginfo, context);
     }
 
     // if os::abort() doesn't abort, try os::die();
     os::die();
   }

@@ -1175,23 +1132,23 @@
  * OnOutOfMemoryError scripts/commands executed while VM is a safepoint - this
  * ensures utilities such as jmap can observe the process is a consistent state.
  */
 class VM_ReportJavaOutOfMemory : public VM_Operation {
  private:
-  VMError *_err;
+  const char* _message;
  public:
-  VM_ReportJavaOutOfMemory(VMError *err) { _err = err; }
+  VM_ReportJavaOutOfMemory(const char* message) { _message = message; }
   VMOp_Type type() const                 { return VMOp_ReportJavaOutOfMemory; }
   void doit();
 };
 
 void VM_ReportJavaOutOfMemory::doit() {
   // Don't allocate large buffer on stack
   static char buffer[O_BUFLEN];
 
   tty->print_cr("#");
-  tty->print_cr("# java.lang.OutOfMemoryError: %s", _err->message());
+  tty->print_cr("# java.lang.OutOfMemoryError: %s", _message);
   tty->print_cr("# -XX:OnOutOfMemoryError=\"%s\"", OnOutOfMemoryError);
 
   // make heap parsability
   Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
 

@@ -1210,12 +1167,12 @@
       tty->print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno);
     }
   }
 }
 
-void VMError::report_java_out_of_memory() {
+void VMError::report_java_out_of_memory(const char* message) {
   if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
     MutexLocker ml(Heap_lock);
-    VM_ReportJavaOutOfMemory op(this);
+    VM_ReportJavaOutOfMemory op(message);
     VMThread::execute(&op);
   }
 }
< prev index next >