summaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2011-10-19 20:32:03 -0700
committerJeff Brown <jeffbrown@google.com>2011-10-22 15:43:01 -0700
commitb78eab06552c503106eec5dc832a1eb5b1e0205a (patch)
treeb0880d086541a9cec21b68968f4ae9846ccc2f8f /vm
parentb4593f197532419746a0df6d93fb33f8b815affc (diff)
downloadandroid_dalvik-b78eab06552c503106eec5dc832a1eb5b1e0205a.tar.gz
android_dalvik-b78eab06552c503106eec5dc832a1eb5b1e0205a.tar.bz2
android_dalvik-b78eab06552c503106eec5dc832a1eb5b1e0205a.zip
Dump native stack of JNI methods when handling SIGQUIT.
Change-Id: I7da7259f1350e853153ba4dea96797fc86284068
Diffstat (limited to 'vm')
-rw-r--r--vm/ReconfigureDvm.mk2
-rw-r--r--vm/Thread.cpp5
-rw-r--r--vm/interp/Stack.cpp37
-rw-r--r--vm/interp/Stack.h1
4 files changed, 44 insertions, 1 deletions
diff --git a/vm/ReconfigureDvm.mk b/vm/ReconfigureDvm.mk
index 20e562635..dd134823a 100644
--- a/vm/ReconfigureDvm.mk
+++ b/vm/ReconfigureDvm.mk
@@ -26,7 +26,7 @@ endif
include $(LOCAL_PATH)/Dvm.mk
-LOCAL_SHARED_LIBRARIES += liblog libcutils libnativehelper libz libdl
+LOCAL_SHARED_LIBRARIES += liblog libcutils libnativehelper libz libdl libcorkscrew
LOCAL_STATIC_LIBRARIES += libdex
diff --git a/vm/Thread.cpp b/vm/Thread.cpp
index 5122adfad..c375d57d3 100644
--- a/vm/Thread.cpp
+++ b/vm/Thread.cpp
@@ -3327,6 +3327,11 @@ void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
else
dvmDumpThreadStack(target, thread);
+ /* grab the native stack, if possible */
+ if (thread->status == THREAD_NATIVE) {
+ dvmDumpNativeStack(target, thread);
+ }
+
dvmReleaseTrackedAlloc(threadObj, NULL);
free(threadName);
free(groupName);
diff --git a/vm/interp/Stack.cpp b/vm/interp/Stack.cpp
index ad6af823d..98cc4ce97 100644
--- a/vm/interp/Stack.cpp
+++ b/vm/interp/Stack.cpp
@@ -25,6 +25,10 @@
#include <stdlib.h>
#include <stdarg.h>
+#ifdef HAVE_ANDROID_OS
+#include <corkscrew/backtrace.h>
+#endif
+
/*
* Initialize the interpreter stack in a new thread.
*
@@ -1378,3 +1382,36 @@ void dvmDumpRunningThreadStack(const DebugOutputTarget* target, Thread* thread)
dumpFrames(target, stackCopy + fpOffset, thread);
free(stackCopy);
}
+
+/*
+ * Dump the native stack for the specified thread.
+ */
+void dvmDumpNativeStack(const DebugOutputTarget* target, Thread* thread)
+{
+#ifdef HAVE_ANDROID_OS
+ const size_t MAX_DEPTH = 32;
+ backtrace_frame_t backtrace[MAX_DEPTH];
+ ssize_t frames = unwind_backtrace_thread(thread->systemTid, backtrace, 0, MAX_DEPTH);
+ if (frames > 0) {
+ backtrace_symbol_t backtrace_symbols[MAX_DEPTH];
+ get_backtrace_symbols(backtrace, frames, backtrace_symbols);
+
+ dvmPrintDebugMessage(target, "Native Stack:\n");
+ for (size_t i = 0; i < size_t(frames); i++) {
+ const backtrace_symbol_t& symbol = backtrace_symbols[i];
+ const char* mapName = symbol.map_info ? symbol.map_info->name : "<unknown>";
+ const char* symbolName = symbol.demangled_name ? symbol.demangled_name : symbol.name;
+ if (symbolName) {
+ dvmPrintDebugMessage(target, " #%02d pc %08x %s (%s)\n",
+ i, uint32_t(symbol.relative_pc), mapName, symbolName);
+ } else {
+ dvmPrintDebugMessage(target, " #%02d pc %08x %s\n",
+ i, uint32_t(symbol.relative_pc), mapName);
+ }
+ }
+ dvmPrintDebugMessage(target, "\n");
+
+ free_backtrace_symbols(backtrace_symbols, frames);
+ }
+#endif
+}
diff --git a/vm/interp/Stack.h b/vm/interp/Stack.h
index ef3db4a1b..4a1e5e644 100644
--- a/vm/interp/Stack.h
+++ b/vm/interp/Stack.h
@@ -275,5 +275,6 @@ extern "C" void dvmCleanupStackOverflow(Thread* self, const Object* exception);
/* debugging; dvmDumpThread() is probably a better starting point */
void dvmDumpThreadStack(const DebugOutputTarget* target, Thread* thread);
void dvmDumpRunningThreadStack(const DebugOutputTarget* target, Thread* thread);
+void dvmDumpNativeStack(const DebugOutputTarget* target, Thread* thread);
#endif // DALVIK_INTERP_STACK_H_