当前位置: 首页 > news >正文

Android 死机问题学习笔记

5b05f3cf74e42cf9b04a8d46655ac572.gif

和你一起终身学习,这里是程序员Android

经典好文推荐,通过阅读本文,您将收获以下知识点:

一、死机系统简图
二、死机的可能原因
三、死机问题需要分析哪些数据
四 、Java Backtrace 分析
五、常见 Java backtrace 举例
六、Native Backtrace
七、Kernel Backtrace
八、几种典型的异常情况

一、死机系统简图

当用户对手机进行操作时, 对应的数据流将是下面一个概括的流程图.

7e30668cc43e52ff6b1edcbdd46611ee.jpeg

  • HW 如传感器, 触摸屏(TP), 物理按键(KP)等感知到用户操作后,触发相关的中断(ISR) 传递给Kernel, Kernel 相关的driver 对这些ISR 进行处理后,转化成标准的InputEvent.

  • User Space 的System Server 中的Input System 则持续监听Kernel 传递上来的原始InputEvent, 对其进行进一步的处理后, 变成上层APP 可直接处理的Input Event, 如button 点击, 长按, 滑动等等.

  • APP 对相关的事件进行处理后,请求更新相关的逻辑界面,而这个则由System Server 中的WMS 等来负责.

  • 相关的逻辑界面更新后(Z-Window), 则会请求SurfaceFlinger 来产生FrameBuffer 数据, SurfaceFlinger 则会利用GPU 等来计算生成.

  • Display System/Driver 则会将FrameBuffer 中的数据更新显示出来, 这样用户才能感知到他的操作行为.

二、死机的可能原因

原则上上面流程中,每一步出现问题,都可能引发死机问题. 大的方面讲,可以分成 硬件HW 和 软件SW 两个层次, 硬件HW 不在我们的讲诉之内.

1.软件SW 上,死机的原因可以分成两种:

逻辑行为异常

  • 逻辑判断错误

  • 逻辑设计错误

逻辑卡顿(block)

  • 死循环 (Deadloop)

  • 死锁 (Deadlock)

2.从具体的原因上将,可以进一步分成:

(1). Input Driver

  • 无法接收HW 的中ISR,产生原始的InputEvent, 或者产生的InputEvent 异常.

(2). Input System

  • 无法监听Kernel 传递上来的原始InputEvent, 或者转换与传递异常.

(3). System Logic

  • 无法正常响应Input System 传递过来的InputEvent, 或者响应出错.

(4). WMS/Surfaceflinger 行为异常

  • WMS/SF 无法正确的对Z-Window 进行叠加转换

(5). Display System3

  • 无法更新Framebuffer 数据,或者填充的数据错误

(6). LCM Driver

  • 无法将Framebuffer 数据显示在LCM 上

(7). CPU Scheduler/File System/Memory Manager 等Kernel 支撑性模块.

  • 系统支撑性模块无法正常, 导致整个流程都没法正常进行, 如CPU Scheduler 无法正常执行,导致thread 都无法被调度, memory 耗尽导致系统无法快速申请到memory, file system 卡住导致无法进行读写操作等.

3. 对应硬件HW hang, 经常见得的情况有:

  • Power 异常

  • Clock/26M/32K 失效

  • CPU Core 无法启动, 执行异常等.

  • Memory & Memory Controller.

  • Fail IC.

三、死机问题需要分析哪些数据

1. 死机分析数据

俗话说, 巧妇难为无米之炊, 死机分析, 同样需要获取第一手的资料, 方可分析问题. 那么哪些数据可以用来分析死机呢。
大概的讲,可以分成空间数据和时间数据。空间数据,即当时现场环境,如有哪些process 在运行,CPU 的执行情况,memory 的利用情况,以及具体的process 的memory 数据等。 时间数据,即行为上的连续数据,比如某个Process 在一段时间内执行了哪些操作,某段时间内CPU 利用率的变化等。通常时空都是交融的,对应我们抓取资讯时往往也是。

2. 哪些数据可以用来分析.

Backtrace

Backtrace 又分成Java backtrace, Native Backtrace, Kernel Backtrace. 它是分析死机的非常重要的手段,我们可以快速的知道,对应的process/thread 在当时正在执行哪些动作,卡住哪里等。可以非常直观的分析死机现场。

另外还有一类trace 为ftrace/systrace, 除非特别开启, 以及在特定的流程点上添加, 这类trace 往往不是很详尽, 但也具有比较好的参考作用.

系统运行环境

客观的反应系统的执行环境,通常包括如CPU 利用率,Memory 使用情况, Storage 剩余情况等。这些资料也非常重要,比如可以快速的知道,当时是否有Process 在疯狂的执行,当时是不是处于严重的low memory 情况, Storage 是否有耗尽的情况发生等。

