diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index bdf0902b96f..ba076586276 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -1878,13 +1878,17 @@ void os::shutdown() { // Note: os::abort() might be called very early during initialization, or // called from signal handler. Before adding something to os::abort(), make // sure it is async-safe and can handle partially initialized VM. +// Also note we can abort while other threads continue to run, so we can +// easily trigger secondary faults in those threads. To reduce the likelihood +// of that we use _exit rather than exit, so that no atexit hooks get run. +// But note that os::shutdown() could also trigger secondary faults. void os::abort(bool dump_core, void* siginfo, const void* context) { os::shutdown(); if (dump_core) { LINUX_ONLY(if (DumpPrivateMappingsInCore) ClassLoader::close_jrt_image();) ::abort(); // dump core } - ::exit(1); + ::_exit(1); } // Die immediately, no exit hook, no abort hook, no cleanup. diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 57296c3e2a1..31b78ee97ff 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -1372,13 +1372,14 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt static bool out_done = false; // done printing to standard out static bool log_done = false; // done saving error log - if (SuppressFatalErrorMessage) { - os::abort(CreateCoredumpOnCrash); - } intptr_t mytid = os::current_thread_id(); if (_first_error_tid == -1 && Atomic::cmpxchg(&_first_error_tid, (intptr_t)-1, mytid) == -1) { + if (SuppressFatalErrorMessage) { + os::abort(CreateCoredumpOnCrash); + } + // Initialize time stamps to use the same base. out.time_stamp().update_to(1); log.time_stamp().update_to(1); @@ -1428,21 +1429,33 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt // This is not the first error, see if it happened in a different thread // or in the same thread during error reporting. if (_first_error_tid != mytid) { - char msgbuf[64]; - jio_snprintf(msgbuf, sizeof(msgbuf), - "[thread " INTX_FORMAT " also had an error]", - mytid); - out.print_raw_cr(msgbuf); + if (!SuppressFatalErrorMessage) { + char msgbuf[64]; + jio_snprintf(msgbuf, sizeof(msgbuf), + "[thread " INTX_FORMAT " also had an error]", + mytid); + out.print_raw_cr(msgbuf); + } - // error reporting is not MT-safe, block current thread + // Error reporting is not MT-safe, nor can we let the current thread + // proceed, so we block it. os::infinite_sleep(); } else { if (recursive_error_count++ > 30) { - out.print_raw_cr("[Too many errors, abort]"); + if (!SuppressFatalErrorMessage) { + out.print_raw_cr("[Too many errors, abort]"); + } os::die(); } + if (SuppressFatalErrorMessage) { + // If we already hit a secondary error during abort, then calling + // it again is likely to hit another one. But eventually, if we + // don't deadlock somewhere, we will call os::die() above. + os::abort(CreateCoredumpOnCrash); + } + outputStream* const st = log.is_open() ? &log : &out; st->cr();