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