程序执行环境

客观的反应当时某个程序(Kernel 也可以看成一个程序)的执行现场, 此类资讯通常包括如process 的coredump, java heap prof, kernel 的memory dump 等。完整的执行环境,我们可以快速的知道当时具体的变量的值,寄存器值等,可以精细的分析问题。

其他的一些资讯

这些资讯相对来说,比较零散了,如通常的LOG, 一些debug 命令的结果, JTAG & CVD 的数据等。

四 、Backtrace 分析

1. Java Backtrace

从Java Backtrace, 我们可以知道当时Process 的虚拟机执行状态. Java Backtrace 依靠SignalCatcher 来抓取.
Google default: SignalCatcher catchs SIGQUIT(3), and then print the java backtrace to /data/anr/trace.txt
MTK Enhance: SignalCatcher catchs SIGSTKFLT(16), and then print the java backtrace to /data/anr/mtktrace.txt( 仅仅 Android ICS 4.0 <-> Android M 6.0版本)
You can update system properties dalvik.vm.stack-trace-file to Change the address, default is /data/anr/traces.txt

1.1 抓取的方式

  • 在ENG Build 中

adb remount
adb shell chmod 0777 data/anr
adb shell kill -3 pid
adb pull /data/anr
  • 在User Build 中

没有root 权限的情况下,只能直接pull 已经存在的backtrace.

adb pull /data/anr
  • 你可以尝试直接使用下面的脚本一次性抓取

adb remount
adb shell chmod 0777 data/anr
adb shell ps
@echo off
set processid=
set /p processid=Please Input process id:
@echo on
adb shell kill -3 %processid%
@echo off
ping -n 8 127.0.0.1>nul
@echo on
adb pull data/anr/traces.txt trace-%processid%.txt
pause

1.2 JavaBacktrace 解析

Android 比较新的版本的java backtrace, 除了直接的thread backtrace 之外, 同时也会把ART 的一些基本状态也打印出来, 比较方便观察ART 的基本状态, 比如:

