diff options
author | Mathieu Chartier <mathieuc@google.com> | 2017-01-12 14:51:44 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2017-01-12 15:15:51 -0800 |
commit | 4201cf014cfe00c145edc0b32bf30b1ceaf1495f (patch) | |
tree | 086c5df83832b6d80864a294503b6dc6025f270c /runtime/native/dalvik_system_VMStack.cc | |
parent | 9e68f5043323eaf4543ebf3b6f496145d8ae77a2 (diff) |
Avoid suspending heap task thread for getting stack traces
Instead of suspending the heap task thread, GetThreadStack (called by
VMStack_fillStackTraceElements and VMStack_getThreadStackTrace) will
return an empty thread stack. This fixes possible deadlocks caused by
suspending the GC thread and doing allocations for the stack trace.
Bug: 28261069
Test: test-art-host
Change-Id: I45a0b8ac94a99d6bbcfcdc2b41afadf941ec0138
Diffstat (limited to 'runtime/native/dalvik_system_VMStack.cc')
-rw-r--r-- | runtime/native/dalvik_system_VMStack.cc | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc index 36825cb870..268d71ac65 100644 --- a/runtime/native/dalvik_system_VMStack.cc +++ b/runtime/native/dalvik_system_VMStack.cc @@ -17,6 +17,7 @@ #include "dalvik_system_VMStack.h" #include "art_method-inl.h" +#include "gc/task_processor.h" #include "jni_internal.h" #include "nth_caller_visitor.h" #include "mirror/class-inl.h" @@ -31,9 +32,18 @@ namespace art { static jobject GetThreadStack(const ScopedFastNativeObjectAccess& soa, jobject peer) REQUIRES_SHARED(Locks::mutator_lock_) { jobject trace = nullptr; - if (soa.Decode<mirror::Object>(peer) == soa.Self()->GetPeer()) { + ObjPtr<mirror::Object> decoded_peer = soa.Decode<mirror::Object>(peer); + if (decoded_peer == soa.Self()->GetPeer()) { trace = soa.Self()->CreateInternalStackTrace<false>(soa); } else { + // Never allow suspending the heap task thread since it may deadlock if allocations are + // required for the stack trace. + Thread* heap_task_thread = + Runtime::Current()->GetHeap()->GetTaskProcessor()->GetRunningThread(); + // heap_task_thread could be null if the daemons aren't yet started. + if (heap_task_thread != nullptr && decoded_peer == heap_task_thread->GetPeer()) { + return nullptr; + } // Suspend thread to build stack trace. ScopedThreadSuspension sts(soa.Self(), kNative); ThreadList* thread_list = Runtime::Current()->GetThreadList(); |