From b78eab06552c503106eec5dc832a1eb5b1e0205a Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 19 Oct 2011 20:32:03 -0700 Subject: [PATCH] Dump native stack of JNI methods when handling SIGQUIT. Change-Id: I7da7259f1350e853153ba4dea96797fc86284068 --- vm/ReconfigureDvm.mk | 2 +- vm/Thread.cpp | 5 +++++ vm/interp/Stack.cpp | 37 +++++++++++++++++++++++++++++++++++++ vm/interp/Stack.h | 1 + 4 files changed, 44 insertions(+), 1 deletion(-) 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 #include +#ifdef HAVE_ANDROID_OS +#include +#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 : ""; + 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_ -- 2.11.0