----- pid 1051 at 2018-09-29 23:23:52 -----
Cmd line: system_server
Build fingerprint: 'XXXXX/A73/A73:8.1.0/O11019/1537977601:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=5413 post zygote classes=6049
Intern table: 61702 strong; 12632 weak
JNI: CheckJNI is off; globals=10050 (plus 1015 weak)
Libraries: /system/lib64/libandroid.so /system/lib64/libandroid_servers.so /system/lib64/libcompiler_rt.so /system/lib64/libdcfdecoderjni.so /system/lib64/libjavacrypto.so /system/lib64/libjnigraphics.so /system/lib64/libmedia_jni.so /system/lib64/libmediatek_exceptionlog.so /system/lib64/libperfframeinfo_jni.so /system/lib64/librutils.so /system/lib64/libsoundpool.so /system/lib64/libwebviewchromium_loader.so /system/lib64/libwifi-service.so /vendor/lib64/libnativecheck-jni.so libjavacore.so libopenjdk.so (17)
Heap: 9% free, 80MB/89MB; 1893251 objects
Dumping cumulative Gc timings
Start Dumping histograms for 12601 iterations for concurrent copying
ProcessMarkStack: Sum: 3760.617s 99% C.I. 35.990ms-1218.784ms Avg: 298.438ms Max: 14617.568ms
ScanImmuneSpaces: Sum: 216.241s 99% C.I. 2.719ms-110.340ms Avg: 17.160ms Max: 1644.161ms
FlipOtherThreads: Sum: 136.969s 99% C.I. 0.517ms-174.411ms Avg: 10.869ms Max: 5585.050ms
VisitConcurrentRoots: Sum: 119.937s 99% C.I. 1.928ms-50.934ms Avg: 9.518ms Max: 1356.509ms
ClearFromSpace: Sum: 66.775s 99% C.I. 0.168ms-21.473ms Avg: 5.299ms Max: 118.068ms
SweepSystemWeaks: Sum: 58.215s 99% C.I. 0.196ms-19.387ms Avg: 4.619ms Max: 342.553ms
GrayAllDirtyImmuneObjects: Sum: 57.570s 99% C.I. 0.133ms-123.041ms Avg: 4.568ms Max: 2010.547ms
ForwardSoftReferences: Sum: 37.474s 99% C.I. 0.037ms-13.834ms Avg: 2.973ms Max: 118.213ms
EnqueueFinalizerReferences: Sum: 30.905s 99% C.I. 0.094ms-22.239ms Avg: 2.452ms Max: 248.969ms
MarkingPhase: Sum: 24.277s 99% C.I. 0.257ms-51.155ms Avg: 1.926ms Max: 3743.053ms
VisitNonThreadRoots: Sum: 23.507s 99% C.I. 0.065ms-15.260ms Avg: 1.865ms Max: 190.694ms
ProcessReferences: Sum: 17.221s 99% C.I. 9.019us-4689.544us Avg: 683.321us Max: 94215us
EmptyRBMarkBitStack: Sum: 15.343s 99% C.I. 0.026ms-13.119ms Avg: 1.217ms Max: 145.672ms
ThreadListFlip: Sum: 10.730s 99% C.I. 128.387us-25549.046us Avg: 851.524us Max: 1555533us
InitializePhase: Sum: 7.689s 99% C.I. 125us-9536.627us Avg: 610.256us Max: 434902us
FlipThreadRoots: Sum: 4.346s 99% C.I. 16.387us-13773.217us Avg: 344.930us Max: 241943us
RecordFree: Sum: 4.106s 99% C.I. 95us-2474.875us Avg: 325.895us Max: 31656us
SweepAllocSpace: Sum: 2.746s 99% C.I. 32.035us-6375.082us Avg: 217.946us Max: 397272us
SweepLargeObjects: Sum: 2.611s 99% C.I. 10us-1976.352us Avg: 207.248us Max: 36205us
ResumeOtherThreads: Sum: 2.453s 99% C.I. 8.115us-8079.599us Avg: 194.712us Max: 86018us
ReclaimPhase: Sum: 2.086s 99% C.I. 9us-4266.285us Avg: 165.567us Max: 155093us
ResumeRunnableThreads: Sum: 1.759s 99% C.I. 8.063us-2676.218us Avg: 139.607us Max: 87029us
MarkStackAsLive: Sum: 782.752ms 99% C.I. 5us-799.362us Avg: 62.118us Max: 41297us
MarkZygoteLargeObjects: Sum: 741.028ms 99% C.I. 12us-899.899us Avg: 58.807us Max: 24679us
(Paused)GrayAllNewlyDirtyImmuneObjects: Sum: 651.153ms 99% C.I. 12us-373.754us Avg: 51.674us Max: 14328us
ClearRegionSpaceCards: Sum: 412.842ms 99% C.I. 8us-199.633us Avg: 32.762us Max: 16297us
(Paused)SetFromSpace: Sum: 357.553ms 99% C.I. 3us-286.340us Avg: 28.374us Max: 14500us
SwapBitmaps: Sum: 151.902ms 99% C.I. 4us-99.729us Avg: 12.054us Max: 5447us
Sweep: Sum: 110.635ms 99% C.I. 2us-49.924us Avg: 8.779us Max: 1087us
(Paused)FlipCallback: Sum: 105.455ms 99% C.I. 2us-99.800us Avg: 8.368us Max: 8433us
(Paused)ClearCards: Sum: 89.377ms 99% C.I. 1000ns-199016ns Avg: 295ns Max: 17545000ns
UnBindBitmaps: Sum: 17.838ms 99% C.I. 0.250us-49.765us Avg: 1.415us Max: 1516us
Done Dumping histograms
concurrent copying paused: Sum: 10.999s 99% C.I. 320.432us-63766.026us Avg: 872.888us Max: 1214342us
concurrent copying total time: 4607.007s mean time: 365.606ms
concurrent copying freed: 4075114399 objects with total size 152GB
concurrent copying throughput: 884547/s / 33MB/s
Cumulative bytes moved 115136403208
Cumulative objects moved 2160415247
Total time spent in GC: 4607.007s
Mean GC size throughput: 32MB/s
Mean GC object throughput: 884504 objects/s
Total number of allocations 4076810306
Total bytes allocated 145GB
Total bytes freed 145GB
Free memory 8MB
Free memory until GC 8MB
Free memory until OOME 431MB
Total memory 89MB
Max memory 512MB
Zygote space size 652KB
Total mutator paused time: 10.999s
Total time waiting for GC to complete: 71.458s
Total GC count: 12601
Total GC time: 4607.007s
Total blocking GC count: 3305
Total blocking GC time: 1302.402s
Histogram of GC count per 10000 ms: 0:11034,1:7128,2:1807,3:417,4:87,5:21,6:6,7:3,8:2,9:2,11:2,12:2,17:1
Histogram of blocking GC count per 10000 ms: 0:17706,1:2336,2:443,3:26,4:1
Registered native bytes allocated: 57354982
/system/framework/oat/arm64/com.android.location.provider.odex: speed
/system/priv-app/FusedLocation/oat/arm64/FusedLocation.odex: speed
/system/priv-app/Telecom/oat/arm64/Telecom.odex: speed
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/com.coloros.statistics.odex: quicken
/system/priv-app/SettingsProvider/oat/arm64/SettingsProvider.odex: speed
/system/framework/oat/arm64/services.odex: speed
/system/framework/oat/arm64/ethernet-service.odex: speed
/system/framework/oat/arm64/wifi-service.odex: speed
/system/framework/oat/arm64/com.android.location.provider.odex: speed
/system/framework/oat/arm64/mediatek-services.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/data/dalvik-cache/arm64/vendor@app@LPPeService@LPPeService.apk@classes.dex: quicken
/system/framework/oat/arm64/mediatek-framework-net.odex: quicken
/data/dalvik-cache/arm64/vendor@app@NlpService@NlpService.apk@classes.dex: quicken
Running non JIT

