Merge
authorplevart
Fri, 22 Jun 2018 18:19:26 +0200
changeset 50721 e541c1b68b89
parent 50720 c55b1386f119 (current diff)
parent 50718 5698cf4e50f1 (diff)
child 50722 bc104aaf24e9
Merge
--- a/src/hotspot/share/runtime/threadSMR.cpp	Fri Jun 22 18:18:05 2018 +0200
+++ b/src/hotspot/share/runtime/threadSMR.cpp	Fri Jun 22 18:19:26 2018 +0200
@@ -1067,8 +1067,15 @@
 
 // Print Threads class SMR info.
 void ThreadsSMRSupport::print_info_on(outputStream* st) {
-  // Only grab the Threads_lock if we don't already own it
-  // and if we are not reporting an error.
+  // Only grab the Threads_lock if we don't already own it and if we
+  // are not reporting an error.
+  // Note: Not grabbing the Threads_lock during error reporting is
+  // dangerous because the data structures we want to print can be
+  // freed concurrently. However, grabbing the Threads_lock during
+  // error reporting can be equally dangerous since this thread might
+  // block during error reporting or a nested error could leave the
+  // Threads_lock held. The classic no win scenario.
+  //
   MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock);
 
   st->print_cr("Threads class SMR info:");
--- a/src/hotspot/share/utilities/vmError.cpp	Fri Jun 22 18:18:05 2018 +0200
+++ b/src/hotspot/share/utilities/vmError.cpp	Fri Jun 22 18:19:26 2018 +0200
@@ -1698,6 +1698,13 @@
   // Case 15 is tested by test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java.
   // Case 16 is tested by test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java.
   // Case 17 is tested by test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java.
+
+  // We grab Threads_lock to keep ThreadsSMRSupport::print_info_on()
+  // from racing with Threads::add() or Threads::remove() as we
+  // generate the hs_err_pid file. This makes our ErrorHandling tests
+  // more stable.
+  MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
+
   switch (how) {
     case  1: vmassert(str == NULL, "expected null"); break;
     case  2: vmassert(num == 1023 && *str == 'X',