如何快速对android 重启系统重启问题进行分析归类

3271人阅读
android(63)
From : /blog/jinlu7611/article/p-5005930.html
当手机长时间无法再被用户控制操作时,我们称为死机。在这里我们强调长时间,如果是短时间,归结为性能问题。
* 用户操作手机无任何响应,如触摸屏幕,按键操作等。
* 手机屏幕黑屏,无法点亮屏幕。
* 手机界面显示内容和用户输入不相干。
当用户对手机进行操作时,对应的数据流将是下面一个概括的流程图
* HW 如传感器,触摸屏(TP),物理按键(KP)等感知到用户操作后,触发相关的中断(ISR)传递给Kernel,Kernel相关的driver
对这些中断进行处理后,转化成标准的InputEvent。&
* UserSpace 的System Server中的Input System则持续监听Kernel传递上来的原始InputEvent,对其进行进一步的处理后,变成上层APP可直接处理的Input
Event,如button点击,长按,滑动等等。
* APP 对相关的事件进行处理后,请求更新相关的逻辑界面,而这个则由System Server中的WMS
等来负责。
* 相关的逻辑界面更新后,则会请求SurfaceFlinger来产生FrameBuffer数据,SurfaceFlinger则会利用GPU
等来计算生成。
* DisplaySystem/Driver 则会将FrameBuffer中的数据更新显示出来,这样用户才能感知到他的操作行为。
可能死机的原因
原则上上面流程中,每一步出现问题,都可能引发死机问题。大的方面讲,可以分成硬件HW和软件SW两个层次,硬件HW不在我们的范围之内。
软件SW上,死机的原因可以分成两种:
(1). 逻辑行为异常
&** 逻辑判断错误
&** 逻辑设计错误
&(2). 逻辑卡顿(block)
&* 死循环 (Deadloop)
&* 死锁 (Deadlock)
&从具体的原因上将,可以进一步分成:
(1). InputDriver
* 无法接收HW的中ISR,产生原始的InputEvent或者产生的InputEvent异常。
分析死机、触屏无响应的问题的时候,第一步要先看看有没有inputEvent上来,即有没有报点,各个平台inputEvent的设备节点都不一样,可以通过下面方法获取:
adb shellgetevent
这个命令下下去以后会在屏幕上输出当前设备的节点,可从name一行判断哪一个是TW,当然也可以在此时直接在屏幕上触摸看有没有时间上报,正常情况如下:
可以看出event2是触摸事件。
异常情况下触摸是没有事件上报的。
当然也可以直接下adb shell getevent&/dev/input/event2检查。
(2). InputSystem
&无法监听Kernel传递上来的原始InputEvent,或者转换与传递异常。
(3). SystemLogic
&无法正常响应InputSystem传递过来的InputEvent,或者响应出错。
(4).WMS/Surfaceflinger 行为异常
&WMS/ Surfaceflinger 无法正确的对Window进行叠加转换
(5).Display System
&无法更新Framebuffer数据,或者填充的数据错误
(6). LCMDriver
无法将Framebuffer数据显示在LCM上
&对应硬件HW异常,经常见得的情况有:
* Memory& Memory Controller
死机分析,同样需要获取第一手的资料,方可分析问题.那么哪些数据可以用来分析死机呢?
大概的讲,可以分成空间数据和时间数据。空间数据,即当时现场环境,如有哪些process在运行,CPU
的执行情况,memory
的利用情况,以及具体的process的memory
数据等。时间数据,即行为上的连续数据,比如某个Process在一段时间内执行了哪些操作,某段时间内CPU利用率的变化等。通常时空都是交融的,对应我们抓取log时往往也是。&
Backtrace 又分成Java backtrace,Native Backtrace,Kernel
Backtrace。它是分析死机的非常重要的手段,借助Backtrace,我们可以快速的知道,对应的process/thread在当时正在执行哪些动作,卡住哪里等。可以非常直观的分析死机现场。
1 Java Backtrace
从Java Backtrace,我们可以知道当时Process的虚拟机执行状态。
JavaBacktrace依靠SignalCatcher来抓取。
Googledefault: SignalCatcher catchs SIGQUIT(3), and thenprint the java backtrace to /data/anr/trace.txt
MTKEnhance:& SignalCatcher catchs SIGSTKFLT(16), and thenprint the java backtrace to /data/anr/mtktrace.txt( After 6577.SP/ICS2.MP)
可以通过修改系统属性dalvik.vm.stack-trace-file改变trace文件路径,&默认路径为/data/anr/traces.txt
<span style="color:#.1&&&&&&&抓取的方式
一般进程出现无响应的问题,Android系统会发送SIGQUIT(<span style="color:#)信号给该进程,收到这个信号会,进程会将当前的调用栈打印在trace.txt文件里。
手动抓取进程的Backtrace方法如下:
adb remount
adb shellchmod 0777 data/anr
adb shellkill -3 pid
adb pull/data/anr
&1.2JavaBacktrace 解析
下面是一小段system server的java backtrace的开始
----- pid 682 at
18:04:53 -----
Cmd line: system_server
JNI: CheckJNIpins=4; globals=1484 (plus 50 weak)
DALVIK THREADS:
&main& prio=5 tid=1 NATIVE
& | group=&main& sCount=1dsCount=0 obj=0x4193fde0 self=0x
& | sysTid=682 nice=-2 sched=0/0cgrp=apps handle=
& | state=S schedstat=(
44902 ) utm=4074 stm=711 core=0
& at android.os.MessageQueue.nativePollOnce(NativeMethod)
& at android.os.MessageQueue.next(MessageQueue.java:138)
& at android.os.Looper.loop(Looper.java:150)
& at com.android.server.ServerThread.initAndLoop(SystemServer.java:1468)
& at com.android.server.SystemServer.main(SystemServer.java:1563)
& at java.lang.reflect.Method.invokeNative(NativeMethod)
& at java.lang.reflect.Method.invoke(Method.java:515)
& at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
& at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
& at dalvik.system.NativeStart.main(NativeMethod)
&&我们一行一行来解析.
0#&最开始是 -----PID at Time& 然后接着 Cmd line: process name
1#& the backtrace header: dvm thread :“DALVIK THREADS:”
&2# thread name, java thread Priority, [daemon], DVM thread id, DVM thread status.
&&main&& -& mainthread -& activity thread
&prio& -& java threadpriority default is 5, (nice =0, linux thread priority 120),&domain is [1,10]
&DVMthread id, NOT linux thread id
&DVM thread Status:
&&ZOMBIE,& RUNNABLE, TIMED_WAIT, MONITOR, WAIT, INITALIZING,STARTING, NATIVE, VMWAIT, SUSPENDED,UNKNOWN
&&&main& prio=5 tid=1NATIVE
&3# DVM thread status&
&group: default is “main”
&&&Compiler,JDWP,Signal Catcher,GC,FinalizerWatchdogDaemon,FinalizerDaemon,ReferenceQueueDaemonare system group
&sCount:& thread suspend count
&dsCount: thread dbg suspend count
&obj:&&&& threadobj address
&Sef:& thread point address
&group=&main& sCount=1dsCount=0 obj=0x4193fde0 self=0x
#5 Linux thread status
&sysTId:& linux thread tid
&Nice: linux thread nice value
&sched: cgroup policy/gourp id
&cgrp:& c group &
&handle:& handle address
&sysTid=682 nice=-2 sched=0/0cgrp=apps handle=
&#6 CPU Schedstat
&Schedstat (Run CPU Clock/ns, Wait CPU Clock/ns,& Slice times)
&utm: utime, user space time(jiffies)
&stm: stime, kernel space time(jiffies)
&Core now running in cpu.
&state=S schedstat=(
44902 ) utm=4074 stm=711 core=0
&#7-more CallStack
<span style="color:#.3 几种常见的java backtrace
<span style="color:#.3.1ActivityThread 正常状态的Backtrace
MessageQueue is empty, and thread wait fornext message.
&&main& prio=5 tid=1 NATIVE
&& | group=&main&sCount=1 dsCount=0 obj=0x4193fde0 self=0x
&& | sysTid=11559 nice=0sched=0/0 cgrp=apps/bg_non_interactive handle=
&& | state=S schedstat=(
7975 ) utm=100 stm=139 core=1
&& at android.os.MessageQueue.nativePollOnce(NativeMethod)
&& at android.os.MessageQueue.next(MessageQueue.java:138)
&& at android.os.Looper.loop(Looper.java:150)
&& at android.app.ActivityThread.main(ActivityThread.java:5299)
&& at java.lang.reflect.Method.invokeNative(NativeMethod)
&& at java.lang.reflect.Method.invoke(Method.java:515)
&& at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
&& at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
&& at dalvik.system.NativeStart.main(NativeMethod)
<span style="color:#.3.2 JavaBacktrace Monitor case
SynchronizedLock:等待同步锁时的backtrace.
&&AnrMonitorThread& prio=5tid=24 MONITOR
&& | group=&main&sCount=1 dsCount=0 obj=0x41fd80c8 self=0x551ac808
&& | sysTid=711 nice=0 sched=0/0cgrp=apps handle=
&& | state=S schedstat=(
6892 ) utm=160 stm=666 core=0
&& at com.android.server.am.ANRManager$AnrDumpMgr.dumpAnrDebugInfoLocked(SourceFile:~832)
&& - waiting to lock&0x& (a com.android.server.am.ANRManager$AnrDumpRecord) held bytid=20 (ActivityManager)
&& at com.android.server.am.ANRManager$AnrDumpMgr.dumpAnrDebugInfo(SourceFile:824)
&& at com.android.server.am.ANRManager$AnrMonitorHandler.handleMessage(SourceFile:220)
&& at android.os.Handler.dispatchMessage(Handler.java:110)
&& at android.os.Looper.loop(Looper.java:193)
&& at android.os.HandlerThread.run(HandlerThread.java:61)
<span style="color:#.3.3 执行JNI code未返回,状态是native的情况
&&WifiP2pService& prio=5tid=37 NATIVE
&& | group=&main&sCount=1 dsCount=0 obj=0x427a9910 self=0x55f088d8
&& | sysTid=734 nice=0 sched=0/0cgrp=apps handle=
&& | state=S schedstat=(
) utm=7 stm=2 core=1
&& #00& pc &/system/lib/libc.so (epoll_wait&#43;12)
&& #01& pc &/system/lib/libutils.so (android::Looper::pollInner(int)&#43;94)
&& #02& pc &/system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)&#43;92)
&& #03& pc 0006c96d&/system/lib/libandroid_runtime.so(android::NativeMessageQueue::pollOnce(_JNIEnv*, int)&#43;22)
&& #04& pc 0001eacc&/system/lib/libdvm.so (dvmPlatformInvoke&#43;112)
&& #05& pc 0004fed9&/system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)&#43;484)
&& #06& pc 00027ea8&/system/lib/libdvm.so
&& #07& pc &/system/lib/libdvm.so (dvmMterpStd(Thread*)&#43;76)
&& #08& pc &/system/lib/libdvm.so (dvmInterpret(Thread*, Methodconst*, JValue*)&#43;188)
&& #09& pc &/system/lib/libdvm.so (dvmCallMethodV(Thread*, Methodconst*, Object*, bool, JValue*,std::__va_list)&#43;340)
&& #10& pc &/system/lib/libdvm.so (dvmCallMethod(Thread*, Methodconst*, Object*, JValue*, ...)&#43;20)
&& #11& pc &/system/lib/libdvm.so
&& #12& pc 0000dd40&/system/lib/libc.so (__thread_entry&#43;72)
&& at android.os.MessageQueue.nativePollOnce(NativeMethod)
&& at android.os.MessageQueue.next(MessageQueue.java:138)
&& at android.os.Looper.loop(Looper.java:150)
&& at android.os.HandlerThread.run(HandlerThread.java:61)
<span style="color:#.3.4 执行object.wait等待状态
&&AsyncTask #1& prio=5tid=33 WAIT
&& | group=&main&sCount=1 dsCount=0 obj=0x427a8480 self=0x56036b40
&& | sysTid=733 nice=10sched=0/0 cgrp=apps/bg_non_interactive handle=
&& | state=S schedstat=(
4229 ) utm=119 stm=75 core=0
&& at java.lang.Object.wait(NativeMethod)
&& - waiting on&0x427a8618& (a java.lang.VMThread) held by tid=33 (AsyncTask #1)
&& at java.lang.Thread.parkFor(Thread.java:1212)
&& at sun.misc.Unsafe.park(Unsafe.java:325)
&& at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
&& at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2017)
&& at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:410)
&& at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)
&& at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1097)
&& at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
&& at java.lang.Thread.run(Thread.java:848)
<span style="color:#.3.5Suspend 状态,通常表明是抓取backtrace时,当时还正在执行java代码,被强制suspend的情况
&&FileObserver& prio=5tid=23 SUSPENDED
&& | group=&main&sCount=1 dsCount=0 obj=0x41fd1dc8 self=0x551abda0
&& | sysTid=710 nice=0 sched=0/0cgrp=apps handle=
&& | state=S schedstat=( ) utm=9 stm=4 core=0
&& #00& pc &/system/lib/libc.so (__futex_syscall3&#43;8)
&& #01& pc 000108cc&/system/lib/libc.so (__pthread_cond_timedwait_relative&#43;48)
&& #02& pc 0001092c&/system/lib/libc.so (__pthread_cond_timedwait&#43;64)
&& #03& pc 00055a93&/system/lib/libdvm.so
&& #04& pc 0005614d& /system/lib/libdvm.so(dvmChangeStatus(Thread*, ThreadStatus)&#43;34)
&& #05& pc 0004ae7f&/system/lib/libdvm.so
&& #06& pc &/system/lib/libdvm.so
&& #07& pc &/system/lib/libandroid_runtime.so
&& #08& pc 0008af9f&/system/lib/libandroid_runtime.so
&& #09& pc 0001eacc&/system/lib/libdvm.so (dvmPlatformInvoke&#43;112)
&& #10& pc 0004fed9&/system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)&#43;484)
&& #11& pc 00027ea8&/system/lib/libdvm.so
&& #12& pc &/system/lib/libdvm.so (dvmMterpStd(Thread*)&#43;76)
&& #13& pc &/system/lib/libdvm.so (dvmInterpret(Thread*, Methodconst*, JValue*)&#43;188)
&& #14& pc &/system/lib/libdvm.so (dvmCallMethodV(Thread*, Methodconst*, Object*, bool, JValue*, std::__va_list)&#43;340)
&& #15& pc &/system/lib/libdvm.so (dvmCallMethod(Thread*, Methodconst*, Object*, JValue*, ...)&#43;20)
&& #16& pc &/system/lib/libdvm.so
&& #17& pc 0000dd40&/system/lib/libc.so (__thread_entry&#43;72)
&& at android.os.FileObserver$ObserverThread.observe(NativeMethod)
&& at android.os.FileObserver$ObserverThread.run(FileObserver.java:88)
2 Native Backtrace
&2.1Native Backtrace
&&2.1.1添加代码直接抓取
Google 默认提供了CallStack API,请参考
system/core/include/libutils/CallStack.h&
system/core/libutils/CallStack.cpp
可快速打印单个线程的backtrace.
<span style="color:#.1.2 自动抓取
Natice层的进程发生异常后一般都在/data/tombstones目录下生成文件(墓碑文件),该文件描述了该进程当前的Backtrace,不过是链接地址,需要进行解析。
&2.1.3利用debuggerd抓取
MTK 已经制作了一个利用debuggerd抓取Native backtrace的tool
RTT(Runtime Trace),对应的执行命令是:
rtt builttimestamp (Apr 18 :21)
USAGE : rtt[-h] -f function -p pid [-t tid]
& -ffuncion : current support functions:
&&&&&&&&&&&&&&&&bt& (Backtrace function)
& -ppid&&&& : pid to trace
& -ttid&&&& : tid to trace
& -nname&&& : process name to trace
&-h&&&&&&&& : help menu
&2.2解析Native Backtrace
你可以使用GDB,或者addr2line等
tool 来解析抓回的Native Backtrace,从而知道当时正在执行的native代码,
arm-linux-androideabi-addr2line-f -C -e symbols address
公司将addr2line封装后实现了一套解析NativeBacktrace(show Stack)。参考下文
3 Kernel Backtrace
&3.1Kernel Backtrace
<span style="color:#.1.1 运行时抓取
* AEE/RTT 工具
* ProcSystem
& catproc/pid/task/tid/stack
*Sysrq-trigger
&adbshell cat proc/kmsg & kmsg.txt
&adbshell &echo 8 & proc/sys/kernel/printk“ //修改printk loglevel
&adbshell &echo t & /proc/sysrq-trigger“ //打印所有的backtrace
&adbshell &echo w & /proc/sysrq-trigger“//打印'-D' status'D'的 process
&Longpress volume UP and DOWN more then 10s
&btp&&&&&&&&&&&&&pid&&&&&&&&&&&&&&&&&
&Displaystack for process &pid&
&bta&&&&&&&&&&&&[DRSTCZEUIMA]&&&&&&&&
&Displaystack all processes
&btc&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&Backtracecurrent process on each cpu
&btt&&&&&&&&&&&&&vaddr&&&&&&&&&&&&&&&
&Backtraceprocess given its struct task add
<span style="color:#.1.2 添加代码直接抓取
* #include&linux/sched.h&
&当前thread:& dump_stack();
&其他thread:& show_stack(task, NULL);
<span style="color:#.2Process/Thread 状态
&&R(running)&,&&/*&&0 */
&&S(sleeping)&,&&/*&&1 */
&&D(disk sleep)&,&/*&& 2*/
&&T(stopped)&,&&/*&&4 */
&&t(tracing stop)&,&/*&& 8*/
&&Z(zombie)&,&&/*&16 */
&&X(dead)&,&&/*&32 */
&&x(dead)&,&&/*&64 */
&&K(wakekill)&,&&/* 128 */
&&W(waking)&,&&/* 256 */
通常一般的Process处于的状态都是S(sleeping),而如果一旦发现处于如D
(disksleep), T (stopped), Z (zombie)等就要认真审查。
系统运行环境
客观的反应系统的执行环境,通常包括如CPU利用率,Memory
使用情况, Storage
剩余情况等。这些资料也非常重要,比如可以快速的知道,当时是否有Process在疯狂的执行,当时是不是处于严重的low memory情况,
Storage是否有耗尽的情况发生等。
程序执行环境
客观的反应当时某个程序(Kernel也可以看成一个程序)的执行现场,此类资讯通常包括如process的coredump,
java heap prof, kernel的memory dump
等。完整的执行环境,我们可以快速的知道当时具体的变量的&#20540;,寄存器&#20540;等,可以精细的分析问题。
其他的一些资讯
这些资讯相对来说,比较零散了,如通常的LOG,一些debug命令的结果数据等。
下面这个case可以看到PowerManagerService, ActivityManager,
WindowManager相互之间发生deadlock。
&PowerManagerService& prio=5tid=25 MONITOR
& | group=&main& sCount=1dsCount=0 obj=0x42bae270 self=0x
& | sysTid=913 nice=0 sched=0/0cgrp=apps handle=
& | state=S schedstat=( 016 ) utm=232 stm=276 core=2
& atcom.android.server.am.ActivityManagerService.bindService(ActivityManagerService.java:~14079)
& - waiting to lock &0x42aa0f78& (acom.android.server.am.ActivityManagerService) held by tid=16 (ActivityManager)
& atandroid.app.ContextImpl.bindServiceCommon(ContextImpl.java:1665)
& atandroid.app.ContextImpl.bindService(ContextImpl.java:1648)
& atcom.android.server.power.PowerManagerService.bindSmartStandByService(PowerManagerService.java:4090)
& atcom.android.server.power.PowerManagerService.handleSmartStandBySettingChangedLocked(PowerManagerService.java:4144)
& at com.android.server.power.PowerManagerService.access$5600(PowerManagerService.java:102)
& atcom.android.server.power.PowerManagerService$SmartStandBySettingObserver.onChange(PowerManagerService.java:4132)
& atandroid.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:181)
& atandroid.os.Handler.handleCallback(Handler.java:809)
& atandroid.os.Handler.dispatchMessage(Handler.java:102)
& atandroid.os.Looper.loop(Looper.java:139)
& atandroid.os.HandlerThread.run(HandlerThread.java:58)
& &ActivityManager& prio=5tid=16 MONITOR
& | group=&main& sCount=1dsCount=0 obj=0x42aa0d08 self=0x
& | sysTid=902 nice=-2 sched=0/0cgrp=apps handle=
& | state=S schedstat=(
69675 ) utm=1544 stm=2392 core=2
& at com.android.server.wm.WindowManagerService.setAppVisibility(WindowManagerService.java:~4783)
& - waiting to lock &0x42d17590& (ajava.util.HashMap) held by tid=12 (WindowManager)
& atcom.android.server.am.ActivityStack.stopActivityLocked(ActivityStack.java:2432)
& at com.android.server.am.ActivityStackSupervisor.activityIdleInternalLocked(ActivityStackSupervisor.java:2103)
& atcom.android.server.am.ActivityStackSupervisor$ActivityStackSupervisorHandler.activityIdleInternal(ActivityStackSupervisor.java:2914)
& at com.android.server.am.ActivityStackSupervisor$ActivityStackSupervisorHandler.handleMessage(ActivityStackSupervisor.java:2921)
& atandroid.os.Handler.dispatchMessage(Handler.java:110)
& atandroid.os.Looper.loop(Looper.java:147)
& atcom.android.server.am.ActivityManagerService$AThread.run(ActivityManagerService.java:2112)
& &WindowManager& prio=5tid=12 MONITOR
& | group=&main& sCount=1dsCount=0 obj=0x42a92550 self=0x6491dd48
& | sysTid=898 nice=-4 sched=0/0cgrp=apps handle=
& | state=S schedstat=(
19755 ) utm=4659 stm=1414 core=1
& atcom.android.server.power.PowerManagerService.setScreenBrightnessOverrideFromWindowManagerInternal(PowerManagerService.java:~3207)
& - waiting to lock &0x42a95140& (ajava.lang.Object) held by tid=25 (PowerManagerService)
& atcom.android.server.power.PowerManagerService.setScreenBrightnessOverrideFromWindowManager(PowerManagerService.java:3196)
& atcom.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedInner(WindowManagerService.java:9686)
& atcom.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedLoop(WindowManagerService.java:8923)
& atcom.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLocked(WindowManagerService.java:8879)
& at com.android.server.wm.WindowManagerService.access$500(WindowManagerService.java:170)
& atcom.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:7795)
& atandroid.os.Handler.dispatchMessage(Handler.java:110)
& at android.os.Looper.loop(Looper.java:147)
& atandroid.os.HandlerThread.run(HandlerThread.java:58)
后一直不见返回
&main& prio=5 tid=1 NATIVE
& | group=&main& sCount=1dsCount=0 obj=0x41bb3d98 self=0x41ba2878
& | sysTid=814 nice=-2 sched=0/0cgrp=apps handle=
& | state=D schedstat=(
32612 ) utm=1670 stm=534 core=0
& (native backtrace unavailable)
& at android.hardware.SystemSensorManager$BaseEventQueue.nativeDisableSensor(NativeMethod)
& at android.hardware.SystemSensorManager$BaseEventQueue.disableSensor(SystemSensorManager.java:399)
& at android.hardware.SystemSensorManager$BaseEventQueue.removeAllSensors(SystemSensorManager.java:325)
& at android.hardware.SystemSensorManager.unregisterListenerImpl(SystemSensorManager.java:194)
& at android.hardware.SensorManager.unregisterListener(SensorManager.java:560)
& at com.android.internal.policy.impl.WindowOrientationListener.disable(WindowOrientationListener.java:139)
& at com.android.internal.policy.impl.PhoneWindowManager.updateOrientationListenerLp(PhoneWindowManager.java:774)
& at com.android.internal.policy.impl.PhoneWindowManager.screenTurnedOff(PhoneWindowManager.java:4897)
& at com.android.server.power.Notifier.sendGoToSleepBroadcast(Notifier.java:518)
& at com.android.server.power.Notifier.sendNextBroadcast(Notifier.java:434)
& at com.android.server.power.Notifier.access$500(Notifier.java:63)
& at com.android.server.power.Notifier$NotifierHandler.handleMessage(Notifier.java:584)
& at android.os.Handler.dispatchMessage(Handler.java:110)
& at android.os.Looper.loop(Looper.java:193)
& at com.android.server.ServerThread.initAndLoop(SystemServer.java:1436)
& at com.android.server.SystemServer.main(SystemServer.java:1531)
& at java.lang.reflect.Method.invokeNative(NativeMethod)
& at java.lang.reflect.Method.invoke(Method.java:515)
& at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
& at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
& at dalvik.system.NativeStart.main(NativeMethod)
KERNEL SPACE BACKTRACE, sysTid=814
&[&ffffffff&] 0xffffffff from[&c07e5140&] __schedule&#43;0x3fc/0x950
&[&c07e4d50&]__schedule&#43;0xc/0x950 from [&c07e57e4&] schedule&#43;0x40/0x80
&[&c07e57b0&] schedule&#43;0xc/0x80from [&c07e5ae4&] schedule_preempt_disabled&#43;0x20/0x2c
&[&c07e5ad0&]schedule_preempt_disabled&#43;0xc/0x2c from [&c07e3c3c&]mutex_lock_nested&#43;0x1b8/0x560
&[&c07e3a90&]mutex_lock_nested&#43;0xc/0x560 from [&c05667d8&] gsensor_operate&#43;0x1bc/0x2c0
&[&c0566628&]gsensor_operate&#43;0xc/0x2c0 from [&c0495fa0&] hwmsen_enable&#43;0xa8/0x30c
&[&c0495f04&]hwmsen_enable&#43;0xc/0x30c from [&c0496500&]hwmsen_unlocked_ioctl&#43;0x2fc/0x528
&[&c0496210&]hwmsen_unlocked_ioctl&#43;0xc/0x528 from [&c018ad98&] do_vfs_ioctl&#43;0x94/0x5bc
&[&c018ad10&] do_vfs_ioctl&#43;0xc/0x5bcfrom [&c018b33c&] sys_ioctl&#43;0x7c/0x8c
&[&c018b2cc&]sys_ioctl&#43;0xc/0x8c from [&c000e480&] ret_fast_syscall&#43;0x0/0x40
&[&ffffffff&]& from[&ffffffff&]&
客观的反应系统的执行环境,通常包括如CPU利用率,Memory
使用情况, Storage
剩余情况等。这些资料也非常重要,比如可以快速的知道,当时是否有Process在疯狂的执行,当时是不是处于严重的low memory情况,
Storage是否有耗尽的情况发生等。
追查CPU利用率可大体的知道,当时机器是否有Process在疯狂的运行,当时系统运行是否繁忙。通常死机分析,只需要抓取基本的使用情况即可。下面说一下一般的抓取方式
top 可以简单的查询Cpu的基本使用情况
Usage: top[ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h]
&&&-m num& Maximum number of processes to display.
&&&-n num& Updates to show before exiting.
&&&-d num& Seconds to wait between updates.
&&&-s col& Column to sort by (cpu,vss,rss,thr).
&&&-t&&&&& Show threads instead of processes.
&&&-h&&&&& Display this help screen.
注意的是top的CPU%
是按全部CPU
来计算的,如果以单线程来计算,比如当时有开启<span style="color:#个核心,那么最多吃到<span style="color:#%。&
个人常见的操作方式如:& top -t -m 5 -n 2
I.E 正常情况
User 2%, System 12%, IOW 0%, IRQ 0%
User 14 &#43; Nice 0 &#43; Sys 67 &#43; Idle 471 &#43; IOW0 &#43; IRQ 0 &#43; SIRQ 2 = 554
& PID&& TID PR CPU%S&&&& VSS&&&& RSS PCYUID&&&&&Thread&&&&&&&&& Proc
&& 1&&8% R&& 2316K&& 1128K&&&&root&&&&top&&&&&&&&&&&& top
& 270&& 270&0&& 1% S&& 2160K&&&924K&&&& root&&&&aee_resmon&&&&& /system/bin/aee_resmon
& 159&& 159&0&& 0% D&&&&&0K&&&&& 0K&&&&root&&&& bat_thread_kthr
&&&3&&&& 3& 0&& 0%S&&&&& 0K&&&&&0K&&&& root&&&& ksoftirqd/0
&& 57&&& 57&0&& 0% D&&&&&0K&&&&& 0K&&&&root&&&& hps_main
User 1%, System 7%, IOW 0%, IRQ 0%
User 10 &#43; Nice 0 &#43; Sys 41 &#43; Idle 494 &#43; IOW0 &#43; IRQ 0 &#43; SIRQ 0 = 545
& PID&& TID PR CPU%S&&&& VSS&&&& RSS PCYUID&&&&&Thread&&&&&&&&& Proc
&& 1&&8% R&& 2324K&& 1152K&&&&root&&&&top&&&&&&&&&&&& top
&& 57&&& 57&0&& 0% D&&&&&0K&&&&& 0K&&&&root&&&& hps_main
& 242&& 419&0&& 0% S&& 8600K&& 4540K&&&&shell&&& mobile_log_d&&& /system/bin/mobile_log_d
& 982&& 991&0&& 0% S&& 4364K&& 1156K&&&&media_rw sdcard&&&&&&&&&/system/bin/sdcard
& 272&& 272&0&& 0% S& 30680K&& 9048K&&&&root&&&&em_svr&&&&&&&&& /system/bin/em_svr
& 从上面可以看出,系统基本运行正常,没有很吃CPU的进程。
I.E 异常情况
User 59%, System 4%, IOW 2%, IRQ 0%
User 1428 &#43; Nice 0 &#43; Sys 110 &#43; Idle 811 &#43;IOW 67 &#43; IRQ 0 &#43; SIRQ 1 = 2417
& PID&& TID PR CPU%S&&&& VSS&&&& RSS PCYUID&&&&&Thread&&&&&&&&& Proc
& 3& 14% R997100K& 53492K& bg u0_a60&&Thread-1401&&&& com.android.mms
& 1& 14% R997100K& 53492K& bg u0_a60&&Thread-1400&&&& com.android.mms
& 2& 14% R997100K& 53492K& bg u0_a60&&Thread-1399&&&& com.android.mms
& 0& 14% R997100K& 53492K& bg u0_a60&&Thread-1398&&&& com.android.mms
& 4&& 1%R&& 2068K&& 1020K&&&&shell&&&top&&&&&&&&&&&& top
User 67%, System 3%, IOW 7%, IRQ 0%
User 1391 &#43; Nice 0 &#43; Sys 75 &#43; Idle 435 &#43;IOW 146 &#43; IRQ 0 &#43; SIRQ 1 = 2048
& PID&& TID PR CPU%S&&&& VSS&&&& RSS PCYUID&&&&&Thread&&&&&&&&& Proc
& 3& 16% R997100K& 53492K& bg u0_a60&&Thread-1401&&&& com.android.mms
& 2& 16% R997100K& 53492K& bg u0_a60&&Thread-1399&&&& com.android.mms
& 0& 16% R997100K& 53492K& bg u0_a60&&Thread-1400&&&& com.android.mms
& 1& 16% R997100K& 53492K& bg u0_a60&&Thread-1398&&&& com.android.mms
& 4&& 2%R&& 2196K&& 1284K&&&&shell&&&top&&&&&&&&&&&& top
可以明显的看到,贵司的mms的<span style="color:#个thread都有进入了deadloop,分别占用了一个cpu
core.&同时可以快速抓取他们的java trace,&进一步可以看到当时MMS的四个backtrace,以便快速分析。
&Thread-1401& prio=5 tid=32SUSPENDED JIT
& | group=&main& sCount=1dsCount=0 obj=0x self=0x7b183558
& | sysTid=32195 nice=0 sched=0/0cgrp=apps/bg_non_interactive handle=
& | state=S schedstat=( 8 383002 ) utm=324720 stm=3725 core=5
& at com.yulong.android.mms.c.f.d(MmsChatDataServer.java:~1095)
& at com.yulong.android.mms.ui.MmsChatActivity$37.run(MmsChatActivity.java:7582)
& at java.lang.Thread.run(Thread.java:841)
&Thread-1400& prio=5 tid=31SUSPENDED JIT
& | group=&main& sCount=1dsCount=0 obj=0x41f5d8f0 self=0x7be2a8e8
& | sysTid=32190 nice=0 sched=0/0cgrp=apps/bg_non_interactive handle=
& | state=S schedstat=( 2 382946 ) utm=324805 stm=3685 core=5
& at com.yulong.android.mms.ui.MmsChatActivity$37.run(MmsChatActivity.java:~7586)
& at java.lang.Thread.run(Thread.java:841)
&Thread-1399& prio=5 tid=30SUSPENDED JIT
& | group=&main& sCount=1dsCount=0 obj=0x42564d28 self=0x7b0e6838
& | sysTid=32188 nice=0 sched=0/0cgrp=apps/bg_non_interactive handle=
& | state=S schedstat=( 6 375959 ) utm=325143 stm=3661 core=7
& at com.yulong.android.mms.ui.MmsChatActivity$37.run(MmsChatActivity.java:~7586)
& at java.lang.Thread.run(Thread.java:841)
&Thread-1398& prio=5 tid=29SUSPENDED
& | group=&main& sCount=1dsCount=0 obj=0x self=0x7be0d128
& | sysTid=32187 nice=0 sched=0/0cgrp=apps/bg_non_interactive handle=
& | state=S schedstat=( 3 379634 ) utm=325055 stm=3669 core=6
& at com.yulong.android.mms.ui.MmsChatActivity$37.run(MmsChatActivity.java:~7586)
& at java.lang.Thread.run(Thread.java:841)
当时处于suspend,即意味着当时这四个thread正在执行java
code,而抓取backtrace时强制将thread suspend。看起来客户改动所致,并且客户有Proguard,麻烦客户自己review代码。
ftrace 可以纪录CPU最为详细的执行情况,即linux scheduler的执行情况。通常默认只开启
sched_switch。&
如何抓取ftrace可以查询相关的FAQ。
有的时候我们需要追查一下,当时Kernel的基本调度情况,以及接收中断的情况,以判断当前CPU执行的基本情况是否异常。比如有时候如果某个中断上来太过频繁,就容易导致系统运行缓慢,甚至死机。
* CPU Sched status
&&&& adb shell catproc/sched_debug
&&&& Use sysrq-trigger
* CPU interrupts
&&&& adb shell catproc/interrupts
&&&& adb shell catproc/irq/irq_id/spurious
MemoryUsage,我们通常会审查,系统当时memory是否足够,是否处于low
memory状态,是否可能出现因无法申请到memory而卡死的情况。
常见的一些基本信息如下:
* meminfo: basic memory status
adb shell cat proc/meminfo
adb shell cat proc/pid/maps
adb shell cat proc/pid/smaps
* procrank info: all process memory status
adb shell procrank
adb shell procmem pid
adb shell dumpsys meminfo pid
* zoneinfo:
adb shell cat proc/zoneinfo
* buddyinfo:
adb shell cat /proc/buddyinfo
查看Storage的情况,通常主要是查询data分区是否已经刷满, sdcard是否已经刷满,剩余的空间是否足够。以及是否有产生超大文件等。
通常使用的命令如 df
Filesystem&&&&&&&&&&&&&&Size&&&& Used&&&& Free&&Blksize
/dev&&&&&&&&&&&&&&&&&&446.0M&& 128.0K&& 445.8M&& 4096
/sys/fs/cgroup&&&&&&&&446.0M&&& 12.0K&& 445.9M&& 4096
/mnt/secure&&&&&&&&&&&446.0M&&&& 0.0K&& 446.0M&& 4096
/mnt/asec&&&&&&&&&&&&&446.0M&&&& 0.0K&& 446.0M&& 4096
/mnt/obb&&&&&&&&&&&&&&446.0M&&&& 0.0K&& 446.0M&& 4096
/system&&&&&&&&&&&&&&&&&1.2G&& 915.3M&& 355.5M&& 4096
/data&&&&&&&&&&&&&&&&&&&1.1G&& 136.7M& 1010.1M&& 4096
/cache&&&&&&&&&&&&&&&&106.2M&&& 48.0K&& 106.2M&& 4096
/protect_f&&&&&&&&&&&&&&4.8M&&& 52.0K&&&& 4.8M&& 4096
/protect_s&&&&&&&&&&&&&&4.8M&&& 48.0K&&&& 4.8M&& 4096
/mnt/cd-rom&&&&&&&&&&&&&1.2M&&&& 1.2M&&&& 0.0K&& 2048
/mnt/media_rw/sdcard0&&&&4.6G&&&& 1.1G&&&& 3.4G&&32768
/mnt/secure/asec&&&&&&&&4.6G&&&& 1.1G&&&& 3.4G&&32768
/storage/sdcard0&&&&&&&&4.6G&&&& 1.1G&&&& 3.4G&&32768
以及ls, du 等命令,如du
usage: du [-H | -L | -P] [-a | -d depth |-s] [-cgkmrx] [file …]
du -LP -d 1
8&&&&&& ./lost&#43;found
88&&&&& ./local
384&&&& ./misc
48&&&&& ./nativebenchmark
912&&&& ./nativetest
8&&&&&& ./dontpanic
13376&&./data
8&&&&&& ./app-private
8&&&&&& ./app-asec
129424& ./app-lib
8&&&&&& ./app
136&&&& ./property
16&&&&& ./ssh
116312& ./dalvik-cache
8&&&&&& ./resource-cache
48&&&&& ./drm
8&&&&&& ./mediadrm
8&&&&&& ./security
3888&&& ./nvram
8&&&&&& ./amit
8&&&&&& ./acdapi
32&&&&& ./sec
8&&&&&& ./user
16&&&&& ./media
16&&&&& ./agps_supl
8&&&&&& ./anr
8&&&&&& ./gps_mnl
8&&&&&& ./nfc_socket
16&&&&& ./ccci_cfg
32&&&&& ./mdlog
1312&&& ./system
176&&&& ./recovery
32&&&&& ./backup
当我们怀疑死机问题可能是某个进程出现问题而引发时,通常我们需要对这个进程进行深入的分析,即进程运行环境分析。通常包括分析如,线程状态,各种变量&#20540;,寄存器状态等。在Android系统中,我们将其划分成三个层次。
即 Java运行环境分析, Native运行环境分析, Kernel运行环境分析。下面分别说明。
运行环境分析
我们对于Zygote fork出来的process,如APP以及system_server,都会进行Java运行环境分析。其关键是分析Java
Heap,以便快速知道某个Java变量的&#20540;,以及Java对象的分布和引用情况。
通常Java Heap的分析方式则是抓取Java Hprof,然后使用MAT等工具进行分析。
* 抓取Hprof的手法,如:
第一种方式:使用am
&&&adb shell am dumpheap {Process} file
&adbshell chmod 777 /data/anr
&adbshell am dumpheap com.android.phone /data/anr/phone.hprof
&adbpull /data/anr/phone.hprof
&第二种方式:使用DDMS
&在DDMS中选择对应的process,然后在Devices按钮栏中选择Dump
Hprof file,保存即可
&第三种方式:通过代码的方式
&&&在android.os.Debug这个class
中有定义相关的抓取hprof
的method。
&如: public static void dumpHprofData(String fileName) throwsIOE
&这样即可在代码中直接将这个process的hprof
保存到相对应的文件中,注意这个只能抓取当时的process。
&如果想抓其他的process的hprof,那么就必须通过AMS帮忙了。
&可以先获取IActivityManager接口,然后调用它的dumpheap方法。具体的代码,大家可以参考
&frameworks/base/cmds/am/src/com/android/commands/am/am.java中的调用代码
第四种方式:发送SIGUSER1&
&&&在部分机器中,如果具有root权限,可以直接发送SIG 10来抓取,此时对应的Hprof保存在/data/misc下面,文件名如:
&heap-dump-tm-pid1882.hprof
* 快速分析
首先, DVM的Hprof
和标准的Java Hprof
有一些差别,需要使用hprof-conv进行一次转换,将DVM&#26684;式的hprof
转换成标准的java
命令的hprof
&&&hprof-conv in.hprof out.hprof
其次,使用如MAT Tool,打开转换后的hprof文件,通常我们会
&analysis&java thread information
&analysis&java var value
&analysis&Object reference
&analysis&GC path
具体如何使用MAT分析可以参考MAT
的官方网站。
&3. Native 运行环境分析
Native 运行环境分析,我们通常会采用Core dump分析手法。 Core dump纪录了当时进程的各类关键资讯,比如变量参数,线程stack,
heap, register等。通常可以认为是这个Process当时最为完整的资讯了。但Core
dump往往比较大,有时甚至会超过<span style="color:#G,属于比较重量型的分析手法了。
* 如何抓取Core Dump。
&&目前MTK的机器会将Core Dump转换成AEE
DB。否则对应的Core dump文件即存放在/data/core目录下
&&手工抓取时,可以:
&&adb shell aee -d coreon
&&adb shell kill -31 PID
&&此时core dump就可能存放在两个目录下:/data/core,以及/sdcard/mtklog/aee_exp下面新的DB
* 如何分析Core Dump。
& 因为通常已经将Core Dump转换成了AEE DB。所以首先将AEE
DB解开,即可以看到PROCESS_COREDUMP的文件,有的时候此文件很大,比如超过<span style="color:#G。
& 而分析Core Dump的Tools
很多,比如traces32, GDB等,这里就不详加说明,可以参考网络上的相关文档。
运行环境分析
从<span style="color:#平台上多了ramdump功能,可以发生KE后将<span style="color:#/92的物理内存压缩保存到EMMC的内置卡(默认保存到EMMC内置卡上)(92可以选择外置t卡)上,拿到该文件后就可以转换为kernel
space,查看kernel各种变量,比查看kernel log更加方便快捷。
只有在eng版本下支持该功能,并且是EMMC的,存在内置T卡才行,
在projectConfig.mk里的MTK_SHARED_SDCARD必须为no即MTK_SHARED_SDCARD=no
连上adb后:
#echo Y& /sys/module/mrdump/parameters/enable
#echo emmc& /sys/module/mrdump/parameters/device& (注意<span style="color:#只能在EMMC内置t卡上,不能下这条命令,<span style="color:#可以下这条命令修改到sdcard:#echo
sdcard & /sys/module/mrdump/parameters/device)
这样就开启了ramdump功能,注意重启后无效,必须重新设置才行
之后重新开机,此时会在
内置T卡:/storage/sdcard0/
或外置T卡:/storage/sdcard1/
看到CEDump.kdmp文件,结合kernel/out/vmlinux或out/target/product/$proj/obj/KERNEL_OBJ/vmlinux一起提供给Mediatek即可做进一步kernel异常重启的分析。
当你遇到死机问题时,你可能面临的是下面三种情况。
* 有死机现场
&&资讯最为充足,你可以快速的利用死机现场来分析。
* 已经重启过的手机
& 死机现场已经不复存在,但手机还没有刷机,可以从手机中抓取已经存在的资讯来分析。
* 仅仅一些LOG或者其他的资讯
& 需要从这些LOG或者资讯中猜测当时手机的状态,以及可能死机的原因。
&从这三种情况,不难得知,有死机现场的情况下是最容易分析的。而如果仅仅只有一些LOG的话,就需要工程师具有非常丰富的经验,从仅有的LOG中,提取有价&#20540;的资讯,来猜测出当时死机的原因。
死机分析如同医生给病人诊断病情,所有的手法不在乎分为两种。
* 高科技的诊断设备,分析病人的病情。死机分析就依靠各种技术方法去诊断当时手机的运行的真实状态。
* 通过病人的各种活动,分析病人的潜在病因。就依靠各种对手机的操作,以及命令,让手机跑相应的流程,从而进一步分析。
&下面我们将针对每一个流程进行具体的说明。
* 通过做一些基本的测试,可大体上确认可能引发死机的模块,为后续Debug确定好方向。
* 通常只能正向推理,可以做什么 =》推断什么模块正常;逆向推理可能因为各种原因而失常。
&*Touch Panel
&&- 屏幕是否有响应(一般情况下没响应)。
&&- 如果有响应,可能机器已经活过来了,或者当时把ANR认为了hang
机;需要进一步确认情况。
&&- 确认按键的情况,通常都设定振动反馈,如果有,那么就认为当时按键事件可以传递到SystemServer,此时可能System
Server 逻辑异常。
&*Power Key/ Volumn Up/Down Key
&&- 是否可以亮、灭屏
&&- 可点亮关闭屏幕,说明KPD -&input manager-&PowerManagerService-&Power-&LCDdriver正常;通常可以怀疑TPD,以及SurfaceFlinger。
&* 是否可以显示音量调整情况
&&- 可显示音量调整情况,进一步说明SurfaceFlinger也正常,进一步怀疑TPD,或者直接的APP无响应的情况。
&*SystemUI & Status Bar
&&- Status Bar 是否可以拉下,以便防止只是活动区卡住的情况,可下拉,说明只是APP卡住,或者lockscreen无法解锁的情况
*LockScreen
&&- 测试LockScreen是否可以解锁,
* Home Key/ Back Key/Menu Key
&&- 确认当时是否只是APP hang住的情况,避免将ANR误判为死机
* 插入USB观察充电情况
&&- 可确认Surfaceflinger, System Server的运行情况
* 插入USB,确认ADB是否可以使用
&- 首先查看windows的设备管理器里面是否出现对应的设备
&- 在命令行中输入adb devices,看是否可以打印设备信息,在输入之前您最好先输入adb
kill-server 保证pc上的adb client没有卡住
&- 请确保您使用的PC上已经安装ADB,USB端口本身正常
&*Case1: adb 能正常连接,adb shell #
- adb 目前可以正常接入,可以进行USB/ADB Debug
&*Case2: windows 设备管理器有反应,adb shell提示device not found。
- 确认adb驱动是否安装好,USB的uid
是否和driver匹配。
- 可能机器的adbd已经无法对接,尝试adbkill-server来确认
&*Case3:& windows 设备管理器有反应,adb shell提示offline。
- 机器的adbd拒绝连接,或者adbd无法拉起。
- PC adb 版本过低
- 很可能adbd已经卡住, adbdprocess status为
机器状态基本检测
* ps or ps-t or ps -t -p查看进程基本状态
&-t& 以线程为单位打印
&-p& 附加打印线程优先级信息
&** 追查如system server, surfaceflinger,
service manager, media server(ss, sf, sm、ms),zygote,等关键进程的状态,进行初步确认。正常情况下,都应处于’S’,异常情况有如’D’,
‘T’, ‘Z’
, ‘R’等
** 大体追查ss, sf,
sm, ms, zygote等的memory情况,是否有明显的溢出情况
** 大体查看当时的ss pid, sf pid,如果机器上层没有重启过,通常sf
pid & 200, ss pid & 600,如果pid比较大就说明上层重启过。
** 是否还存在特别进程,如ipod,表示在ipo关机中,如aee_core_forworder,表示在抓core
dump,aee_dumpstate表示aee
** 追查debuggerd的process
数量,通常正常时,只有一个debuggerd process,pid & 200,如果有达到<span style="color:#个debuggerd,这个时候将无法进行rtt之类的操作
- 审查storage的使用情况,查看SD
分区使用情况,特别是如SD卡已满,或者data
分区写满等。
&* catproc/meminfo, procrank
- 审查当前的memory使用情况,追查各个进程的memory情况
- 审查当前system properties情况
&* top-t -m 5 -n 2
- 摸一摸手机,感觉有点热,或者发烫的话,说明通常是CPU利用率比较高
- 大体上审查当前CPU的利用情况,不求精湛
总之,机器状态基本检测,目标就是通过简单几个命令直接侦测当前手机最为可能的异常情况。包括关键进程基本状态, CPU利用率,memory
状况,storage
状况等。做出基本的预先分析,从而为下一步的debug打好基础。
当usb/adb无法确认问题时或者已经无法连接时,我们需要利用UART/KDB来进一步厘清问题。
确认UART以及 UART Console已经开启。
ENG 版本默认开启,User版本默认关闭。通常在User版本上如果需要抓取UART日志的话需要用散件工具单烧ENG版本的LK分区重启就可以抓取UART日志了。
目前我司一般的UART端口都不支持输入,所以只能通过输出的UART输出的log来分析问题。
我们又回到了最开始的可能会导致死机的模块,下面我们将针对每一个模块做详细的说明。
* 确认Input Driver-Input System通路是否正常,即inputdriver是否可以传上正常的输入
* 最常见的检测方式是 adb shell getevent
如直接输入adb shell getevent可以看到:
D:\log&adbshell getevent
add device1: /dev/input/event0
&name:&&&& &mtk-kpd&
could notget driver version for /dev/input/mouse0, Not atypewriter
add device2: /dev/input/event3
&name:&&&& &mtk-tpd&
add device3: /dev/input/event2
&name:&&&& &hwmdata&
add device4: /dev/input/event1
&name:&&&& &ACCDET&
could notget driver version for /dev/input/mice, Not atypewriter
&对应的操作命令是:
Usage:getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q][-c count] [-r] [device]
&&&-t: show time stamps
&&&-n: don't print newlines
&&&-s: print switch states for given bits
&&&-S: print all switch states
&&&-v: verbosity mask (errs=1, dev=2, name=4,
info=8, vers=16, pos. events=32, props=64)
&&&-d: show HID descriptor, if available
&&&-p: show possible events (errs, dev, name,
pos. events)
&&&-i: show all device info and possible events
&&&-l: label event types and names in plain text
&&&-q: quiet (clear verbosity mask)
&&&-c: print given number of events then exit
&&&-r: print rate events are received
&通常我们会一项一项的确认native层是否可以收到Kernel传递来的input
event事件。
比如我们追查KPD是否有效果,按power key可以看到相关的行为。
D:\log &adbshell getevent -t -l /dev/input/event0
[.433356]EV_KEY&&&&&& KEY_POWER&&&&&&&&&&&DOWN
[.433356]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.527596]EV_KEY&&&&&&KEY_POWER&&&&&&&&&&& UP
[.527596]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.824871]EV_KEY&&&&&&KEY_POWER&&&&&&&&&&&DOWN
[.824871]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.996095]EV_KEY&&&&&&KEY_POWER&&&&&&&&&&& UP
[.996095]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.495346]EV_KEY&&&&&&KEY_POWER&&&&&&&&&&&DOWN
[.495346]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.530963]EV_KEY&&&&&&KEY_POWER&&&&&&&&&&& UP
[.530963]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
&当然如果屏幕是点亮时,肯定就要快速追查tpd以及模拟按键是否正常
D:\log &adbshell getevent -t -l /dev/input/event5
[.432516]EV_ABS&&&&&& ABS_MT_TOUCH_MAJOR&&
[.432516]EV_ABS&&&&&& ABS_MT_TRACKING_ID&&
[.432516]EV_KEY&&&&&&BTN_TOUCH&&&&&&&&&&&DOWN
[.432516]EV_ABS&&&&&& ABS_MT_POSITION_X&&&
[.432516]EV_ABS&&&&&& ABS_MT_POSITION_Y&&&
[.432516]EV_SYN&&&&&&SYN_MT_REPORT&&&&&&&
[.432516]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.496797]EV_ABS&&&&&& ABS_MT_TOUCH_MAJOR&&
[.496797]EV_ABS&&&&&& ABS_MT_TRACKING_ID&&
[.496797]EV_ABS&&&&&& ABS_MT_POSITION_X&&&
[.496797]EV_ABS&&&&&& ABS_MT_POSITION_Y&&&0000027d
[.496797]EV_SYN&&&&&&SYN_MT_REPORT&&&&&&&
[.496797]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.506985]EV_ABS&&&&&& ABS_MT_TOUCH_MAJOR&&
[.506985]EV_ABS&&&&&& ABS_MT_TRACKING_ID&&
[.506985]EV_ABS&&&&&& ABS_MT_POSITION_X&&&
[.506985]EV_ABS&&&&&& ABS_MT_POSITION_Y&&&0000027a
[.506985]EV_SYN&&&&&&SYN_MT_REPORT&&&&&&&
[.506985]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
[.517713]EV_KEY&&&&&&BTN_TOUCH&&&&&&&&&&& UP
[.517713] EV_SYN&&&&&&SYN_MT_REPORT&&&&&&&
[.517713]EV_SYN&&&&&&SYN_REPORT&&&&&&&&&&
&如果发现无法收到此类资讯,那么就可以确认对应的devices可能有故障,需要请对应的driver& vendor工程师来分析。
此分析的关键在于分析 system-server是否还在正常的运转,这是非常重要的,据统计,<span style="color:#%的usb可以debug
机问题,都可以通过对system-server逻辑的审查找出原因。
&Systemserver 是整个android上层的中枢,容纳了最为重要的service。
&对System server的分析主要是通过java native的backtrace来追查Systemserver的关键thread
有没有被lock/dead lock,有没有进入dead loop,状态是否正常。
&从死机机的角度来看system server关键的thread
Serverthread:
System-server的main looper建立在serverthread上,所有service如果不单独创立thread-looper那么都将运行在这个Server
thread上,其关键性不言而喻,用watchdog来监测该thread。
ActivityManager:
处理所有的Activity状态切换,broadcast,以及ANR
监测等等,非常重要。
WindowManager:
处理各种window叠加与切换,Input相关处理。
WindowManagerPolicy/UI:
主要处理LockScreen相关流程,它卡住,lockscreen无法解锁
PowerManagerService:
处理Power相关事宜,它卡住,屏幕无法熄灭,点亮
InputDispatcher/InputReader
处理Input System相关事宜,一旦他们卡住,那么所有的Input Event都无法反馈到其他的module,机器死机就成必然。
在KK以及KK
以后的版本中Google
取消了serverthread这样的main looper thread,直接使用system
server 的第一个thread作为main looper。&Google对system
server的threads
做了进一步的整合,以减少繁杂的线程数,新增了如android.io,android.ui,android.fg,android.bg等threads。将大量的普通型的Handler按时效分类分散到上面的<span style="color:#个threads中。
所以KK及更高的版本还需要分析ndroid.io, android.ui,
android.fg, android.bg等thread。
&这些thread都通过执行MQ-Looper-Handler的模式运行,所以正常的时候的java/native
backtrace都是:
& at android.os.MessageQueue.nativePollOnce(NativeMethod)
& at android.os.MessageQueue.next(MessageQueue.java:138)
& at android.os.Looper.loop(Looper.java:150)
& #00& pc 0002599c&/system/lib/libc.so (epoll_wait&#43;12)
& #01& pc &/system/lib/libutils.so (android::Looper::pollInner(int)&#43;94)
& #02& pc &/system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)&#43;92)
& #03& pc 0006ca5d&/system/lib/libandroid_runtime.so(android::NativeMessageQueue::pollOnce(_JNIEnv*, int)&#43;22)
&一旦不是就可能已经出现异常了。
BinderThread
Systemserver 为外界提供服务,绝大多数都通过binder与其他process
对接。BinderThread
的数量动态调整,默认不会超过<span style="color:#个,如果数量达到<span style="color:#个,即说明当前system server可能非常繁忙,有process非常频繁的和Process通信。
在JB以及以前版本,System-server的第一个thread,在调起serverthread后,自己加到IPCthread
pool中,成为Binder Thread的一员。&
对于Binder Thread,正常时对应的Backtrace:
& #00& pc & /system/lib/libc.so(__ioctl&#43;8)
& #01& pc & /system/lib/libc.so (ioctl&#43;28)
& #02& pc & /system/lib/libbinder.so(android::IPCThreadState::talkWithDriver(bool)&#43;140)
& #03& pc 0001dae3& /system/lib/libbinder.so(android::IPCThreadState::getAndExecuteCommand()&#43;6)
& #04& pc 0001db79& /system/lib/libbinder.so(android::IPCThreadState::joinThreadPool(bool)&#43;48)
& #05& pc 00021a79& /system/lib/libbinder.so
& #06& pc 0000ea01& /system/lib/libutils.so(android::Thread::_threadLoop(void*)&#43;216)
& #07& pc &/system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)&#43;68)
& #08& pc & /system/lib/libutils.so
& #09& pc & /system/lib/libc.so(__thread_entry&#43;72)
& at dalvik.system.NativeStart.run(Native Method)
&抓取system server的java backtrace,依次check
serverthread(JB),ActivityManager, WindowManager,
WindowManagerPolicy,PowerManagerService以及android.io,
android.bg, android.fg, android.ui的状态,如状态异常,则依次推导。
当发现java backtrace最后调用到异常nativemethod时,抓取其native
backtace,通过native backtrace
进一步追查.
如果在native backtrace中,发现已经调入binderdriver,那就是通过binder进行IPC
call,这个时候就要知道binder的对端process,然后查阅它的binder
thread进程进一步分析问题。
&Case1: Abnormal Java Backtrace “Deadlock”
图片deadlock-java-backtrace.png
&Case2: Abnormal Java Backtrace “Lock in native thread&
图片lock-in-native-thread.png
&Case3: Abnormal native Backtrace “Lock in Binder”
图片lock-in-binder.png
&Case4: Abnormal native Backtrace &Lock in Binder thread&
图片lock-in-binder-thread.png
&当确认前面的key thread都没用问题,而通过getevent确认event
已经传递到system server。问题可能出在inputsystem中。
WindowManagerService通过InputManager提供的接口开启一个线程驱动InputReader不断地从/dev/input
/目录下面的设备文件读取事件,然后通过InputDispatcher分发给连接到WindowManagerService服务的客户端。
&Input Reader 正常的backtrace:
&InputReader& sysTid=611
/system/lib/libc.so(epoll_wait&#43;12)
/system/lib/libinput.so(android::EventHub::getEvents(int, android::RawEvent*, unsigned int)&#43;1092)
#02 pc 0002aaf7 /system/lib/libinput.so(android::InputReader::loopOnce()&#43;142)
/system/lib/libinput.so(android::InputReaderThread::threadLoop()&#43;8)
/system/lib/libutils.so(android::Thread::_threadLoop(void*)&#43;492)
#05 pc 0004d12b/system/lib/libandroid_runtime.so(android::AndroidRuntime::javaThreadShell(void*)&#43;150)
/system/lib/libutils.so
#07 pc 0000f66c /system/lib/libc.so (__thread_entry&#43;80)
&Input Dispatcher 正常的backtrace:
&InputDispatcher& sysTid=610
/system/lib/libc.so(epoll_wait&#43;12)
#01 pc 0001c05c /system/lib/libutils.so(android::Looper::pollInner(int)&#43;140)
/system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)&#43;76)
/system/lib/libinput.so(android::InputDispatcher::dispatchOnce()&#43;94)
#04 pc 0001f5bd /system/lib/libinput.so(android::InputDispatcherThread::threadLoop()&#43;8)
/system/lib/libutils.so(android::Thread::_threadLoop(void*)&#43;492)
#06 pc 0004d12b/system/lib/libandroid_runtime.so(android::AndroidRuntime::javaThreadShell(void*)&#43;150)
/system/lib/libutils.so
#08 pc 0000f66c /system/lib/libc.so(__thread_entry&#43;80)
&Backtrace通常都可以精确的定位问题点,比如卡在了哪一行。
那有没有可能您抓backtrace时,恰好运行到,造成乌龙的情况呢?这个通常需要具体情况具体分析
--- NativeBacktrace 处于R状态
--- JavaBacktrace 处于 Suspend状态, Running状态
---Backtrace 处于明确的非block状态
--- DoubleBacktrace 确认是否CPU有运转
随着android版本的推进,system-server越来越显得庞大,为此Google对system-server做了分拆动作.
After 4.0&SurfaceFlinger removed from system-server and created by init, single process SurfaceFlinger。
除SurfaceFlinger外,对system-server影响最大的是MediaServer。
注意对于surfaceflinger, mediaserver等非DVM Process,切忌不要对他们send
signalSIGQUIT(3),将导致对应的process直接退出
DisplayControl Flow
图片: display-control-flow.png
&*Surface Manager(Surfaceflinger)
**Surfaceflinger 是用户空间中Framework下libraries中负责显示相关的一个模块&
** 当系统同时执行多个应用程序时,Surfaceflinger负责管理显示,主要包括显示的叠加和显示的渲染&
** 其中显示的叠加,MTK架构按照一定的原则和算法,主要用到GPU和
OVL 模块的overlay
功能来做<span style="color:#D/3D
绘图的显示合成
** 基于DDP OVL硬件做HW Overlay功能
&* GPU(Graphic Processing Unit )
**aspecialized electronic circuit designed to accelerate the image processing, frame buffer rendering for output to a display。
&*FrameBuffer&
** 基于Linux Frame buffer模型的MTKFramebuffer实作,主要来管理frame
&*DDP(DisplayData Path)
** MTKDisplay Hardware Controller,包括OVL, DMA,
Color Processor,BLS,& DSI/DBI/DPIController
&DisplayData Flow
图片: display-data-flow.jpg
&* Display大致的流程说明
** APP(包括WMS)会把数据透过Surface送到SF(surfaceflinger)
** SF 按照一定规则,通过GPU/HWC把多个Surface合成,并设定到DDP
OVL 的对应layer
*** MTK OVL一般有<span style="color:# layer(可能不同平台会有差异,目前基本都是<span style="color:# layer),每个layer都可以设定一个对应的图层,然后OVL把这写图层合成后送给DDP的下一级Module
*** 某些情况下(比如总的图层超过<span style="color:#个,OVL无法处理等各种case),会使用GPU
去做<span style="color:#D/3D
的图层合成到frame buffer
** SF/HWC 最后把GPU合成图层以及需要OVL合成的图层,设定到OVL的HW
Register,并trigger HW Engine
** MTK DDP 就会把合成的数据像管道一样流向LCM module,最后Panel显示相关的画面
&&对Display的快速分析,我们主要是两个手段,第一个确认FrameBuffer数据是否和理想数据一致,第二个确认SurfaceFlinger状态是否正确。
* 确认FrameBuffer数据和理想数据一致,那么说明android上层的处理行为都是正常的,而问题就很可能出在LCM的driver
本身问题,此时需要联系LCM的driver
工程师以及 LCM vendor
来确认分析,这里不再详细说明。
&* 确认SurfaceFlinger的状态,用于审查SurfaceFlinger的行为是否正常,对应的Thread是否能够正常工作,我司已经在SurfaceFlinger里面导入了Watchdog机制,审查SurfaceFlinger是否有卡住的情况,对应在main
log里面会打印如:&
&[SF-WD]detect SF maybe hang!!!&
这样的LOG,并且会纪录卡顿的时机,如果持续卡顿,毫无疑问, SurfaceFlinger已经卡住,此时就要分析对应的backtrace以及
*SurfaceFlinger 的线程情况在不同的版本上变化比较大,最直接的方式是审查它binder thread情况,以及Event
Loop的执行情况。 binderthread和 system server情况一致,不再详细说明。
Event Loop在JB
以及KK上都不相同,这里分别说明。
&在JB以前的版本,SurfaceFlinger的Event
Loop使用的是普通的pthread控制,并且SurfaceFlinger的第一个Thread
在执行SurfaceFlinger
的初始化后,转换为了binder thread。而Event Loop的thread
是新起的 &SurfaceFlinger& thread。对应的正常backtrace是:
图片: surfaceflinger-event-loop-beforce-jb.png
&在JB版本,SurfaceFlinger的Event
Loop换成了Message Queue-Looper,对应的backtrace是:
图片: surfaceflinger-event-loop-jb.png
&在KK版本,SurfaceFlinger的第一个thread
直接作为了Event Loop thread,对应的backtrace是:
图片: surfaceflinger-event-loop-kk.png
&然后再根据SurfaceFlinger的代码逻辑,以及backtrace的lock
情况进行审查分析。
前面已经提到,无场景分成两类
* 已经重启过的手机
& 死机现场已经不复存在,但手机还没有刷机,可以从手机中抓取已经存在的资讯来分析。
&&*仅仅一些LOG或者其他的资讯
& 需要从这些LOG或者资讯中猜测,当时手机的状态,以及可能死机的原因。
&&对于前者,如同法医解剖逝者遗体,分析可能的死亡原因。而对于后者,就相当于警察叔叔对一些曾年旧案的考证,挖掘与分析,难度可想而知。
为了能够更好更快的分析死机问题,通常我们都强烈建议保存好现场,如果一些特殊环境下无法保存现场,那么就要求测试工程师详细的纪录当时现场环境,包括但不限于下面的资讯:
* 发现死机的时间
--- 如果是发现时,感觉机器早已经死机,也请说明
--- 如有截图,拍照,可以从图像上先获取
&* 复现手法,操作的流程,当时环境
--- 强调在正常使用到死机过程中的操作。
--- 环境状态通常包括温度,湿度,网络信号状况。
--- 复现流程的视频
&* 复现手机情况
--- 复现的软件版本:版本号?
--- 外部设备情况:有插入SD卡?耳机?SIM
--- 软件开启情况:&&开启蓝牙? WIFI?数据服务?GPS?
&*复现的概率
--- 多少台手机做过测试,多少台手机可以复现。
--- 前后多少个版本可以复现,从哪个版本开始可以复现。
&其中死机的时间点至关重要,需要现场的工程师一定要比较精确的纪录。
* 确认hang机时间,和当时是否已经死机至关重要
* 如果当时kernel已经异常,mobile log无法抓取log,那么log的价&#20540;大打折扣。
* 反过来如果当时mobile log还在继续,说明至少kernel整体功能正常,先分析android上层的情况。
* 从LOG中分析SystemServer,&Surfaceflinger行为是否正常,是否有Lock住。
* 查看System Server中关键Service
执行情况,如AMS, WMS,
PowerManagerService, WindowManagerPolicy。
* 观测AMS是比较快速的方法,因为AMS工作时,会使用到很多其他Service的Lock,比如broadcast,
start activity, start service。通常一旦system server有卡住,则AMS
也会卡住,反过来如果AMS
没有卡住,那么通常就意味着systemserver没有直接卡住。
* 查看Surfaceflinger,先查sf-wd,看看是否surfaceflinger是否已经卡住,然后再追查fps情况,HWComposer等情况。
* 查看Power Key行为来确认上下通路是否正常,一般人看到死机,通常会去按一下Power Key来确认是否死机。
* 查看Binder信息,看看Systemserver,
Surfaceflinger等的IPC
按Power Key 分析
因为死机,一般人都会习惯性的按Power key来查看是否可以恢复,而按Power Key的处理流程,涉及从Kernel
=& Input System =& System Server =& SurfaceFlinger等的整个流程,我们可以观察这个流程来查看hang机情况。
* KPDreceives Interrupt and generate Power Key
图片: power-key-1。png
* Systemserver receives Key and call set_screen_state
图片: power-key-2。png
* PowerState Update:& request_suspend_state
图片: power-key-3.png
* Setscreen on:& mt65xx_leds_set_cust
图片: power-key-4.png
&通过审查每一个阶段流程,确认可能的hang机点。注意的是不同的版本可能有所不同,可以先用正常的机器复现一次后比对。
死机Log 分析, trace 辅助
* 如果有提供/data/anr下的trace,或者相关的db文件。在确认死机的时间下,check
trace对应的时间点,如果时间在死机或者hang机后,则是一份非常有价&#20540;的trace。通常查“-----”or&“pid”
* 借机审查system server, surfaceflinger的状况。
* 如果/data/anr下有标准full_traces_xx即标柱这个backtrace是
SWT 产生的宝贵backtrace,里面一定有system server等的backtrace。
&通常情况下,依靠Log可以找到对应的异常模块,但无法找出根本原因。需要依赖更多的信息来debug确认,所以针对这种情况,我们需要让测试人员抓出更多的信息来分析。
建议使用下面脚本抓取资讯:
@echo &Pull important informationfrom hang phone, written by Yanghui Li&
adb devices
@echo &attach sdcard/mtklog&
adb pull /sdcard/mtklog mtklog/
&@echo “attach sdcard2/mtklog”
adb pull /sdcard2/mtklog mtklog/sdcard2
&@echo &attach trace&
adb pull /data/anr mtklog/anr
@echo &attach rtt dump forsurfaceflinger&
adb pull /data/rtt_dump*&mtklog/sf_dump
adb pull /data/anr/sf_rtt mtklog/sf_rtt_1
@echo &attach data aee db&
adb pull /data/aee_exp mtklog/data_aee_exp
@echo &attach data mobilelog&
adb pull /data/mobilelogmtklog/data_mobilelog
&@echo &attach NE core&
adb pull /data/core mtklog/data_core
&@echo &attach tombstones&
adb pull /data/tombstonesmtklog/tombstones
&@echo “attach phone state”
adb shell ps -t& mtklog/ps.txt
adb shell top -t -m 5 -n 3 & mtklog/top.txt
adb shell service list& &&mtklog/serviceList.txt
adb shell cat /proc/meminfo &mtklog/meminfo
adb shell cat /proc/buddyinfo &mtklog/buddyinfo
adb shell procrank & mtklog/procrank.txt
adb shell cat proc/sched_debug &mtklog/sched_debug.txt
adb shell cat proc/interrupts &mtklog/interrupts.txt
adb shell dumpstate & mtklog/dumpstate.txt
@echo &finish.&
adb devices
@echo&抓出sdcard/mtklog&
adb pull/sdcard/mtklog mtklog/
&@echo&抓出trace&
adb pull/data/anr mtklog/anr
&@echo&抓出data aee db&
adb pull/data/aee_exp mtklog/data_aee_exp
&@echo&抓出data mobilelog&
adb pull/data/mobilelog mtklog/data_mobilelog
&@echo&抓出NE core&
adb pull/data/core mtklog/data_core
&@echo&抓出tombstones&
adb pull/data/tombstones mtklog/tombstones
&@echo&抓sf rtt&
adb pull/data/rtt_dump* mtklog/sf_rtt
adb pull/data/anr/sf_rtt mtklog/sf_rtt_1
&@echo&完成&
应当说针对不同的场景,死机和重启意义不一样。
对于普通用户来说,死机的危害性和重要性远大于重启。死机意味着机器在很长一段时间内机器都运行不正常,不能使用。危害性仅次于不能开机。重启很多时候用户都无法感知到,除非当时正在操作手机,并且通常很快就可以恢复。所以在USER版本中,我们要尽可能的把死机转换成重启。
对于开发者来说,重要的是解决问题,通常把死机转换成重启,为了规避一些未知因素,通常抓取的资讯比较少,难以直接分析问题。而如果有死机的现场,分析起来就相对容易得多。
所以针对ENG版本,我们建议不要把死机转换成重启。针对USER版本,尽可能的把死机转换成重启。
死机转换成重启的通用手段就是Watchdog机制,通过watchdog监测系统执行情况,一旦发生watchdog
timeout,则做相应的异常处理。通常对于严重的情况,就是重启系统。
&在android中有两个最为重要的Watchdog机制,一个是System
Server内部的Watchdog,用于监测System Server重要Thread
是否正常,关键Lock是否可以快速获取。一旦出现故障,则快速重启android上层。另外一个就是整个系统的Watchdog,这个依赖于不同平台厂商的实现,对于MTK平台来说,大体的做法是每一个cpu
core对应一个Watchdog Thread [wdtk-X],周期性(20s)的去写RGUregister,而RGUregister的timeout
时间是<span style="color:#s,即如果出现一个core的watchdog
thread没有按时踢狗,那么就会触发一个timeout的FIQ,产生一个KE引发系统完整重启。
&MTK 在KK以后的平台,又做了hangmonitor机制,
system server的watchdog thread周期性的踢kernel中的一个计时器,并设定下一次踢狗的时间,如果在设定的时间内没有踢狗,即意味着system
server的watchdog
本身可能卡住,那么hang monitor机制就会自己触发一个HWT,引发系统完整重启。
当然并非所有的死机问题都能转换成重启。
HWHang&&&&&&&&&&&&&&&&&&&&&&&&&&[maybe]
IRQ Disable & run longtime&&&&&& [After ICS Reboot, GB Hang]
SoftIRQ run longtime&&&&&&&&&&&&[Reboot]
Preempt Disable longtime&&&&&&&& [Reboot]
RT Thread busy[RT &99]&&&&&&&&&& [Hang or Hanglong time then reboot]
Kernel ModuleHang&&&&&&&&&&&&&&&[maybe]
---- Not block watchdog thread reboot.
Native ModuleHang&&&&&&&&&&&&&&&[maybe]
---- Not block watchdog thread reboot.
SurfaceFlingerHang&&&&&&&&&&&&&&[GB reboot, ICS/JB Hang, KK Hang long time then reboot]&
Display subsystemHang&&&&&&&&&&& [Hang]
LCMHang&&&&&&&&&&&&&&&&&&&&&&&&&[Hang]
Input DriverFail&&&&&&&&&&&&&&&&[Hang]
Input SystemHang&&&&&&&&&&&&&&&&[GB, ICS Hang and JB, KK Reboot]
WindowManagerPolicyHang&&&&&&&&& [Maybe]
---- Need check the serverthread state
System serverdeadlock&&&&&&&&&&&[Reboot]
System server logicabnormal&&&&& [Maybe]
Surfaceflinger logic abnormal&&&&[Maybe]
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:543042次
积分:6185
积分:6185
排名:第4019名
原创:80篇
转载:83篇
评论:267条
(1)(1)(1)(1)(1)(1)(2)(1)(2)(2)(3)(2)(3)(2)(1)(1)(1)(1)(2)(1)(3)(1)(4)(7)(1)(3)(2)(2)(2)(4)(1)(1)(1)(1)(1)(2)(2)(1)(6)(1)(4)(1)(1)(2)(1)(2)(8)(1)(1)(2)(3)(8)(1)(5)(4)(5)(2)(1)(4)(3)(3)(3)(3)(5)(1)(6)(2)(5)

我要回帖

更多关于 android 重启问题 的文章

 

随机推荐