对于死机情况来说, 我们比较关注java heap 的memory 使用与GC 情况:

Heap: 9% free, 80MB/89MB; 1893251 objects 
Free memory 8MB
Free memory until GC 8MB
Free memory until OOME 431MB
Total memory 89MB
Max memory 512MB

==》 可以简单知道是否有java 层的object leaks, 以及触发GC 的情况

除去这些之后, 我们再来看java backtrace 的具体资讯.

下面是一小段system server 的java backtrace 的开始

----- pid 682 at 2014-07-30 18:04:53 -----
Cmd line: system_server
JNI: CheckJNI is off; workarounds are off; pins=4; globals=1484 (plus 50 weak)
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)  <== 只有老版本有.
"main" prio=5 tid=1 NATIVE| group="main" sCount=1 dsCount=0 obj=0x4193fde0 self=0x418538f8| sysTid=682 nice=-2 sched=0/0 cgrp=apps handle=1074835940| state=S schedstat=( 47858718206 26265263191 44902 ) utm=4074 stm=711 core=0at android.os.MessageQueue.nativePollOnce(Native Method)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(Native Method)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(Native Method)

我们一行一行来解析.

  • 0# 最开始是 -----PID at Time 然后接着 Cmd line: process name

  • 1# the backtrace header: dvm thread :“DALVIK THREADS:”
    新版本中有包括 thread 量, 如: "DALVIK THREADS (214):" 可以观察到是否有java thread leaks.

  • 2# Global DVM mutex value: if 0 unlock, else lock
    tll: threadListLock,
    tsl: threadSuspendLock,
    tscl: threadSuspendCountLock
    ghl: gcHeapLock

(mutexes: tll=0 tsl=0 tscl=0 ghl=0)

  • 3# thread name, java thread Priority, [daemon], DVM thread id, DVM thread status.
    "main" -> main thread -> activity thread
    prio -> java thread priority default is 5, (nice =0, linux thread priority 120), domain is [1,10]
    DVM thread id, NOT linux thread id
    DVM thread Status:
    ZOMBIE, RUNNABLE, TIMED_WAIT, MONITOR, WAIT, INITALIZING,STARTING, NATIVE, VMWAIT, SUSPENDED,UNKNOWN

"main" prio=5 tid=1 NATIVE

  • 4# DVM thread status
    group: default is “main”
    Compiler,JDWP,Signal Catcher,GC,FinalizerWatchdogDaemon,FinalizerDaemon,ReferenceQueueDaemon are system group
    sCount: thread suspend count
    dsCount: thread dbg suspend count
    obj: thread obj address
    Sef: thread point address

group="main" sCount=1 dsCount=0 obj=0x4193fde0 self=0x418538f8

  • 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/0 cgrp=apps handle=1074835940

  • 6 CPU Sched stat

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=( 47858718206 26265263191 44902 ) utm=4074 stm=711 core=0

五、常见 Java backtrace 举例

1.ActivityThread 正常状态/ActivityThread Normal Case

Message Queue is empty, and thread wait for next message."main" prio=5 tid=1 NATIVE| group="main" sCount=1 dsCount=0 obj=0x4193fde0 self=0x418538f8| sysTid=11559 nice=0 sched=0/0 cgrp=apps/bg_non_interactive handle=1074835940| state=S schedstat=( 2397315020 9177261498 7975 ) utm=100 stm=139 core=1at android.os.MessageQueue.nativePollOnce(Native Method)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(Native Method)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(Native Method)

2.Java Backtrace Monitor case

Synchronized Lock: 等待同步锁时的backtrace."AnrMonitorThread" prio=5 tid=24 MONITOR| group="main" sCount=1 dsCount=0 obj=0x41fd80c8 self=0x551ac808| sysTid=711 nice=0 sched=0/0 cgrp=apps handle=1356369328| state=S schedstat=( 8265377638 4744771625 6892 ) utm=160 stm=666 core=0at com.android.server.am.ANRManager$AnrDumpMgr.dumpAnrDebugInfoLocked(SourceFile:~832)- waiting to lock <0x42838968> (a com.android.server.am.ANRManager$AnrDumpRecord) held by tid=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)

3.执行JNI code 未返回,状态是native 的情况

