UIWDT 是一种软件实现的看门狗机制,检测一些关键的系统进程是否发生了死锁, ServerThread线程会定期的锁一下系统关键的服务来查看是否发生了死锁,如果发生了死锁,从log中可以查看ServerThread的调用链,有两种可能的情况会产生UIWDT, 一种是ServerThread线程 本身被阻塞了: 如下的log说明该线程正在进行binder通信的返回结果,因此这里需要知道该系统线程正在和哪一个进程进行通信,因此把binder的通信信息保存起来有助于bug的分析。
"android.server.ServerThread" prio=5 tid=16 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x42502f30 self=0x5d7e0a40
| sysTid=29054 nice=-2 sched=0/0 cgrp=apps handle=1577166064
| schedstat=( 37692921905 5310293045 64784 ) utm=2779 stm=990 core=1
#00 pc 00019e84 /system/lib/libc.so
#01 pc 00020861 /system/lib/libbinder.so
#02 pc 000210eb /system/lib/libbinder.so
#03 pc 0001788a /system/lib/libbinder.so
#04 pc 0004cb0a /system/lib/libmedia.so
#05 pc 000582c8 /system/lib/libmedia.so
#06 pc 000caa1b /system/lib/libandroid_runtime.so
#07 pc 0002a540 /system/lib/libdvm.so
#08 pc 0007f158 /system/lib/libdvm.so
#09 pc 00159e31 /system/lib/libdvm.so
#10 pc 00039216 /system/lib/libdvm.so
#11 pc 000369a4 /system/lib/libdvm.so
#12 pc 000ae57c /system/lib/libdvm.so
#13 pc 000aea16 /system/lib/libdvm.so
#14 pc 00091506 /system/lib/libdvm.so
#15 pc 0000dce8 /system/lib/libc.so
#16 pc 0001b70d /system/lib/libc.so
#17 pc 0002c95d /system/lib/libdvm.so
at android.media.AudioSystem.setParameters(Native Method)
at android.media.AudioService$AudioServiceBroadcastReceiver.onReceive(AudioService.java:3611)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:755)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at com.android.server.ServerThread.run(SystemServer.java:904)
binder info:proc 29016
thread 29054: l 10
outgoing transaction 2190776: e080b6c0 from 29016:29054 to 28858:31640 code 14 flags 10 pri -2 r1 node 638678 size 92:0 data fe1002d0
从上面的log 可以看出该线程正在和进程28858中的线程号为31640进行通信,也就是等待该binder服务线程的返回结果,在查看该线程的调用链信息:
"Binder_5" sysTid=31640
#00 pc 0001b7ed /system/lib/libc.so
#01 pc 00054e3b /system/lib/libaudioflinger.so (_ZN7android12AudioFlinger13setParametersEiRKNS_7String8E.part.116+43)
#02 pc 00055342 /system/lib/libaudioflinger.so (android::AudioFlinger::setParameters(int, android::String8 const&)+338)
#03 pc 0004f7ea /system/lib/libmedia.so (android::BnAudioFlinger::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+3178)
#04 pc 00032fca /system/lib/libaudioflinger.so (android::AudioFlinger::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+58)
#05 pc 00016cee /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+94)
#06 pc 0002046d /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+957)
#07 pc 00021370 /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+528)
#08 pc 0002e860 /system/lib/libbinder.so (android::PoolThread::threadLoop()+48)
#09 pc 0001a2bc /system/lib/libutils.so (android::Thread::_threadLoop(void*)+556)
#10 pc 00019f5c /system/lib/libutils.so (thread_data_t::trampoline(thread_data_t const*)+268)
#11 pc 0000dce8 /system/lib/libc.so (__thread_entry+248)
#12 pc 0001b70d /system/lib/libc.so
#13 pc 0002b203 /system/lib/libbinder.so (android::Parcel::writeObject(android::flat_binder_object const&, bool)+339)
该线程阻塞在setParameter函数中,然后在检查该线程正在等待哪个锁,根据log仔细检查用户空间可能的死锁。。。这是一种伪的UIWDT,是由于监视线程本身发生了问题导致的。
另一种UIWDT是真正的 bug, 由于系统关键的服务间发生了死锁,此时从log中可以看出产生死锁的两个或多个问题线程。