summaryrefslogtreecommitdiff
path: root/runtime/native/dalvik_system_VMStack.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2017-01-12 14:51:44 -0800
committerMathieu Chartier <mathieuc@google.com>2017-01-12 15:15:51 -0800
commit4201cf014cfe00c145edc0b32bf30b1ceaf1495f (patch)
tree086c5df83832b6d80864a294503b6dc6025f270c /runtime/native/dalvik_system_VMStack.cc
parent9e68f5043323eaf4543ebf3b6f496145d8ae77a2 (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.cc12
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();