< prev index next >

src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp

Print this page

        

*** 330,366 **** } } /* * We are just about to exit the VM, so we will be very aggressive ! * at this point in order to increase overall success of dumping jfr data: ! * ! * 1. if the thread state is not "_thread_in_vm", we will quick transition ! * it to "_thread_in_vm". ! * 2. if the thread is the owner of some critical lock(s), unlock them. * * If we end up deadlocking in the attempt of dumping out jfr data, * we rely on the WatcherThread task "is_error_reported()", * to exit the VM after a hard-coded timeout (disallow WatcherThread to emergency dump). * This "safety net" somewhat explains the aggressiveness in this attempt. * */ static bool prepare_for_emergency_dump() { if (JfrStream_lock->owned_by_self()) { // crashed during jfr rotation, disallow recursion return false; } - Thread* const thread = Thread::current(); if (thread->is_Watcher_thread()) { // need WatcherThread as a safeguard against potential deadlocks return false; } - if (thread->is_Java_thread()) { - ((JavaThread*)thread)->set_thread_state(_thread_in_vm); - } - #ifdef ASSERT Mutex* owned_lock = thread->owned_locks(); while (owned_lock != NULL) { Mutex* next = owned_lock->next(); owned_lock->unlock(); --- 330,360 ---- } } /* * We are just about to exit the VM, so we will be very aggressive ! * at this point in order to increase overall success of dumping jfr data. * * If we end up deadlocking in the attempt of dumping out jfr data, * we rely on the WatcherThread task "is_error_reported()", * to exit the VM after a hard-coded timeout (disallow WatcherThread to emergency dump). * This "safety net" somewhat explains the aggressiveness in this attempt. * */ static bool prepare_for_emergency_dump() { + Thread* const thread = Thread::current_or_null_safe(); + assert(thread != NULL, "invariant"); + if (JfrStream_lock->owned_by_self()) { // crashed during jfr rotation, disallow recursion return false; } if (thread->is_Watcher_thread()) { // need WatcherThread as a safeguard against potential deadlocks return false; } #ifdef ASSERT Mutex* owned_lock = thread->owned_locks(); while (owned_lock != NULL) { Mutex* next = owned_lock->next(); owned_lock->unlock();
*** 426,439 **** static bool guard_reentrancy() { return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0; } void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { ! if (!(guard_reentrancy() && prepare_for_emergency_dump())) { return; } EventDumpReason event; if (event.should_commit()) { event.set_reason(exception_handler ? "Crash" : "Out of Memory"); event.set_recordingId(-1); event.commit(); --- 420,466 ---- static bool guard_reentrancy() { return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0; } + class JavaThreadInVM : public StackObj { + private: + JavaThread* _jt; + JavaThreadState _original_state; + + public: + + JavaThreadInVM(Thread* thread) : _jt(NULL), + _original_state(_thread_max_state) { + if ((thread != NULL) && thread->is_Java_thread()) { + _jt = (JavaThread*)thread; + _original_state = _jt->thread_state(); + _jt->set_thread_state(_thread_in_vm); + } + } + + ~JavaThreadInVM() { + if (_jt != NULL) { + _jt->set_thread_state(_original_state); + } + } + + }; + void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { ! if (!guard_reentrancy()) { return; } + + Thread* thread = Thread::current_or_null_safe(); + + // Ensure a JavaThread is _thread_in_vm when we make this call + JavaThreadInVM jtivm(thread); + if ((thread != NULL) && !prepare_for_emergency_dump()) { + return; + } + EventDumpReason event; if (event.should_commit()) { event.set_reason(exception_handler ? "Crash" : "Out of Memory"); event.set_recordingId(-1); event.commit();
< prev index next >