diff options
-rw-r--r-- | runtime/native/dalvik_system_VMStack.cc | 12 | ||||
-rw-r--r-- | test/129-ThreadGetId/expected.txt | 1 | ||||
-rw-r--r-- | test/129-ThreadGetId/src/Main.java | 14 |
3 files changed, 26 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(); diff --git a/test/129-ThreadGetId/expected.txt b/test/129-ThreadGetId/expected.txt index 134d8d0b47..aadf90d9d7 100644 --- a/test/129-ThreadGetId/expected.txt +++ b/test/129-ThreadGetId/expected.txt @@ -1 +1,2 @@ +HeapTaskDaemon depth 0 Finishing diff --git a/test/129-ThreadGetId/src/Main.java b/test/129-ThreadGetId/src/Main.java index 9934bba95f..5aefd17f0e 100644 --- a/test/129-ThreadGetId/src/Main.java +++ b/test/129-ThreadGetId/src/Main.java @@ -22,6 +22,7 @@ public class Main implements Runnable { public static void main(String[] args) throws Exception { final Thread[] threads = new Thread[numberOfThreads]; + test_getStackTraces(); for (int t = 0; t < threads.length; t++) { threads[t] = new Thread(new Main()); threads[t].start(); @@ -32,6 +33,19 @@ public class Main implements Runnable { System.out.println("Finishing"); } + static void test_getStackTraces() { + // Check all the current threads for positive IDs. + Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces(); + for (Map.Entry<Thread, StackTraceElement[]> pair : map.entrySet()) { + Thread thread = pair.getKey(); + // Expect empty stack trace since we do not support suspending the GC thread for + // obtaining stack traces. See b/28261069. + if (thread.getName().equals("HeapTaskDaemon")) { + System.out.println(thread.getName() + " depth " + pair.getValue().length); + } + } + } + public void test_getId() { if (Thread.currentThread().getId() <= 0) { System.out.println("current thread's ID is not positive"); |