--- a/hotspot/src/share/vm/utilities/vmError.cpp Mon Sep 28 15:05:02 2015 +0200
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Tue Sep 29 11:02:08 2015 +0200
@@ -71,108 +71,6 @@
(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)
@@ -196,7 +94,6 @@
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:");
@@ -223,7 +120,6 @@
coredump_message[sizeof(coredump_message)-1] = 0;
}
-
// Return a string to describe the error
char* VMError::error_string(char* buf, int buflen) {
char signame_buf[64];
@@ -243,9 +139,9 @@
p ? p + 1 : _filename, _lineno,
os::current_process_id(), os::current_thread_id());
if (n >= 0 && n < buflen && _message) {
- if (_detail_msg) {
+ if (strlen(_detail_msg) > 0) {
jio_snprintf(buf + n, buflen - n, "%s%s: %s",
- os::line_separator(), _message, _detail_msg);
+ os::line_separator(), _message, _detail_msg);
} else {
jio_snprintf(buf + n, buflen - n, "%sError: %s",
os::line_separator(), _message);
@@ -357,7 +253,11 @@
// 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;
+
+void VMError::report(outputStream* st, bool _verbose) {
+
# 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 }
@@ -429,15 +329,15 @@
jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
st->print("%s", buf);
st->print(" bytes");
- if (_message != NULL) {
+ if (strlen(_detail_msg) > 0) {
st->print(" for ");
- st->print("%s", _message);
+ st->print("%s", _detail_msg);
}
st->cr();
} else {
- if (_message != NULL) {
+ if (strlen(_detail_msg) > 0) {
st->print("# ");
- st->print_cr("%s", _message);
+ st->print_cr("%s", _detail_msg);
}
}
// In error file give some solutions
@@ -493,12 +393,12 @@
if (should_report_bug(_id)) { // already printed the message.
// error message
- if (_detail_msg) {
+ if (strlen(_detail_msg) > 0) {
st->print_cr("# %s: %s", _message ? _message : "Error", _detail_msg);
} else if (_message) {
st->print_cr("# Error: %s", _message);
}
- }
+ }
STEP(90, "(printing Java version string)")
@@ -896,7 +796,6 @@
# 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
@@ -958,7 +857,59 @@
return fd;
}
-void VMError::report_and_die() {
+int VMError::_id;
+const char* VMError::_message;
+char VMError::_detail_msg[1024];
+Thread* VMError::_thread;
+address VMError::_pc;
+void* VMError::_siginfo;
+void* VMError::_context;
+const char* VMError::_filename;
+int VMError::_lineno;
+size_t VMError::_size;
+
+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];
@@ -975,11 +926,21 @@
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) {
+
+ _id = id;
+ _message = message;
+ _thread = thread;
+ _pc = pc;
+ _siginfo = siginfo;
+ _context = context;
+ _filename = filename;
+ _lineno = lineno;
+ _size = size;
+ jio_vsnprintf(_detail_msg, sizeof(_detail_msg), detail_fmt, detail_args);
// first time
- first_error_tid = mytid;
set_error_reported();
if (ShowMessageBoxOnError || PauseAtExit) {
@@ -1022,8 +983,7 @@
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);
@@ -1038,21 +998,17 @@
// print to screen
if (!out_done) {
- first_error->_verbose = false;
-
staticBufferStream sbs(buffer, sizeof(buffer), &out);
- first_error->report(&sbs);
+ report(&sbs, false);
out_done = true;
- first_error->_current_step = 0; // reset current_step
- first_error->_current_step_info = ""; // reset current_step string
+ _current_step = 0;
+ _current_step_info = "";
}
// print to error log file
if (!log_done) {
- first_error->_verbose = true;
-
// see if log file is already open
if (!log.is_open()) {
// open log file
@@ -1072,12 +1028,12 @@
}
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
+ report(&sbs, true);
+ _current_step = 0;
+ _current_step_info = "";
// 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");
@@ -1149,7 +1105,7 @@
}
}
- 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;
@@ -1162,7 +1118,7 @@
static bool skip_os_abort = false;
if (!skip_os_abort) {
skip_os_abort = true;
- bool dump_core = should_report_bug(first_error->_id);
+ bool dump_core = should_report_bug(_id);
os::abort(dump_core && CreateCoredumpOnCrash, _siginfo, _context);
}
@@ -1177,10 +1133,10 @@
*/
class VM_ReportJavaOutOfMemory : public VM_Operation {
private:
- VMError *_err;
+ const char* _message;
public:
- VM_ReportJavaOutOfMemory(VMError *err) { _err = err; }
- VMOp_Type type() const { return VMOp_ReportJavaOutOfMemory; }
+ VM_ReportJavaOutOfMemory(const char* message) { _message = message; }
+ VMOp_Type type() const { return VMOp_ReportJavaOutOfMemory; }
void doit();
};
@@ -1189,7 +1145,7 @@
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
@@ -1212,10 +1168,10 @@
}
}
-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);
}
}