diff --git a/src/hotspot/share/runtime/handshake.cpp b/src/hotspot/share/runtime/handshake.cpp index c55803242de15..39ae4f18998f2 100644 --- a/src/hotspot/share/runtime/handshake.cpp +++ b/src/hotspot/share/runtime/handshake.cpp @@ -45,6 +45,7 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/preserveException.hpp" #include "utilities/systemMemoryBarrier.hpp" +#include "utilities/vmError.hpp" class HandshakeOperation : public CHeapObj { friend class HandshakeState; @@ -201,6 +202,7 @@ static void handle_timeout(HandshakeOperation* op, JavaThread* target) { } if (target != nullptr) { + VMError::set_handshake_timed_out_thread(p2i(target)); if (os::signal_thread(target, SIGILL, "cannot be handshaked")) { // Give target a chance to report the error and terminate the VM. os::naked_sleep(3000); @@ -208,7 +210,11 @@ static void handle_timeout(HandshakeOperation* op, JavaThread* target) { } else { log_error(handshake)("No thread with an unfinished handshake op(" INTPTR_FORMAT ") found.", p2i(op)); } - fatal("Handshake timeout"); + if (target != nullptr) { + fatal("Thread " PTR_FORMAT " has not cleared handshake op %s, and failed to terminate the JVM", p2i(target), op->name()); + } else { + fatal("Handshake timeout"); + } } static void check_handshake_timeout(jlong start_time, HandshakeOperation* op, JavaThread* target = nullptr) { diff --git a/src/hotspot/share/runtime/safepoint.cpp b/src/hotspot/share/runtime/safepoint.cpp index ab896290007e0..6fcf1e6c0f5bf 100644 --- a/src/hotspot/share/runtime/safepoint.cpp +++ b/src/hotspot/share/runtime/safepoint.cpp @@ -66,6 +66,7 @@ #include "utilities/events.hpp" #include "utilities/macros.hpp" #include "utilities/systemMemoryBarrier.hpp" +#include "utilities/vmError.hpp" static void post_safepoint_begin_event(EventSafepointBegin& event, uint64_t safepoint_id, @@ -650,6 +651,7 @@ void SafepointSynchronize::print_safepoint_timeout() { // Send the blocking thread a signal to terminate and write an error file. for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) { if (cur_thread->safepoint_state()->is_running()) { + VMError::set_safepoint_timed_out_thread(p2i(cur_thread)); if (!os::signal_thread(cur_thread, SIGILL, "blocking a safepoint")) { break; // Could not send signal. Report fatal error. } diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index df41594468247..bd882a7ef3cbb 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -104,6 +104,8 @@ int VMError::_lineno; size_t VMError::_size; const size_t VMError::_reattempt_required_stack_headroom = 64 * K; const intptr_t VMError::segfault_address = pd_segfault_address; +volatile intptr_t VMError::_handshake_timed_out_thread = p2i(nullptr); +volatile intptr_t VMError::_safepoint_timed_out_thread = p2i(nullptr); // List of environment variables that should be reported in error log file. static const char* env_list[] = { @@ -819,7 +821,13 @@ void VMError::report(outputStream* st, bool _verbose) { st->print(" (0x%x)", _id); // signal number st->print(" at pc=" PTR_FORMAT, p2i(_pc)); if (_siginfo != nullptr && os::signal_sent_by_kill(_siginfo)) { - st->print(" (sent by kill)"); + if (_handshake_timed_out_thread == p2i(_thread)) { + st->print(" (sent by handshake timeout handler"); + } else if (_safepoint_timed_out_thread == p2i(_thread)) { + st->print(" (sent by safepoint timeout handler"); + } else { + st->print(" (sent by kill)"); + } } } else { if (should_report_bug(_id)) { @@ -1330,6 +1338,14 @@ void VMError::report(outputStream* st, bool _verbose) { # undef END } +void VMError::set_handshake_timed_out_thread(intptr_t thread_addr) { + _handshake_timed_out_thread = thread_addr; +} + +void VMError::set_safepoint_timed_out_thread(intptr_t thread_addr) { + _safepoint_timed_out_thread = thread_addr; +} + // Report for the vm_info_cmd. This prints out the information above omitting // crash and thread specific information. If output is added above, it should be added // here also, if it is safe to call during a running process. diff --git a/src/hotspot/share/utilities/vmError.hpp b/src/hotspot/share/utilities/vmError.hpp index 0109b9bf0bd02..96e37acff576f 100644 --- a/src/hotspot/share/utilities/vmError.hpp +++ b/src/hotspot/share/utilities/vmError.hpp @@ -142,6 +142,10 @@ class VMError : public AllStatic { static jlong get_step_start_time(); static void clear_step_start_time(); + // Handshake/safepoint timed out threads + static volatile intptr_t _handshake_timed_out_thread; + static volatile intptr_t _safepoint_timed_out_thread; + WINDOWS_ONLY([[noreturn]] static void raise_fail_fast(const void* exrecord, const void* context);) public: @@ -218,6 +222,9 @@ class VMError : public AllStatic { static int prepare_log_file(const char* pattern, const char* default_pattern, bool overwrite_existing, char* buf, size_t buflen); static bool was_assert_poison_crash(const void* sigInfo); + + static void set_handshake_timed_out_thread(intptr_t thread_addr); + static void set_safepoint_timed_out_thread(intptr_t thread_addr); }; class VMErrorCallback { diff --git a/test/hotspot/jtreg/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java b/test/hotspot/jtreg/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java index c85dd6573381a..e28dd7f4d2ae2 100644 --- a/test/hotspot/jtreg/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java +++ b/test/hotspot/jtreg/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java @@ -88,7 +88,7 @@ private static void verifyAbortVmApplied(OutputAnalyzer output) { } else { output.shouldContain("SIGILL"); if (Platform.isLinux()) { - output.shouldContain("(sent by kill)"); + output.shouldContain("(sent by safepoint timeout handler"); } } output.shouldNotHaveExitValue(0);