ART: Allow thread suspend lock to be held when dumping a thread

Only dumping a thread's suspend state requires holding the lock.
Specialize the code to recognize if the lock is already held,
and remove the negative capability from the callers.

Bug: 134037466
Bug: 134167395
Test: m
Test: m test-art-host-gtest-runtime_test
Change-Id: Ib55eafba72c5d15de01719840ba3f223ae4af8c7
diff --git a/runtime/runtime_test.cc b/runtime/runtime_test.cc
index aa4020e..282e430 100644
--- a/runtime/runtime_test.cc
+++ b/runtime/runtime_test.cc
@@ -40,4 +40,18 @@
   }, kDeathRegex);
 }
 
+
+TEST_F(RuntimeTest, AbortWithThreadSuspendCountLockHeld) {
+  // This assumes the test is run single-threaded: do not start the runtime to avoid daemon threads.
+
+  constexpr const char* kDeathRegex = "Skipping all-threads dump as locks are held";
+  ASSERT_DEATH({
+    // The regex only works if we can ensure output goes to stderr.
+    android::base::SetLogger(android::base::StderrLogger);
+
+    MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_);
+    Runtime::Abort("Attempt to abort");
+  }, kDeathRegex);
+}
+
 }  // namespace art