Switch to libcorkscrew for native stack traces.
This is both for the current thread (which backtrace(3) could do) and other
threads, which is functionality we didn't have on x86 before.
We jump through the appropriate hoops to get static symbols as well as dynamic
ones.
Also unify the existing native stack dumpers so they can share the best code.
Example x86 check failure:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR) fault addr 0xdeadd00d
Registers:
eax: 0x00000000 ebx: 0x55a966f0 ecx: 0x55d523c0 edx: 0x09225a50
edi: 0x559d9b84 esi: 0xfffd8bcc ebp: 0x55a9aba0 esp: 0xfffd8b90
eip: 0x558e2e98 eflags: 0x00010246 [ PF ZF IF ]
cs: 0x00000023 ds: 0x0000002b es: 0x0000002b fs: 0x00000007
gs: 0x00000063 ss: 0x0000002b
Backtrace:
#00 unwind_backtrace_thread+536 [0x55d76bb8] (libcorkscrew.so)
#01 art::DumpNativeStack(std::ostream&, int, char const*, bool)+79 [0x55924fcf] (libartd.so)
#02 art::HandleUnexpectedSignal(int, siginfo*, void*)+1431814659 [0x5597cc23] (libartd.so)
#03 __kernel_rt_sigreturn [0x55573410] ([vdso])
#04 art::Runtime::Abort()+600 [0x558e2e98] (libartd.so)
#05 art::LogMessage::~LogMessage()+1052 [0x5580c16c] (libartd.so)
#06 art::EnsureResolved(art::Class*)+336 [0x5570dad0] (libartd.so)
#07 art::ClassLinker::FindClass(char const*, art::ClassLoader const*)+144 [0x5571bc90] (libartd.so)
#08 art::ClassLinker::FindSystemClass(char const*)+43 [0x5572287b] (libartd.so)
#09 art::ClassLinker::FinishInit()+82 [0x557228d2] (libartd.so)
#10 art::ClassLinker::InitFromImage()+1469 [0x5572451d] (libartd.so)
#11 art::ClassLinker::CreateFromImage(art::InternTable*)+60 [0x5572583c] (libartd.so)
#12 art::Runtime::Init(std::vector<std::pair<std::string, void const*>, std::allocator<std::pair<std::string, void const*> > > const&, bool)+943 [0x558e882f] (libartd.so)
#13 art::Runtime::Create(std::vector<std::pair<std::string, void const*>, std::allocator<std::pair<std::string, void const*> > > const&, bool)+119 [0x558e9057] (libartd.so)
#14 art::Dex2Oat::CreateRuntime(std::vector<std::pair<std::string, void const*>, std::allocator<std::pair<std::string, void const*> > >&, art::InstructionSet)+42 [0x80ac68a] (dex2oatd)
#15 art::Dex2Oat::Create(std::vector<std::pair<std::string, void const*>, std::allocator<std::pair<std::string, void const*> > >&, art::InstructionSet, unsigned int, bool)+60 [0x80ac87c] (dex2oatd)
#16 art::dex2oat(int, char**)+3167 [0x80894cf] (dex2oatd)
#17 main+17 [0x8086a01] (dex2oatd)
#18 __libc_start_main+230 [0x55c12bd6] (libc-2.11.1.so)
Example x86 SIGQUIT dump (note the three stacks, and note the absence of all
the crap that makes dalvik's attempt so unreadable):
"Thread-10" prio=5 tid=11 VmWait
| group="main" sCount=1 dsCount=0 obj=0x612d6620 self=0x884f8f0
| sysTid=30512 nice=0 sched=0/0 cgrp=default handle=1458686832
| schedstat=( 1249502 8995 26 ) utm=0 stm=0 core=14 HZ=100
| stackSize=1044KB stack=0x57905000-0x57906000
kernel: futex_wait_queue_me+0xcd/0x110
kernel: futex_wait+0x1e5/0x310
kernel: do_futex+0x101/0xb00
kernel: compat_sys_futex+0x75/0x160
kernel: sysenter_dispatch+0x7/0x2e
native: __kernel_vsyscall+14 [0x5557342e] ([vdso])
native: pthread_mutex_lock+54 [0x55cd8bf6] (libc-2.11.1.so)
native: art::Mutex::Lock()+86 [0x55823a86] (libartd.so)
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:75)
at java.lang.StringBuilder.<init>(StringBuilder.java:54)
at java.lang.Thread.create(Thread.java:427)
at java.lang.Thread.<init>(Thread.java:223)
at ThreadStress$1.run(ThreadStress.java:134)
Change-Id: Id263e51a167bcfc623634f910e9d138a1f472db7
diff --git a/src/thread_android.cc b/src/thread_android.cc
index 4d982b1..f86d0f4 100644
--- a/src/thread_android.cc
+++ b/src/thread_android.cc
@@ -21,7 +21,6 @@
#include <limits.h>
#include <errno.h>
-#include <corkscrew/backtrace.h>
#include <cutils/sched_policy.h>
#include <utils/threads.h>
@@ -29,23 +28,22 @@
namespace art {
-/*
- * Conversion map for "nice" values.
- *
- * We use Android thread priority constants to be consistent with the rest
- * of the system. In some cases adjacent entries may overlap.
- */
+// Conversion map for "nice" values.
+//
+// We use Android thread priority constants to be consistent with the rest
+// of the system. In some cases adjacent entries may overlap.
+//
static const int kNiceValues[10] = {
- ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
+ ANDROID_PRIORITY_LOWEST, // 1 (MIN_PRIORITY)
ANDROID_PRIORITY_BACKGROUND + 6,
ANDROID_PRIORITY_BACKGROUND + 3,
ANDROID_PRIORITY_BACKGROUND,
- ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
+ ANDROID_PRIORITY_NORMAL, // 5 (NORM_PRIORITY)
ANDROID_PRIORITY_NORMAL - 2,
ANDROID_PRIORITY_NORMAL - 4,
ANDROID_PRIORITY_URGENT_DISPLAY + 3,
ANDROID_PRIORITY_URGENT_DISPLAY + 2,
- ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
+ ANDROID_PRIORITY_URGENT_DISPLAY // 10 (MAX_PRIORITY)
};
void Thread::SetNativePriority(int newPriority) {
@@ -89,29 +87,4 @@
return managed_priority;
}
-void Thread::DumpNativeStack(std::ostream& os) const {
- const size_t MAX_DEPTH = 32;
- UniquePtr<backtrace_frame_t[]> backtrace(new backtrace_frame_t[MAX_DEPTH]);
- ssize_t frame_count = unwind_backtrace_thread(GetTid(), backtrace.get(), 0, MAX_DEPTH);
- if (frame_count == -1) {
- os << " (unwind_backtrace_thread failed for thread " << GetTid() << ".)";
- return;
- } else if (frame_count == 0) {
- os << " (no native stack frames)";
- return;
- }
-
- UniquePtr<backtrace_symbol_t[]> backtrace_symbols(new backtrace_symbol_t[frame_count]);
- get_backtrace_symbols(backtrace.get(), frame_count, backtrace_symbols.get());
-
- for (size_t i = 0; i < static_cast<size_t>(frame_count); ++i) {
- char line[MAX_BACKTRACE_LINE_LENGTH];
- format_backtrace_line(i, &backtrace[i], &backtrace_symbols[i],
- line, MAX_BACKTRACE_LINE_LENGTH);
- os << " " << line << "\n";
- }
-
- free_backtrace_symbols(backtrace_symbols.get(), frame_count);
-}
-
} // namespace art