Include held locks in SIGQUIT thread dumps.
Handy if you have an ANR that's locking related. Quick tour:
at org.apache.harmony.dalvik.NativeTestTarget.emptyJniStaticSynchronizedMethod0(Native method)
- locked <0x60135aa8> (a java.lang.Class<org.apache.harmony.dalvik.NativeTestTarget>)
at java.lang.reflect.Method.invoke(Native method)
at C.whileTrue(Main.java:63)
at C.synchronizedOnClassString(Main.java:56)
- locked <0x60002a70> (a java.lang.Class<java.lang.String>)
at C.nestedSynchronizationWithTryCatch(Main.java:44)
- locked <0x61336b90> (a java.lang.String)
- locked <0x61336bd0> (a java.lang.String)
at C.nestedSynchronization(Main.java:35)
- locked <0x61336b18> (a java.lang.String)
- locked <0x61336b50> (a java.lang.String)
at C.synchronizedOnClassC(Main.java:30)
- locked <0x613366f8> (a java.lang.Class<C>)
at C.noLocks(Main.java:27)
at C.<clinit>(Main.java:24)
- locked <0x613366f8> (a java.lang.Class<C>)
at Main.main(Main.java:19)
A non-static synchronized native method works too:
at org.apache.harmony.dalvik.NativeTestTarget.emptyJniSynchronizedMethod0(Native method)
- locked <0x613371a8> (a org.apache.harmony.dalvik.NativeTestTarget)
...
Note that most stack traces don't look any different; the above is a
pathological example that exercises different kinds of locking. Testing
with system_server shows most threads don't hold any locks.
Future work (marked by TODO) is that explicit JNI MonitorEnter calls in
native code aren't shown.
Change-Id: I2747f5cddb4ef64b1935736f084a68fe8e4005e9
diff --git a/src/nth_caller_visitor.h b/src/nth_caller_visitor.h
index db4d28c..0f29ae7 100644
--- a/src/nth_caller_visitor.h
+++ b/src/nth_caller_visitor.h
@@ -24,8 +24,9 @@
// Walks up the stack 'n' callers, when used with Thread::WalkStack.
struct NthCallerVisitor : public StackVisitor {
- NthCallerVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
- size_t n) : StackVisitor(stack, trace_stack), n(n), count(0), caller(NULL) {}
+ NthCallerVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack, size_t n)
+ : StackVisitor(stack, trace_stack, NULL), n(n), count(0), caller(NULL) {}
+
bool VisitFrame() {
DCHECK(caller == NULL);
if (count++ == n) {
@@ -34,6 +35,7 @@
}
return true;
}
+
size_t n;
size_t count;
Method* caller;