src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp
changeset 58945 a3b046720c3b
parent 58863 c16ac7a2eba4
child 59252 623722a6aeb9
equal deleted inserted replaced
58944:bb2a436e616c 58945:a3b046720c3b
   330   }
   330   }
   331 }
   331 }
   332 
   332 
   333 /*
   333 /*
   334 * We are just about to exit the VM, so we will be very aggressive
   334 * We are just about to exit the VM, so we will be very aggressive
   335 * at this point in order to increase overall success of dumping jfr data:
   335 * at this point in order to increase overall success of dumping jfr data.
   336 *
       
   337 * 1. if the thread state is not "_thread_in_vm", we will quick transition
       
   338 *    it to "_thread_in_vm".
       
   339 * 2. if the thread is the owner of some critical lock(s), unlock them.
       
   340 *
   336 *
   341 * If we end up deadlocking in the attempt of dumping out jfr data,
   337 * If we end up deadlocking in the attempt of dumping out jfr data,
   342 * we rely on the WatcherThread task "is_error_reported()",
   338 * we rely on the WatcherThread task "is_error_reported()",
   343 * to exit the VM after a hard-coded timeout (disallow WatcherThread to emergency dump).
   339 * to exit the VM after a hard-coded timeout (disallow WatcherThread to emergency dump).
   344 * This "safety net" somewhat explains the aggressiveness in this attempt.
   340 * This "safety net" somewhat explains the aggressiveness in this attempt.
   345 *
   341 *
   346 */
   342 */
   347 static bool prepare_for_emergency_dump() {
   343 static bool prepare_for_emergency_dump(Thread* thread) {
       
   344   assert(thread != NULL, "invariant");
       
   345 
       
   346   if (thread->is_Watcher_thread()) {
       
   347     // need WatcherThread as a safeguard against potential deadlocks
       
   348     return false;
       
   349   }
   348   if (JfrStream_lock->owned_by_self()) {
   350   if (JfrStream_lock->owned_by_self()) {
   349     // crashed during jfr rotation, disallow recursion
   351     // crashed during jfr rotation, disallow recursion
   350     return false;
   352     return false;
   351   }
       
   352   Thread* const thread = Thread::current();
       
   353   if (thread->is_Watcher_thread()) {
       
   354     // need WatcherThread as a safeguard against potential deadlocks
       
   355     return false;
       
   356   }
       
   357 
       
   358   if (thread->is_Java_thread()) {
       
   359     ((JavaThread*)thread)->set_thread_state(_thread_in_vm);
       
   360   }
   353   }
   361 
   354 
   362 #ifdef ASSERT
   355 #ifdef ASSERT
   363   Mutex* owned_lock = thread->owned_locks();
   356   Mutex* owned_lock = thread->owned_locks();
   364   while (owned_lock != NULL) {
   357   while (owned_lock != NULL) {
   426 
   419 
   427 static bool guard_reentrancy() {
   420 static bool guard_reentrancy() {
   428   return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0;
   421   return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0;
   429 }
   422 }
   430 
   423 
       
   424 class JavaThreadInVM : public StackObj {
       
   425  private:
       
   426   JavaThread* const _jt;
       
   427   JavaThreadState _original_state;
       
   428  public:
       
   429 
       
   430   JavaThreadInVM(Thread* t) : _jt(t->is_Java_thread() ? (JavaThread*)t : NULL),
       
   431                               _original_state(_thread_max_state) {
       
   432     if ((_jt != NULL) && (_jt->thread_state() != _thread_in_vm)) {
       
   433       _original_state = _jt->thread_state();
       
   434       _jt->set_thread_state(_thread_in_vm);
       
   435     }
       
   436   }
       
   437 
       
   438   ~JavaThreadInVM() {
       
   439     if (_original_state != _thread_max_state) {
       
   440       _jt->set_thread_state(_original_state);
       
   441     }
       
   442   }
       
   443 
       
   444 };
       
   445 
   431 void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) {
   446 void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) {
   432   if (!(guard_reentrancy() && prepare_for_emergency_dump())) {
   447   if (!guard_reentrancy()) {
   433     return;
   448     return;
   434   }
   449   }
       
   450 
       
   451   Thread* thread = Thread::current_or_null_safe();
       
   452   if (thread == NULL) {
       
   453     return;
       
   454   }
       
   455   // Ensure a JavaThread is _thread_in_vm when we make this call
       
   456   JavaThreadInVM jtivm(thread);
       
   457   if (!prepare_for_emergency_dump(thread)) {
       
   458     return;
       
   459   }
       
   460 
   435   EventDumpReason event;
   461   EventDumpReason event;
   436   if (event.should_commit()) {
   462   if (event.should_commit()) {
   437     event.set_reason(exception_handler ? "Crash" : "Out of Memory");
   463     event.set_reason(exception_handler ? "Crash" : "Out of Memory");
   438     event.set_recordingId(-1);
   464     event.set_recordingId(-1);
   439     event.commit();
   465     event.commit();