From c32a3774e9c1eeb289d71e0e53199893b6951b1b Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Tue, 18 Sep 2012 17:50:59 -0700 Subject: [PATCH] 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 (cherry-pick of b3667a19f5c573b7785876979af4781292d27327.) Change-Id: I0a40cb3d3cdd9aef8589a39586cccd9c229aa8cb --- vm/Misc.cpp | 6 ++++-- vm/Misc.h | 1 + vm/Thread.cpp | 16 ++++++++++++---- vm/interp/Stack.cpp | 2 ++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/vm/Misc.cpp b/vm/Misc.cpp index f07684878b..1f01c2f454 100644 --- a/vm/Misc.cpp +++ b/vm/Misc.cpp @@ -699,8 +699,10 @@ bool dvmGetThreadStats(ProcStatData* pData, pid_t tid) 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 86e0a71c45..4c425760d1 100644 --- a/vm/Misc.h +++ b/vm/Misc.h @@ -300,6 +300,7 @@ void *dvmAllocRegion(size_t size, int prot, const char *name); * 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 aa2352af29..7f6f583762 100644 --- a/vm/Thread.cpp +++ b/vm/Thread.cpp @@ -3236,9 +3236,9 @@ static void dumpSchedStat(const DebugOutputTarget* target, pid_t tid) { /* 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 @@ void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread, 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 a1f8d71302..9ef92c7b99 100644 --- a/vm/interp/Stack.cpp +++ b/vm/interp/Stack.cpp @@ -1401,6 +1401,8 @@ void dvmDumpNativeStack(const DebugOutputTarget* target, pid_t tid) } free_backtrace_symbols(backtrace_symbols, frames); + } else { + dvmPrintDebugMessage(target, " (native backtrace unavailable)\n"); } #endif }