ANR之进程冻结

285 阅读9分钟

SystemUI子进程处理截屏手势弹窗出现ANR

现象:从下拉中点击截屏,弹出学习截屏的弹窗后,点击界面无效区域,过一会就发生ANR

分析:

  1. Perfetto

image.png

从trace中看到两次点击事件,第一次DOWN和UP分发正常,第二次DOWN和UP分发不正常。第二次iq和oq都正常下降到0,但是wq一直在累积,并且客户端的aq也没有收到输入事件

  1. log

正常log流程


一次motion事件分发

09-20 11:23:14.208 8019 8134 D InputDispatcher: dispatchEventToCurrentInputTargets

准备分发

09-20 11:23:14.208 8019 8134 D InputDispatcher: channel 'c8b6716 ScreenShotLearningDialog (server)' \~ prepareDispatchCycle - flags=FOREGROUND | SPLIT | DISPATCH\_AS\_IS, globalScaleFactor=1.000000, pointerIds=00000000000000000000000000000001

通过socket发送给客户端的窗口ScreenShotLearningDialog,此时oq会减1,wq会加1,mAnrTracker记录当前事件

09-20 11:23:14.208 8019 8134 D InputDispatcher: channel 'c8b6716 ScreenShotLearningDialog (server)' \~ startDispatchCycle

客户端接收输入事件的Looper唤醒消费输入事件

09-20 11:23:14.209 5452 5452 D InputEventReceiver: channel 'c8b6716 ScreenShotLearningDialog (client)' \~ Consuming input events, consumeBatches=false, frameTime=-1

从socket读取到事件

09-20 11:23:14.210 5452 5452 D InputEventReceiver: channel 'c8b6716 ScreenShotLearningDialog (client)' \~ Received motion event.

转换成MotionEvent,分发给java端的InputEventReceiver.dispatchInputEvent

09-20 11:23:14.210 5452 5452 D InputEventReceiver: channel 'c8b6716 ScreenShotLearningDialog (client)' \~ Dispatching input event.

事件处理完成后,java端InputEventReceiver调用finishInputEvent,并通过socket告知InputDispatcher

09-20 11:23:14.227 5452 5452 D InputEventReceiver: channel 'c8b6716 ScreenShotLearningDialog (client)' \~ Finished input event.

InputDispatcher回调handleReceiveCallback,并调用finishDispatchCycleLocked->doDispatchCycleFinishedCommand,wq减1,并且从mAnrTracker中移除

09-20 11:23:14.227 8019 8134 D InputDispatcher: channel 'c8b6716 ScreenShotLearningDialog (server)' \~ finishDispatchCycle - seq=387, handled=true

尝试继续从oq中获取事件继续分发

09-20 11:23:14.227 8019 8134 D InputDispatcher: channel 'c8b6716 ScreenShotLearningDialog (server)' \~ startDispatchCycle

出问题的log


只有system\_server端的log,没有客户端的log,即客户端没有接收到事件

09-20 11:23:28.013 8019 8134 D InputDispatcher: dispatchEventToCurrentInputTargets

09-20 11:23:28.013 8019 8134 D InputDispatcher: channel 'c8b6716 ScreenShotLearningDialog (server)' \~ prepareDispatchCycle - flags=FOREGROUND | SPLIT | DISPATCH\_AS\_IS, globalScaleFactor=1.000000, pointerIds=00000000000000000000000000000001

09-20 11:23:28.013 8019 8134 D InputDispatcher: channel 'c8b6716 ScreenShotLearningDialog (server)' \~ startDispatchCycle

09-20 11:23:32.886 8019 8134 W InputDispatcher: Window c8b6716 ScreenShotLearningDialog (server) is unresponsive: c8b6716 ScreenShotLearningDialog (server) is not responding. Waited 5005ms for MotionEvent(deviceId=5, eventTime=1851103240000, source=TOUCHSCREEN, displayId=0, action=DOWN, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, xCursorPosition=nan, yCursorPosition=nan, pointers=\[0: (147.8, 1040.4)]), policyFlags=0x62000000

09-20 11:23:32.886 8019 8134 W InputDispatcher: Canceling events for c8b6716 ScreenShotLearningDialog (server) because it is unresponsive
  1. anr trace文件

没有看到堆栈信息,进程中对应的线程状态