"WifiP2pService" prio=5 tid=37 NATIVE| group="main" sCount=1 dsCount=0 obj=0x427a9910 self=0x55f088d8| sysTid=734 nice=0 sched=0/0 cgrp=apps handle=1443230288| state=S schedstat=( 91121772 135245305 170 ) utm=7 stm=2 core=1#00  pc 00032700  /system/lib/libc.so (epoll_wait+12)#01  pc 000105e3  /system/lib/libutils.so (android::Looper::pollInner(int)+94)#02  pc 00010811  /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+92)#03  pc 0006c96d  /system/lib/libandroid_runtime.so (android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+22)#04  pc 0001eacc  /system/lib/libdvm.so (dvmPlatformInvoke+112)#05  pc 0004fed9  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)#06  pc 00027ea8  /system/lib/libdvm.so#07  pc 0002f4b0  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)#08  pc 0002c994  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+188)#09  pc 000632a5  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+340)#10  pc 000632c9  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)#11  pc 00057961  /system/lib/libdvm.so#12  pc 0000dd40  /system/lib/libc.so (__thread_entry+72)at android.os.MessageQueue.nativePollOnce(Native Method)at android.os.MessageQueue.next(MessageQueue.java:138)at android.os.Looper.loop(Looper.java:150)at android.os.HandlerThread.run(HandlerThread.java:61)

4. 执行object.wait 等待状态

"AsyncTask #1" prio=5 tid=33 WAIT| group="main" sCount=1 dsCount=0 obj=0x427a8480 self=0x56036b40| sysTid=733 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1443076000| state=S schedstat=( 1941480839 10140523154 4229 ) utm=119 stm=75 core=0at java.lang.Object.wait(Native Method)- 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)

5. Suspend 状态,通常表明是抓取backtrace 时,当时还正在执行java code, 被强制suspend 的情况

"FileObserver" prio=5 tid=23 SUSPENDED| group="main" sCount=1 dsCount=0 obj=0x41fd1dc8 self=0x551abda0| sysTid=710 nice=0 sched=0/0 cgrp=apps handle=1427817920| state=S schedstat=( 130152222 399783851 383 ) utm=9 stm=4 core=0#00  pc 000329f8  /system/lib/libc.so (__futex_syscall3+8)#01  pc 000108cc  /system/lib/libc.so (__pthread_cond_timedwait_relative+48)#02  pc 0001092c  /system/lib/libc.so (__pthread_cond_timedwait+64)#03  pc 00055a93  /system/lib/libdvm.so#04  pc 0005614d  /system/lib/libdvm.so (dvmChangeStatus(Thread*, ThreadStatus)+34)#05  pc 0004ae7f  /system/lib/libdvm.so#06  pc 0004e353  /system/lib/libdvm.so#07  pc 000518d5  /system/lib/libandroid_runtime.so#08  pc 0008af9f  /system/lib/libandroid_runtime.so#09  pc 0001eacc  /system/lib/libdvm.so (dvmPlatformInvoke+112)#10  pc 0004fed9  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)#11  pc 00027ea8  /system/lib/libdvm.so#12  pc 0002f4b0  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)#13  pc 0002c994  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+188)#14  pc 000632a5  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+340)#15  pc 000632c9  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)#16  pc 00057961  /system/lib/libdvm.so#17  pc 0000dd40  /system/lib/libc.so (__thread_entry+72)at android.os.FileObserver$ObserverThread.observe(Native Method)at android.os.FileObserver$ObserverThread.run(FileObserver.java:88)

六、Native Backtrace

1. Native Backtrace 抓取方式

1.利用debuggerd 抓取

MTK 已经制作了一个利用debuggerd 抓取Native backtrace 的tool RTT(Runtime Trace), 对应的执行命令是:

rtt built timestamp (Apr 18 2014 15:36:21)
USAGE : rtt [-h] -f function -p pid [-t tid]-f funcion : current support functions:bt  (Backtrace function)-p pid     : pid to trace-t tid     : tid to trace-n name    : process name to trace-h         : help menu

这个rtt 目前只有在eng/userdebug 中可以使用; 另外大家可以使用 google 默认的debuggerd 来抓取:

adb shell debuggerd -b pid

注意的是这些都是要依赖debuggerd 的流程正常, 以及对应抓取process 的debuggerd_signal_handler 行为正常, 否则抓取不到.

2. 添加代码直接抓取

Google 默认提供了CallStack API, 请参考

system/core/include/libutils/CallStack.h 
system/core/libutils/CallStack.cpp

可快速打印单个线程的backtrace.

2.解析Native Backtrace

你可以使用GDB, 或者addr2line 等 tool 来解析抓回的Native Backtrace, 从而知道当时正在执行的native 代码.
如addr2line 执行

