Include non-attached native threads in the SIGQUIT output.
These threads look something like this:
"droid.phasebeam' prio=5 tid=? (not attached)
| sysTid=5369 nice=-4 sched=0/0 cgrp=default
| schedstat=( 0 0 0 ) utm=1 stm=8 core=0 HZ=100
native: __futex_syscall3+8 [0x40074678] (libc.so)
native: __pthread_cond_timedwait_relative+48 [0x40079474] (libc.so)
native: __pthread_cond_timedwait+72 [0x40079528] (libc.so)
native: android::renderscript::Signal::wait(unsigned long long)+58 [0x418bf117] (libRS.so)
native: android::renderscript::LocklessCommandFifo::wait(unsigned long long)+38 [0x418bab97] (libRS.so)
native: android::renderscript::LocklessCommandFifo::get(unsigned int*, unsigned int*, unsigned long long)+22 [0x418babbb] (libRS.so)
native: android::renderscript::ThreadIO::playCoreCommands(android::renderscript::Context*, bool, unsigned long long)+126 [0x418bf84b] (libRS.so)
native: android::renderscript::Context::threadProc(void*)+382 [0x418b7347] (libRS.so)
native: __thread_entry+48 [0x40079d30] (libc.so)
native: pthread_create+180 [0x40079884] (libc.so)
Also fix running tests on Mac OS, which has no /proc/self/cmdline.
Change-Id: Ib5e6f7e23dd45aecdf814e84f573361a5d91bac6
diff --git a/src/thread_list.cc b/src/thread_list.cc
index e8b412c..3d0e0be 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -16,11 +16,14 @@
#include "thread_list.h"
+#include <dirent.h>
+#include <sys/types.h>
#include <unistd.h>
#include "debugger.h"
#include "scoped_heap_lock.h"
#include "scoped_thread_list_lock.h"
+#include "utils.h"
namespace art {
@@ -50,6 +53,15 @@
return find(list_.begin(), list_.end(), thread) != list_.end();
}
+bool ThreadList::Contains(pid_t tid) {
+ for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
+ if ((*it)->tid_ == tid) {
+ return true;
+ }
+ }
+ return false;
+}
+
pid_t ThreadList::GetLockOwner() {
return thread_list_lock_.GetOwner();
}
@@ -57,6 +69,32 @@
void ThreadList::DumpForSigQuit(std::ostream& os) {
ScopedThreadListLock thread_list_lock;
DumpLocked(os);
+ DumpUnattachedThreads(os);
+}
+
+static void DumpUnattachedThread(std::ostream& os, pid_t tid) {
+ Thread::DumpState(os, NULL, tid);
+ DumpKernelStack(os, tid, " kernel: ", false);
+ DumpNativeStack(os, tid, " native: ", false);
+ os << "\n";
+}
+
+void ThreadList::DumpUnattachedThreads(std::ostream& os) {
+ DIR* d = opendir("/proc/self/task");
+ if (!d) {
+ return;
+ }
+
+ dirent de;
+ dirent* result;
+ while (!readdir_r(d, &de, &result) && result != NULL) {
+ char* end;
+ pid_t tid = strtol(de.d_name, &end, 10);
+ if (!*end && !Contains(tid)) {
+ DumpUnattachedThread(os, tid);
+ }
+ }
+ closedir(d);
}
void ThreadList::DumpLocked(std::ostream& os) {