libcorkscrew native stacks, mutex ranking, and better ScopedThreadListLock.
This change uses libcorkscrew to show native stacks for threads in kNative or,
unlike dalvikvm, kVmWait --- working on the runtime directly I've found it
somewhat useful to be able to see _which_ internal resource we're waiting on.
We can always take that back out (or make it oatexecd-only) if it turns out to
be too noisy/confusing for app developers.
This change also lets us rank mutexes and enforce -- in oatexecd -- that you
take locks in a specific order.
Both of these helped me test the third novelty: removing the heap locking from
ScopedThreadListLock. I've manually inspected all the callers and added a
ScopedHeapLock where I think one is necessary. In manual testing, this makes
jdb a lot less prone to locking us up. There still seems to be a problem with
the JDWP VirtualMachine.Resume command, but I'll look at that separately. This
is a big enough and potentially disruptive enough change already.
Change-Id: Iad974358919d0e00674662dc8a69cc65878cfb5c
diff --git a/src/thread_android.cc b/src/thread_android.cc
index 295a509..6f80333 100644
--- a/src/thread_android.cc
+++ b/src/thread_android.cc
@@ -21,6 +21,7 @@
#include <limits.h>
#include <errno.h>
+#include <corkscrew/backtrace.h>
#include <cutils/sched_policy.h>
#include <utils/threads.h>
@@ -88,4 +89,28 @@
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) {
+ 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