arm-linux-androideabi-addr2line  -f -C -e symbols address

七、Kernel Backtrace

1.Kernel Backtrace 抓取方式

1 运行时抓取

  • AEE/RTT 工具

  • Proc System

cat proc/pid/task/tid/stack
  • Sysrq-trigger

adb shell cat proc/kmsg > kmsg.txtadb shell "echo 8 > proc/sys/kernel/printk“ //修改printk logleveladb shell "echo t > /proc/sysrq-trigger“ //打印所有的backtraceadb shell "echo w > /proc/sysrq-trigger“//打印'-D' status 'D' 的 process
  • KDB

Long press volume UP and DOWN more then 10sbtp             <pid>                Display stack for process <pid>bta             [DRSTCZEUIMA]        Display stack all processesbtc                                  Backtrace current process on each cpubtt             <vaddr>              Backtrace process given its struct task add

2.添加代码直接抓取

#include <linux/sched.h>当前thread:  dump_stack();其他thread:  show_stack(task, NULL);

3. Process/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 (disk sleep), T (stopped), Z (zombie) 等就要认真审查.

八、几种典型的异常情况

1. Deadlock

下面这个case 可以看到PowerManagerService, ActivityManager, WindowManager 相互之间发生deadlock.

"PowerManagerService" prio=5 tid=25 MONITOR| group="main" sCount=1 dsCount=0 obj=0x42bae270 self=0x6525d5c0| sysTid=913 nice=0 sched=0/0 cgrp=apps handle=1696964440| state=S schedstat=( 5088939411 10237027338 34016 ) utm=232 stm=276 core=2at com.android.server.am.ActivityManagerService.bindService(ActivityManagerService.java:~14079)- waiting to lock <0x42aa0f78> (a com.android.server.am.ActivityManagerService) held by tid=16 (ActivityManager)at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1665)at android.app.ContextImpl.bindService(ContextImpl.java:1648)at com.android.server.power.PowerManagerService.bindSmartStandByService(PowerManagerService.java:4090)at com.android.server.power.PowerManagerService.handleSmartStandBySettingChangedLocked(PowerManagerService.java:4144)at com.android.server.power.PowerManagerService.access$5600(PowerManagerService.java:102)at com.android.server.power.PowerManagerService$SmartStandBySettingObserver.onChange(PowerManagerService.java:4132)at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:181)at android.os.Handler.handleCallback(Handler.java:809)at android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:139)at android.os.HandlerThread.run(HandlerThread.java:58)"ActivityManager" prio=5 tid=16 MONITOR| group="main" sCount=1 dsCount=0 obj=0x42aa0d08 self=0x649166b0| sysTid=902 nice=-2 sched=0/0 cgrp=apps handle=1687251744| state=S schedstat=( 39360881460 25703061063 69675 ) utm=1544 stm=2392 core=2at com.android.server.wm.WindowManagerService.setAppVisibility(WindowManagerService.java:~4783)- waiting to lock <0x42d17590> (a java.util.HashMap) held by tid=12 (WindowManager)at com.android.server.am.ActivityStack.stopActivityLocked(ActivityStack.java:2432)at com.android.server.am.ActivityStackSupervisor.activityIdleInternalLocked(ActivityStackSupervisor.java:2103)at com.android.server.am.ActivityStackSupervisor$ActivityStackSupervisorHandler.activityIdleInternal(ActivityStackSupervisor.java:2914)at com.android.server.am.ActivityStackSupervisor$ActivityStackSupervisorHandler.handleMessage(ActivityStackSupervisor.java:2921)at android.os.Handler.dispatchMessage(Handler.java:110)at android.os.Looper.loop(Looper.java:147)at com.android.server.am.ActivityManagerService$AThread.run(ActivityManagerService.java:2112)"WindowManager" prio=5 tid=12 MONITOR| group="main" sCount=1 dsCount=0 obj=0x42a92550 self=0x6491dd48| sysTid=898 nice=-4 sched=0/0 cgrp=apps handle=1687201104| state=S schedstat=( 60734070955 41987172579 219755 ) utm=4659 stm=1414 core=1at com.android.server.power.PowerManagerService.setScreenBrightnessOverrideFromWindowManagerInternal(PowerManagerService.java:~3207)- waiting to lock <0x42a95140> (a java.lang.Object) held by tid=25 (PowerManagerService)at com.android.server.power.PowerManagerService.setScreenBrightnessOverrideFromWindowManager(PowerManagerService.java:3196)at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedInner(WindowManagerService.java:9686)at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedLoop(WindowManagerService.java:8923)at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLocked(WindowManagerService.java:8879)at com.android.server.wm.WindowManagerService.access$500(WindowManagerService.java:170)at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:7795)at android.os.Handler.dispatchMessage(Handler.java:110)at android.os.Looper.loop(Looper.java:147)at android.os.HandlerThread.run(HandlerThread.java:58)

