thread_list::dump()
说道JDWP,我简单对其说明下,说明是JDWP呢,JDWP的全写是:Java Debug Wire Protocol:即JAVA调试器无线协议,它定义了调试器(Debugger)和被调试的JAVA虚拟机(target vm)之间的通信协议,在这里,我更要说明下:Debugger与Target vm,Target vm 中运行着我们希望要调试的程序,它与一般运行的 Java 虚拟机没有什么区别,只是在启动时加载了 Agent JDWP 从而具备了调试功能。而 debugger 就是我们熟知的调试器,它向运行中的 target vm 发送命令来获取 target vm 运行时的状态和控制 Java 程序的执行。Debugger 和 target vm 分别在各自的进程中运行,他们之间的通信协议就是 JDWP。JDWP 与其他许多协议不同,它仅仅定义了数据传输的格式,但并没有指定具体的传输方式。这就意味着一个 JDWP 的实现可以不需要做任何修改就正常工作在不同的传输方式上(在 JDWP 传输接口中会做详细介绍)。JDWP 是语言无关的。理论上我们可以选用任意语言实现 JDWP。然而我们注意到,在 JDWP 的两端分别是 target vm 和 debugger。Target vm 端,JDWP 模块必须以 Agent library 的形式在 Java 虚拟机启动时加载,并且它必须通过 Java 虚拟机提供的 JVMTI 接口实现各种 debug 的功能,所以必须使用 C/C++ 语言编写。而 debugger 端就没有这样的限制,可以使用任意语言编写,只要遵守 JDWP 规范即可。
// timeout 后会调用UnsafeLogFatalForThreadSuspendAllTimeout() NO_RETURN static void UnsafeLogFatalForThreadSuspendAllTimeout() { Runtime* runtime = Runtime::Current(); std::ostringstream ss; ss << "Thread suspend timeout\n"; Locks::mutator_lock_->Dump(ss); ss << "\n"; runtime->GetThreadList()->Dump(ss); LOG(FATAL) << ss.str(); exit(0); } void Mutex::Dump(std::ostream& os) const { os << (recursive_ ? "recursive " : "non-recursive ") << name_ << " level=" << static_cast<int>(level_) << " rec=" << recursion_count_ << " owner=" << GetExclusiveOwnerTid() << " "; DumpContention(os); } void ThreadList::Dump(std::ostream& os) { std::ostringstream local_os; { MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); local_os << "DALVIK THREADS (" << list_.size() << "):\n"; } DumpCheckpoint checkpoint(&local_os); // caoming threads_running_checkpoint : the count of threads these who suspend by themself size_t threads_running_checkpoint = RunCheckpoint(&checkpoint); if (threads_running_checkpoint != 0) { bool time_out = checkpoint.WaitForThreadsToRunThroughCheckpoint(threads_running_checkpoint); if (time_out) { LOG(ERROR) << local_os.str(); } } os << local_os.str(); } class DumpCheckpoint FINAL : public Closure { public: explicit DumpCheckpoint(std::ostream* os) : os_(os), barrier_(0) {} void Run(Thread* thread) OVERRIDE { // Note thread and self may not be equal if thread was already suspended at the point of the // request. Thread* self = Thread::Current(); std::ostringstream local_os; { ScopedObjectAccess soa(self); thread->Dump(local_os); } local_os << "\n"; { // Use the logging lock to ensure serialization when writing to the common ostream. MutexLock mu(self, *Locks::logging_lock_); *os_ << local_os.str(); } if (thread->GetState() == kRunnable) { // caoming barrier_ is for these threads who dump themselves barrier_.Pass(self); } } bool WaitForThreadsToRunThroughCheckpoint(size_t threads_running_checkpoint) { Thread* self = Thread::Current(); ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun); // kDumpWaitTimeout = 10s bool timed_out = barrier_.Increment(self, threads_running_checkpoint, kDumpWaitTimeout); if (timed_out) { // Avoid a recursive abort. LOG((kIsDebugBuild && (gAborting == 0)) ? FATAL : ERROR) << "Unexpected time out during dump checkpoint."; } return timed_out; } private: // The common stream that will accumulate all the dumps. std::ostream* const os_; // The barrier to be passed through and for the requestor to wait upon. Barrier barrier_; };
F art : art/runtime/thread_list.cc:241] Thread suspend timeout // Locks::mutator_lock_->Dump(ss); dump mutator锁 // level代表一个级别的锁,一般一个级别就一个锁,这里是mutator锁 // AtomicInteger state_; -1 implies held exclusive, +ve shared held by state_ many owners. // volatile uint64_t exclusive_owner_;独占时的线程id号,考虑到state_ = 1也就是说被一个线程共享占有,所以这里owner没有任何意义 // num_pending_writers 等待独占的线程数 // num_pending_readers 等待共享占有的线程数 F art : art/runtime/thread_list.cc:241] mutator lock level=54 owner=18446744073709551615 state=1 num_pending_writers=0 num_pending_readers=0 F art : art/runtime/thread_list.cc:241] DALVIK THREADS (28): // 这里表示一个有28个线程 // 看样子先dump是当前的线程 F art : art/runtime/thread_list.cc:241] "HeapTaskDaemon" daemon prio=5 tid=7 Runnable F art : art/runtime/thread_list.cc:241] | group="system" sCount=0 dsCount=0 obj=0x22c07280 self=0xab806cd0 F art : art/runtime/thread_list.cc:241] | sysTid=24676 nice=0 cgrp=bg_non_interactive sched=0/0 handle=0xe1e39930 F art : art/runtime/thread_list.cc:241] | state=R schedstat=( 0 0 0 ) utm=72 stm=10 core=4 HZ=100 F art : art/runtime/thread_list.cc:241] | stack=0xe1d37000-0xe1d39000 stackSize=1038KB F art : art/runtime/thread_list.cc:241] | held mutexes= "mutator lock"(shared held) F art : art/runtime/thread_list.cc:241] native: #00 pc 0035fdad /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*)+116) F art : art/runtime/thread_list.cc:241] native: #01 pc 003407b1 /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, BacktraceMap*) const+152) F art : art/runtime/thread_list.cc:241] native: #02 pc 0034a25b /system/lib/libart.so (art::DumpCheckpoint::Run(art::Thread*)+426) F art : art/runtime/thread_list.cc:241] native: #03 pc 0034adb5 /system/lib/libart.so (art::ThreadList::RunCheckpoint(art::Closure*)+192) F art : art/runtime/thread_list.cc:241] native: #04 pc 0034b303 /system/lib/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+138) F art : art/runtime/thread_list.cc:241] native: #05 pc 0034c303 /system/lib/libart.so (art::UnsafeLogFatalForThreadSuspendAllTimeout()+218) F art : art/runtime/thread_list.cc:241] native: #06 pc 0034cbd1 /system/lib/libart.so (art::ThreadList::SuspendAll(char const*, bool)+2120) F art : art/runtime/thread_list.cc:241] native: #07 pc 00190bef /system/lib/libart.so (art::gc::collector::GarbageCollector::ScopedPause::ScopedPause(art::gc::collector::GarbageCollector*)+34) F art : art/runtime/thread_list.cc:241] native: #08 pc 0019be41 /system/lib/libart.so (art::gc::collector::MarkSweep::RunPhases()+652) F art : art/runtime/thread_list.cc:241] native: #09 pc 00191aed /system/lib/libart.so (art::gc::collector::GarbageCollector::Run(art::gc::GcCause, bool)+276) F art : art/runtime/thread_list.cc:241] native: #10 pc 001afe49 /system/lib/libart.so (art::gc::Heap::CollectGarbageInternal(art::gc::collector::GcType, art::gc::GcCause, bool)+1480) F art : art/runtime/thread_list.cc:241] native: #11 pc 001b0e2d /system/lib/libart.so (art::gc::Heap::ConcurrentGCTask::Run(art::Thread*)+84) F art : art/runtime/thread_list.cc:241] native: #12 pc 001d1021 /system/lib/libart.so (art::gc::TaskProcessor::RunAllTasks(art::Thread*)+40) F art : art/runtime/thread_list.cc:241] native: #13 pc 00000377 /system/framework/arm/boot.oat (Java_dalvik_system_VMRuntime_runHeapTasks__+74) F art : art/runtime/thread_list.cc:241] at dalvik.system.VMRuntime.runHeapTasks(Native method) F art : art/runtime/thread_list.cc:241] at java.lang.Daemons$HeapTaskDaemon.run(Daemons.java:418) F art : art/runtime/thread_list.cc:241] at java.lang.Thread.run(Thread.java:818) F art : art/runtime/thread_list.cc:241] F art : art/runtime/thread_list.cc:241] "main" prio=5 tid=1 Native F art : art/runtime/thread_list.cc:241] | group="main" sCount=2 dsCount=0 obj=0x752bfe10 self=0xab57b500 F art : art/runtime/thread_list.cc:241] | sysTid=24666 nice=0 cgrp=default sched=0/0 handle=0xf72c8b5c F art : art/runtime/thread_list.cc:241] | state=S schedstat=( 0 0 0 ) utm=112 stm=47 core=4 HZ=100 F art : art/runtime/thread_list.cc:241] | stack=0xff44e000-0xff450000 stackSize=8MB F art : art/runtime/thread_list.cc:241] | held mutexes= F art : art/runtime/thread_list.cc:241] kernel: __switch_to+0x90/0x9c F art : art/runtime/thread_list.cc:241] kernel: futex_wait_queue_me+0xd4/0x12c F art : art/runtime/thread_list.cc:241] kernel: futex_wait+0xe0/0x1d4 F art : art/runtime/thread_list.cc:241] kernel: do_futex+0xc8/0x8d4 F art : art/runtime/thread_list.cc:241] kernel: compat_SyS_futex+0xd0/0x14c F art : art/runtime/thread_list.cc:241] kernel: cpu_switch_to+0x48/0x4c F art : art/runtime/thread_list.cc:241] native: #00 pc 00016994 /system/lib/libc.so (syscall+28) F art : art/runtime/thread_list.cc:241] native: #01 pc 000f6483 /system/lib/libart.so (art::ConditionVariable::Wait(art::Thread*)+82) F art : art/runtime/thread_list.cc:241] native: #02 pc 002916d7 /system/lib/libart.so (art::JNI::NewObjectV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+1426) F art : art/runtime/thread_list.cc:241] native: #03 pc 0000ffe5 /system/lib/libjavacore.so (???) F art : art/runtime/thread_list.cc:241] native: #04 pc 0001e957 /system/lib/libjavacore.so (???) F art : art/runtime/thread_list.cc:241] native: #05 pc 000200fd /system/lib/libjavacore.so (???) F art : art/runtime/thread_list.cc:241] native: #06 pc 0024e97d /system/framework/arm/boot.oat (Java_libcore_io_Posix_fstat__Ljava_io_FileDescriptor_2+96) F art : art/runtime/thread_list.cc:241] at libcore.io.Posix.fstat(Native method) F art : art/runtime/thread_list.cc:241] at libcore.io.BlockGuardOs.fstat(BlockGuardOs.java:133) F art : art/runtime/thread_list.cc:241] at libcore.io.IoBridge.open(IoBridge.java:441) F art : art/runtime/thread_list.cc:241] at java.io.FileOutputStream.<init>(FileOutputStream.java:87) F art : art/runtime/thread_list.cc:241] at java.io.FileOutputStream.<init>(FileOutputStream.java:127) F art : art/runtime/thread_list.cc:241] at com.gracenote.mmid.MobileSDK.s.a(GNUtil.java:122) F art : art/runtime/thread_list.cc:241] at com.gracenote.mmid.MobileSDK.GNConfig.appendToDebugLog(GNConfig.java:1028) F art : art/runtime/thread_list.cc:241] - locked <0x045aedc4> (a com.gracenote.mmid.MobileSDK.GNConfig) F art : art/runtime/thread_list.cc:241] at com.gracenote.mmid.MobileSDK.GNOperations$GNOperationAlbumIdFile.onPostExecute(GNOperations.java:1123) F art : art/runtime/thread_list.cc:241] at com.gracenote.mmid.MobileSDK.GNOperations$GNOperationAlbumIdFile.onPostExecute(GNOperations.java:1037) F art : art/runtime/thread_list.cc:241] at android.os.AsyncTask.finish(AsyncTask.java:651) F art : art/runtime/thread_list.cc:241] at android.os.AsyncTask.access$500(AsyncTask.java:180) F art : art/runtime/thread_list.cc:241] at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668) F art : art/runtime/thread_list.cc:241] at android.os.Handler.dispatchMessage(Handler.java:102) F art : art/runtime/thread_list.cc:241] at android.os.Looper.loop(Looper.java:168) F art : art/runtime/thread_list.cc:241] at android.app.ActivityThread.main(ActivityThread.java:5885) F art : art/runtime/thread_list.cc:241] at java.lang.reflect.Method.invoke!(Native method) F art : art/runtime/thread_list.cc:241] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) F art : art/runtime/thread_list.cc:241] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) F art : art/runtime/thread_list.cc:241] F art : art/runtime/thread_list.cc:241] "Signal Catcher" daemon prio=5 tid=2 Native F art : art/runtime/thread_list.cc:241] | group="system" sCount=2 dsCount=0 obj=0x22c070a0 self=0xab805b28 F art : art/runtime/thread_list.cc:241] | sysTid=24671 nice=0 cgrp=default sched=0/0 handle=0xf484f930 F art : art/runtime/thread_list.cc:241] | state=S schedstat=( 0 0 0 ) utm=7 stm=4 core=2 HZ=100 F art : art/runtime/thread_list.cc:241] | stack=0xf4753000-0xf4755000 stackSize=1014KB F art : art/runtime/thread_list.cc:241] | held mutexes= F art : art/runtime/thread_list.cc:241] kernel: __switch_to+0x90/0x9c F art : art/runtime/thread_list.cc:241] kernel: futex_wait_queue_me+0xd4/0x12c F art : art/runtime/thread_list.cc:241] kernel: futex_wait+0xe0/0x1d4 F art : art/runtime/thread_list.cc:241] kernel: do_futex+0xc8/0x8d4 F art : art/runtime/thread_list.cc:241] kernel: compat_SyS_futex+0xd0/0x14c F art : art/runtime/thread_list.cc:241] kernel: cpu_switch_to+0x48/0x4c F art : art/runtime/thread_list.cc:241] native: #00 pc 00016994 /system/lib/libc.so (syscall+28) F art : art/runtime/thread_list.cc:241] native: #01 pc 000f6483 /system/lib/libart.so (art::ConditionVariable::Wait(art::Thread*)+82) F art : art/runtime/thread_list.cc:241] native: #02 pc 0034c1a5 /system/lib/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+2252) F art : art/runtime/thread_list.cc:241] native: #03 pc 00324781 /system/lib/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+68) F art : art/runtime/thread_list.cc:241] native: #04 pc 0032be5f /system/lib/libart.so (art::SignalCatcher::HandleSigQuit()+910) F art : art/runtime/thread_list.cc:241] native: #05 pc 0032c72d /system/lib/libart.so (art::SignalCatcher::Run(void*)+324) F art : art/runtime/thread_list.cc:241] native: #06 pc 00042413 /system/lib/libc.so (__pthread_start(void*)+30) F art : art/runtime/thread_list.cc:241] native: #07 pc 00019335 /system/lib/libc.so (__start_thread+6) F art : art/runtime/thread_list.cc:241] (no managed stack frames) F art : art/runtime/thread_list.cc:241] F art : art/runtime/thread_list.cc:241] "JDWP" daemon prio=5 tid=3 WaitingInMainDebuggerLoop F art : art/runtime/thread_list.cc:241] | group="system" sCount=2 dsCount=0 obj=0x22c07100 self=0xab8065d8 F art : art/runtime/thread_list.cc:241] | sysTid=24672 nice=0 cgrp=default sched=0/0 handle=0xf474b930 F art : art/runtime/thread_list.cc:241] | state=S schedstat=( 0 0 0 ) utm=0 stm=0 core=4 HZ=100 F art : art/runtime/thread_list.cc:241] | stack=0xf464f000-0xf4651000 stackSize=1014KB F art : art/runtime/thread_list.cc:241] | held mutexes= F art : art/runtime/thread_list.cc:241] kernel: __switch_to+0x90/0x9c F art : art/runtime/thread_list.cc:241] kernel: unix_stream_recvmsg+0x244/0x67c F art : art/runtime/thread_list.cc:241] kernel: sock_recvmsg+0xa0/0xc8 F art : art/runtime/thread_list.cc:241] kernel: ___sys_recvmsg+0x124/0x1f4 F art : art/runtime/thread_list.cc:241] kernel: __sys_recvmsg+0x3c/0x64 F art : art/runtime/thread_list.cc:241] kernel: compat_sys_recvmsg+0x14/0x28 F art : art/runtime/thread_list.cc:241] kernel: cpu_switch_to+0x48/0x4c F art : art/runtime/thread_list.cc:241] native: #00 pc 00044908 /system/lib/libc.so (recvmsg+8) F art : art/runtime/thread_list.cc:241] native: #01 pc 003ed729 /system/lib/libart.so (art::JDWP::JdwpAdbState::ReceiveClientFd()+80) F art : art/runtime/thread_list.cc:241] native: #02 pc 003edead /system/lib/libart.so (art::JDWP::JdwpAdbState::Accept()+92) F art : art/runtime/thread_list.cc:241] native: #03 pc 0025e2a7 /system/lib/libart.so (art::JDWP::JdwpState::Run()+222) F art : art/runtime/thread_list.cc:241] native: #04 pc 0025f15f /system/lib/libart.so (art::JDWP::StartJdwpThread(void*)+10) F art : art/runtime/thread_list.cc:241] native: #05 pc 00042413 /system/lib/libc.so (__pthread_start(void*)+30) F art : art/runtime/thread_list.cc:241] native: #06 pc 00019335 /system/lib/libc.so (__start_thread+6) F art : art/runtime/thread_list.cc:241] (no managed stack frames) F art : art/runtime/thread_list.cc:241] F art : art/runtime/thread_list.cc:241] "ReferenceQueueDaemon" daemon prio=5 tid=4 Waiting F art : art/runtime/thread_list.cc:241] | group="system" sCount=2 dsCount=0 obj=0x22c07160 self=0xab7859e8 F art : art/runtime/thread_list.cc:241] | sysTid=24673 nice=0 cgrp=default sched=0/0 handle=0xf4645930 F art : art/runtime/thread_list.cc:241] | state=S schedstat=( 0 0 0 ) utm=0 stm=1 core=4 HZ=100 F art : art/runtime/thread_list.cc:241] | stack=0xf4543000-0xf4545000 stackSize=1038KB F art : art/runtime/thread_list.cc:241] | held mutexes= F art : art/runtime/thread_list.cc:241] at java.lang.Object.wait!(Native method) F art : art/runtime/thread_list.cc:241] - waiting on <0x0f34ed64> (a java.lang.Class<java.lang.ref.ReferenceQueue>) F art : art/runtime/thread_list.cc:241] at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:155) F art : art/runtime/thread_list.cc:241] - locked <0x0f34ed64> (a java.lang.Class<java.lang.ref.ReferenceQueue>) F art : art/runtime/thread_list.cc:241] at java.lang.Thread.run(Thread.java:818) F art : art/runtime/thread_list.cc:241] F art : art/runtime/thread_list.cc:241] "FinalizerDaemon" daemon prio=5 tid=5 Waiting F art : art/runtime/thread_list.cc:241] | group="system" sCount=2 dsCount=0 obj=0x22c071c0 self=0xab6a53f8 F art : art/runtime/thread_list.cc:241] | sysTid=24674 nice=0 cgrp=default sched=0/0 handle=0xf453e930 F art : art/runtime/thread_list.cc:241] | state=S schedstat=( 0 0 0 ) utm=2 stm=2 core=4 HZ=100 F art : art/runtime/thread_list.cc:241] | stack=0xf443c000-0xf443e000 stackSize=1038KB F art : art/runtime/thread_list.cc:241] | held mutexes= F art : art/runtime/thread_list.cc:241] at java.lang.Object.wait!(Native method) F art : art/runtime/thread_list.cc:241] - waiting on <0x0935bbcd> (a java.lang.ref.ReferenceQueue) F art : art/runtime/thread_list.cc:241] at java.lang.Object.wait(Object.java:423) F art : art/runtime/thread_list.cc:241] at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:101) F art : art/runtime/thread_list.cc:241] - locked <0x0935bbcd> (a java.lang.ref.ReferenceQueue) F art : art/runtime/thread_list.cc:241] at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:72) F art : art/runtime/thread_list.cc:241] at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:193) F art : art/runtime/thread_list.cc:241] at java.lang.Thread.run(Thread.java:818)
                    
                
                
            
        
浙公网安备 33010602011771号