Also use ThreadList::Dump() in empty checkpoint timeout.

After dumping runnable threading that haven't responded to the empty
checkpoint request, use ThreadList::Dump() to try to dump the other
threads, noting that it may get stuck, but it's the end of logging
anyway. This should help diagnose the timeout better as we would be
able to see more threads.

Bug: 33006388
Bug: 12687968
Test: test-art-host with CC.
Change-Id: I6936098949d53dbc74af11fd5d796e1524581468
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index dccec9f..cebb566 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -832,7 +832,6 @@
       static constexpr uint64_t kEmptyCheckpointTimeoutMs = 600 * 1000;  // 10 minutes.
       bool timed_out = barrier->Increment(self, barrier_count, kEmptyCheckpointTimeoutMs);
       if (timed_out) {
-        Runtime* runtime = Runtime::Current();
         std::ostringstream ss;
         ss << "Empty checkpoint timeout\n";
         ss << "Barrier count " << barrier->GetCount(self) << "\n";
@@ -845,11 +844,11 @@
         ss << "\n";
         LOG(FATAL_WITHOUT_ABORT) << ss.str();
         // Some threads in 'runnable_thread_ids' are probably stuck. Try to dump their stacks.
-        // Avoid using ThreadList::Dump() because it is likely to get stuck as well.
+        // Avoid using ThreadList::Dump() initially because it is likely to get stuck as well.
         {
           ReaderMutexLock mu0(self, *Locks::mutator_lock_);
           MutexLock mu1(self, *Locks::thread_list_lock_);
-          for (Thread* thread : runtime->GetThreadList()->GetList()) {
+          for (Thread* thread : thread_list->GetList()) {
             uint32_t tid = thread->GetThreadId();
             bool is_in_runnable_thread_ids =
                 std::find(runnable_thread_ids.begin(), runnable_thread_ids.end(), tid) !=
@@ -862,7 +861,11 @@
             }
           }
         }
-        LOG(FATAL) << "Dumped runnable threads that haven't responded to empty checkpoint.";
+        LOG(FATAL_WITHOUT_ABORT)
+            << "Dumped runnable threads that haven't responded to empty checkpoint.";
+        // Now use ThreadList::Dump() to dump more threads, noting it may get stuck.
+        thread_list->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT));
+        LOG(FATAL) << "Dumped all threads.";
       }
     } else {
       barrier->Increment(self, barrier_count);