2. 执行JNI native code 后一去不复返

"main" prio=5 tid=1 NATIVE| group="main" sCount=1 dsCount=0 obj=0x41bb3d98 self=0x41ba2878| sysTid=814 nice=-2 sched=0/0 cgrp=apps handle=1074389380| state=D schedstat=( 22048890928 19526803112 32612 ) utm=1670 stm=534 core=0(native backtrace unavailable)at android.hardware.SystemSensorManager$BaseEventQueue.nativeDisableSensor(Native Method)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(Native Method)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(Native Method)

===>
KERNEL SPACE BACKTRACE, sysTid=814

[<ffffffff>] 0xffffffff from [<c07e5140>] __schedule+0x3fc/0x950[<c07e4d50>] __schedule+0xc/0x950 from [<c07e57e4>] schedule+0x40/0x80[<c07e57b0>] schedule+0xc/0x80 from [<c07e5ae4>] schedule_preempt_disabled+0x20/0x2c[<c07e5ad0>] schedule_preempt_disabled+0xc/0x2c from [<c07e3c3c>] mutex_lock_nested+0x1b8/0x560[<c07e3a90>] mutex_lock_nested+0xc/0x560 from [<c05667d8>] gsensor_operate+0x1bc/0x2c0[<c0566628>] gsensor_operate+0xc/0x2c0 from [<c0495fa0>] hwmsen_enable+0xa8/0x30c[<c0495f04>] hwmsen_enable+0xc/0x30c from [<c0496500>] hwmsen_unlocked_ioctl+0x2fc/0x528[<c0496210>] hwmsen_unlocked_ioctl+0xc/0x528 from [<c018ad98>] do_vfs_ioctl+0x94/0x5bc[<c018ad10>] do_vfs_ioctl+0xc/0x5bc from [<c018b33c>] sys_ioctl+0x7c/0x8c[<c018b2cc>] sys_ioctl+0xc/0x8c from [<c000e480>] ret_fast_syscall+0x0/0x40[<ffffffff>]  from [<ffffffff>]

参考文献:

【腾讯文档】Android Framework 知识库
https://docs.qq.com/doc/DSXBmSG9VbEROUXF5

友情推荐:

Android 开发干货集锦

至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

4c0e1f6f731caed8cee5e2dc1c78e582.jpeg

点击阅读原文,为大佬点赞!

相关文章:

Android 死机问题学习笔记

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、死机系统简图二、死机的可能原因三、死机问题需要分析哪些数据四 、Java Backtrace 分析五、常见 Java backtrace 举例六、Native Backtrace七、Ke…...

企业内网终端安全无客户端准入控制技术实践

终端无代理/无客户端准入控制技术因其良好的用户体验而倍受创新企业的青睐。无代理/无客户端准入控制技术&#xff0c;顾名思义&#xff0c;是一种在网络中对终端实施访问控制的方法&#xff0c;无需依赖特定的客户端软件。 不同于银行、医院等传统行业的终端准入控制需求&…...

Android 开发代码规范

一. AndroidStudio开发工具规范 使用最新的稳定版本.统一文件的编码格式为utf-8. 清除每个类里面的无效的import导包.代码样式统一,比如&#xff0c;tab缩进4个空格&#xff0c;或者 tab size等如果没有特殊情况使用默认的配置即可。每行字数每行字符数不得超过 160 字符&…...

c语言(函数)

目录 何为函数 库函数 自定义函数 二分查找数组下标 链式访问 函数的声明 函数定义 递归 正向打印数字 打印字符个数 使用临时变量 递归(不使用临时变量) n的阶乘 一般形式 递归 斐波那契数 递归 正常做法 何为函数 在计算机科学中&#xff0c;子程序是一个…...

OPENCV C++(二)直方图+分离颜色通道+画圆画线画矩形

分离RGB彩图颜色通道 也就是把每种分量的亮度图提出来 vector<Mat> channels;split(image1, channels);Mat R channels.at(0);Mat G channels.at(1);Mat B channels.at(2); 这样R,G,B每个图就是这个图的颜色分量图了 图片的克隆&#xff0c;深拷贝&#xff01; Mat…...

SpringBoot(2.7.x)中使用PageHelper

如何在SpringBoot中使用PageHelper 先添加依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.12</version> </dependency>SpringBoot 2.6.x…...

【HarmonyOS】API9网络buffer图片加载

【引言】 HarmonyOS中加载网络图片常用的方法是直接给Image组件添加图片的网络地址&#xff0c;申请网络权限ohos.permission.INTERNET后就可以通过url加载对应的图片了&#xff0c;如HarmonyOS官网中的写法&#xff1a; Image(https://www.example.com/example.JPG) 【问题概…...

