Log when the native trace is unavailable

This should allow us to differentiate between "couldn't get the
stack" and "didn't try to get the stack".  Also show the thread's
state (e.g. 'R' for running, 'D' for uninterruptible syscall).

Bug 7053953

Change-Id: Ibc9e6a6f0fc855a4e5e8e133122232dc939bcb16
diff --git a/vm/Misc.cpp b/vm/Misc.cpp
index f076848..1f01c2f 100644
--- a/vm/Misc.cpp
+++ b/vm/Misc.cpp
@@ -699,8 +699,10 @@
     char* cp = strchr(lineBuf, ')');
     if (cp == NULL)
         goto parse_fail;
-    cp++;
-    for (i = 2; i < 13; i++) {
+    cp += 2;
+    pData->state = *cp++;
+
+    for (i = 3; i < 13; i++) {
         cp = strchr(cp+1, ' ');
         if (cp == NULL)
             goto parse_fail;
diff --git a/vm/Misc.h b/vm/Misc.h
index 86e0a71..4c42576 100644
--- a/vm/Misc.h
+++ b/vm/Misc.h
@@ -300,6 +300,7 @@
  * Get some per-thread stats from /proc/self/task/N/stat.
  */
 struct ProcStatData {
+    char state;             /* process state, e.g. 'R', 'S', 'D' */
     unsigned long utime;    /* number of jiffies scheduled in user mode */
     unsigned long stime;    /* number of jiffies scheduled in kernel mode */
     int processor;          /* number of CPU that last executed thread */
diff --git a/vm/Thread.cpp b/vm/Thread.cpp
index aa2352a..7f6f583 100644
--- a/vm/Thread.cpp
+++ b/vm/Thread.cpp
@@ -3236,9 +3236,9 @@
 
     /* show what we got */
     dvmPrintDebugMessage(target,
-        "  | schedstat=( %s ) utm=%lu stm=%lu core=%d\n",
-        schedstatBuf, procStatData.utime, procStatData.stime,
-        procStatData.processor);
+        "  | state=%c schedstat=( %s ) utm=%lu stm=%lu core=%d\n",
+        procStatData.state, schedstatBuf, procStatData.utime,
+        procStatData.stime, procStatData.processor);
 #endif
 }
 
@@ -3344,7 +3344,15 @@
 
     dumpSchedStat(target, thread->systemTid);
 
-    /* grab the native stack, if possible */
+    /*
+     * Grab the native stack, if possible.
+     *
+     * The native thread is still running, even if the Dalvik side is
+     * suspended.  This means the thread can move itself out of NATIVE state
+     * while we're in here, shifting to SUSPENDED after a brief moment at
+     * RUNNING.  At that point the native stack isn't all that interesting,
+     * though, so if we fail to dump it there's little lost.
+     */
     if (thread->status == THREAD_NATIVE || thread->status == THREAD_VMWAIT) {
         dvmDumpNativeStack(target, thread->systemTid);
     }
diff --git a/vm/interp/Stack.cpp b/vm/interp/Stack.cpp
index a1f8d71..9ef92c7 100644
--- a/vm/interp/Stack.cpp
+++ b/vm/interp/Stack.cpp
@@ -1401,6 +1401,8 @@
         }
 
         free_backtrace_symbols(backtrace_symbols, frames);
+    } else {
+        dvmPrintDebugMessage(target, "  (native backtrace unavailable)\n");
     }
 #endif
 }