Subject: Input dispatching timed out (c8b6716 ScreenShotLearningDialog (server) is not responding. Waited 5005ms for MotionEvent(deviceId=5, eventTime=1851103240000, source=TOUCHSCREEN, displayId=0, action=DOWN, actionButton=0x00000000, flags=0x00000000, metaState=0x00000000, buttonState=0x00000000, classification=NONE, edgeFlags=0x00000000, xPrecision=1.0, yPrecision=1.0, xCursorPosition=nan, yCursorPosition=nan, pointers=[0: (147.8, 1040.4)]), policyFlags=0x62000000)
RssHwmKb: 195628
RssKb: 172808
RssAnonKb: 48156
RssShmemKb: 1696
VmSwapKb: 19152
--- CriticalEventLog ---
capacity: 20
timestamp_ms: 1726827812924
window_ms: 300000
----- dumping pid: 5452 at 1856113
libdebuggerd_client: failed to read status response from tombstoned: timeout reached?
----- Waiting Channels: pid 5452 at 2024-09-20 11:23:32.892483187+0100 -----
Cmd line: com.android.systemui:screenshot
sysTid=5452      do_freezer_trap
sysTid=5457      do_freezer_trap
sysTid=5458      do_freezer_trap
sysTid=5459      do_freezer_trap
sysTid=5460      do_freezer_trap
sysTid=5461      do_freezer_trap
sysTid=5462      do_freezer_trap
sysTid=5463      do_freezer_trap
sysTid=5464      do_freezer_trap
sysTid=5465      do_freezer_trap
sysTid=5466      do_freezer_trap
sysTid=5467      do_freezer_trap
sysTid=5471      do_freezer_trap
sysTid=5472      do_freezer_trap
sysTid=5473      do_freezer_trap
sysTid=5474      do_freezer_trap
sysTid=5475      do_freezer_trap
sysTid=5477      do_freezer_trap
sysTid=5481      do_freezer_trap
sysTid=5483      do_freezer_trap
sysTid=5484      do_freezer_trap
sysTid=5485      do_freezer_trap
sysTid=5486      do_freezer_trap
sysTid=5487      do_freezer_trap
sysTid=5488      do_freezer_trap
sysTid=5491      do_freezer_trap
sysTid=5492      do_freezer_trap
sysTid=5493      do_freezer_trap
sysTid=5494      do_freezer_trap
sysTid=5495      do_freezer_trap
sysTid=5496      do_freezer_trap
sysTid=5497      do_freezer_trap
sysTid=5498      do_freezer_trap
sysTid=5500      do_freezer_trap
sysTid=5501      do_freezer_trap
sysTid=5502      do_freezer_trap
sysTid=5503      do_freezer_trap
sysTid=5504      do_freezer_trap
sysTid=5505      do_freezer_trap
sysTid=5507      do_freezer_trap
sysTid=5508      do_freezer_trap
sysTid=5509      do_freezer_trap
sysTid=5510      do_freezer_trap
sysTid=5511      do_freezer_trap
sysTid=5512      do_freezer_trap
sysTid=5513      do_freezer_trap
sysTid=5514      do_freezer_trap
sysTid=5515      do_freezer_trap
sysTid=5516      do_freezer_trap
sysTid=5519      do_freezer_trap
sysTid=5520      do_freezer_trap
sysTid=5521      do_freezer_trap
sysTid=5523      do_freezer_trap
sysTid=5525      do_freezer_trap
----- end 5452 -----
libdebuggerd_client: failed to read status response from tombstoned: Try again
----- Waiting Channels: pid 5452 at 2024-09-20 11:23:42.912211187+0100 -----
Cmd line: com.android.systemui:screenshot
sysTid=5452      do_freezer_trap
sysTid=5457      do_freezer_trap
sysTid=5458      do_freezer_trap
sysTid=5459      do_freezer_trap
sysTid=5460      do_freezer_trap
sysTid=5461      do_freezer_trap
sysTid=5462      do_freezer_trap
sysTid=5463      do_freezer_trap
sysTid=5464      do_freezer_trap
sysTid=5465      do_freezer_trap
sysTid=5466      do_freezer_trap
sysTid=5467      do_freezer_trap
sysTid=5471      do_freezer_trap
sysTid=5472      do_freezer_trap
sysTid=5473      do_freezer_trap
sysTid=5474      do_freezer_trap
sysTid=5475      do_freezer_trap
sysTid=5477      do_freezer_trap
sysTid=5481      do_freezer_trap
sysTid=5483      do_freezer_trap
sysTid=5484      do_freezer_trap
sysTid=5485      do_freezer_trap
sysTid=5486      do_freezer_trap
sysTid=5487      do_freezer_trap
sysTid=5488      do_freezer_trap
sysTid=5491      do_freezer_trap
sysTid=5492      do_freezer_trap
sysTid=5493      do_freezer_trap
sysTid=5494      do_freezer_trap
sysTid=5495      do_freezer_trap
sysTid=5496      do_freezer_trap
sysTid=5497      do_freezer_trap
sysTid=5498      do_freezer_trap
sysTid=5500      do_freezer_trap
sysTid=5501      do_freezer_trap
sysTid=5502      do_freezer_trap
sysTid=5503      do_freezer_trap
sysTid=5504      do_freezer_trap
sysTid=5505      do_freezer_trap
sysTid=5507      do_freezer_trap
sysTid=5508      do_freezer_trap
sysTid=5509      do_freezer_trap
sysTid=5510      do_freezer_trap
sysTid=5511      do_freezer_trap
sysTid=5512      do_freezer_trap
sysTid=5513      do_freezer_trap
sysTid=5514      do_freezer_trap
sysTid=5515      do_freezer_trap
sysTid=5516      do_freezer_trap
sysTid=5519      do_freezer_trap
sysTid=5520      do_freezer_trap
sysTid=5521      do_freezer_trap
sysTid=5523      do_freezer_trap
sysTid=5525      do_freezer_trap
----- end 5452 -----