【前端实习生备战秋招】—HTML 和 CSS面试题总结(二)

【前端实习生备战秋招】—HTML 和 CSS面试题总结&#xff08;二&#xff09; 1.有哪些方式可以对一个 DOM 设置它的 CSS 样式&#xff1f; 外部样式表&#xff0c;引入一个外部 css 文件内部样式表&#xff0c;将 css 代码放在 <head> 标签内部内联样式&#xff0c;将 c…...

操作系统知识点总结

操作系统知识点总结: 第一章:操作系统概述 1.1操作系统的概念: ​ 操作系统是一种系统软件,与其他系统软件和应用软件不同,它有自己的基本特征。它的四大基本特征也就是并发,共享,虚拟,异步。 1.2操作系统的特征(四大基本特征): 并发: 这里我们要理解什么是并发,什么是…...

(C++) 多线程之生产者消费者问题

文章目录 前言CodeCode运行效果 分解讲解main()class ProducerConsumerProblemproduce()consumer() END 前言 生产者消费者问题_百度百科 (baidu.com) 生产者消费者问题 &#xff08;英语&#xff1a;Producer-consumer problem&#xff09;&#xff0c;也称有限缓冲问题&…...

【C语言学习】逃逸字符(转义字符)

逃逸字符&#xff08;转义字符&#xff09; 1.\" 双引号 \" printf("请分别输入身高的英尺和英寸&#xff0c;""如输入\"5 7\"表示5英尺7英寸:");这里的"\就是双引号的作用&#xff0c;因为在双引号里面直接用双引号无意义&…...

开发手册|Java后端开发规范重点条目整理

Ps&#xff1a;部分熟知的开发规范未收录在本文中&#xff01; 一、编程规约 1.1 命名风格 代码中的命名严禁使用拼音与英文混合的方式 alibaba / taobao / youku / hangzhou 等国际通用的名称可视同英文 类名使用大驼峰的形式命名&#xff0c;例如 UpperCameCase 方法、参数…...

c++11 标准模板(STL)(std::basic_ofstream)(二)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_ifstream : public std::basic_istream<CharT, Traits> 类模板 basic_ifstream 实现文件流上的高层输入操作。它将 std::basic_istrea…...

k8s概念-pv和pvc

回到目录 kubernetes存储卷的分类太丰富了,每种类型都要写相应的接口与参数才行&#xff0c;这就让维护与管理难度加大。 persistenvolume(PV) 是配置好的一段存储(可以是任意类型的存储卷) 也就是说将网络存储共享出来,配置定义成PV。 PersistentVolumeClaim(PVC)是用户pod使…...

python算法指南程序员经典,python算法教程pdf百度云

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;你也能看懂的python算法书 pdf&#xff0c;python算法教程这本书怎么样&#xff0c;现在让我们一起来看看吧&#xff01; 给大家带来的一篇关于算法相关的电子书资源&#xff0c;介绍了关于算法、详解、算法基础方面的内…...

微服务使用步骤

Maven的依赖冲突解决方案&#xff1a; 路径最短原则配置优先原则破坏规则则使用排除 SpringBoot场景启动器starter的开发流程 c3p0-spring-boot-starter自定义场景启动器test-c3p0调用自定义场景启动器SpringBoot自动装配SpringBoot应用启动原理nacos服务治理 安装 启动bin/s…...

Ubuntu 23.04 作为系统盘的体验和使用感受

1.为啥主系统装了Ubuntu 由于公司发电脑了&#xff0c;我自己也有一台台式电脑&#xff0c;然后也想去折腾一下Ubuntu&#xff0c;就把自己的笔记本装成Ubuntu系统了&#xff0c; 我使用的是23.04的桌面版&#xff0c;带图形化界面的。我准备换回Windows 11了&#xff08;因为…...

百分点科技跻身中国智慧应急人工智能解决方案市场前三

近日&#xff0c; 全球领先的IT市场研究和咨询公司IDC发布了《中国智慧应急解决方案市场份额&#xff0c;2022》报告&#xff0c;数据显示&#xff0c;2022年中国智慧应急整体市场为104亿元人民币。其中&#xff0c;智慧应急人工智能解决方案子市场备受关注&#xff0c;百分点科…...

vscode如何退出/切换 github 账号

退出/切换 github 账号 左下角点击头像按钮&#xff0c;选择注销&#xff0c;然后再重新登录...

maven发布到中央仓库

创建账号 https://issues.sonatype.org 【第二步】登录申请新项目 右上角点击Create&#xff0c;Project选择第一项&#xff0c;有的时候带不出来第二个New Project&#xff0c;可以再选一次Project的选项。...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...