参考文章www.jianshu.com/p/e62892149…

在log中也看到

09-20 11:23:15.406 8019 8121 I am_freeze: [5452,com.android.systemui:screenshot]

通过adb shell cmd activity watch-uids --oom [uid]观察oomadj的变化


# Start proc 475:com.android.systemui:screenshot/u0a180 for service {com.android.systemui/com.android.systemui.screenshot.TakeScreenshotService}

# Making exec-service: ProcessRecord{34d1f6d 475:com.android.systemui:screenshot/u0a180}

# Raise to service: ProcessRecord{34d1f6d 475:com.android.systemui:screenshot/u0a180}, due to ProcessRecord{ade678e 8019:system/1000} adj=0 procState=BFGS

# Set 475 com.android.systemui:screenshot adj 0: service

# Proc state change of com.android.systemui:screenshot to BFGS (5): service

# Making empty: ProcessRecord{34d1f6d 475:com.android.systemui:screenshot/u0a180}

# Raise to service: ProcessRecord{34d1f6d 475:com.android.systemui:screenshot/u0a180}, due to ProcessRecord{ade678e 8019:system/1000} adj=100 procState=BFGS

# Set 475 com.android.systemui:screenshot adj 100: service

# Making exec-service: ProcessRecord{34d1f6d 475:com.android.systemui:screenshot/u0a180}

# Set 475 com.android.systemui:screenshot adj 0: exec-service

# Setting sched group of com.android.systemui:screenshot to 0: exec-service

# Proc state change of com.android.systemui:screenshot to SVC (10): exec-service

# Making empty: ProcessRecord{34d1f6d 475:com.android.systemui:screenshot/u0a180}

# Set 475 com.android.systemui:screenshot adj 1001: cch-empty

# Proc state change of com.android.systemui:screenshot to CEM (19): cch-empty

# Set 475 com.android.systemui:screenshot adj 905: cch-empty

可以看到弹窗出现的时候adj是905,进程的状态是CACHED_EMPTY

image.png

命令行获取冻结相关的变量信息

$ adb shell dumpsys activity settings
  use_freezer=true //是否支持冻结
  freeze_statsd_sample_rate=0.1
  freeze_debounce_timeout=10000 // adj已经是CACHED_EMPTY后,延时10s就会开始冻结
  freeze_exempt_inst_pkg=false
  freeze_binder_enabled=true
  freeze_binder_threshold=1000
  freeze_binder_divisor=4
  freeze_binder_offset=500
  freeze_binder_callback_enabled=true
  freeze_binder_callback_throttle=10000
  freeze_binder_async_threshold=1024
  Apps frozen: 17 //冻结app的列表,代码一共有17个app进程被冻结
    26599270: 6324 com.google.android.apps.wellbeing
    26603762: 6391 com.google.android.googlequicksearchbox:googleapp
    26384926: 6592 com.google.android.webview:webview_service
    26610841: 6676 com.google.android.apps.photos
    ....
  1. 再看Perfetto

1 第一次触摸down,up事件处理及时

2 第二次触摸后wq一直在累加,且没有减少

3 com.android.systemui:screenshot进程被冻结,所以2的触摸事件无法被处理

image.png

从3中查看主线程com.android.systemui:screenshot的runnable片段,可以知道是被SystemService的CachedAppOptimi线程唤醒

image.png

从下图可以看出SystemService的CachedAppOptimi线程正在进行冻结com.android.systemui:screenshot的操作

image.png