1.问题现象

氛围灯和导航交互过程中,导航发送一个广播之后,接连有五个服务被kill掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 932116)
BroadcastQueue: Can't deliver broadcast to com.gxa.service.messagecenter (pid 2707). Crashing it.
BroadcastQueue: Failure sending broadcast Intent { act=com.iflytek.autofly.ACTION_MAP_SEND flg=0x10 (has extras) }
BroadcastQueue: android.os.TransactionTooLargeException: data parcel size 932116 bytes
BroadcastQueue: at android.os.BinderProxy.transactNative(Native Method)
BroadcastQueue: at android.os.BinderProxy.transact(Binder.java:1127)
BroadcastQueue: at android.app.IApplicationThread$Stub$Proxy.scheduleRegisteredReceiver(IApplicationThread.java:1152)
BroadcastQueue: at com.android.server.am.BroadcastQueue.performReceiveLocked(BroadcastQueue.java:494)
BroadcastQueue: at com.android.server.am.BroadcastQueue.deliverToRegisteredReceiverLocked(BroadcastQueue.java:706)
BroadcastQueue: at com.android.server.am.BroadcastQueue.processNextBroadcastLocked(BroadcastQueue.java:866)
BroadcastQueue: at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:825)
BroadcastQueue: at com.android.server.am.BroadcastQueue$BroadcastHandler.handleMessage(BroadcastQueue.java:172)
BroadcastQueue: at android.os.Handler.dispatchMessage(Handler.java:106)
BroadcastQueue: at android.os.Looper.loop(Looper.java:193)
W BroadcastQueue: at android.os.HandlerThread.run(HandlerThread.java:65)
W BroadcastQueue: at com.android.server.ServiceThread.run(ServiceThread.java:44)

AndroidRuntime: Shutting down VM
JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 932116)
BroadcastQueue: Can't deliver broadcast to com.gxatek.cockpit.atmospherelampservice (pid 3559). Crashing it.
AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.gxa.service.messagecenter, PID: 2707
AndroidRuntime: android.app.RemoteServiceException: can't deliver broadcast
AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1745)
AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6718)
AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
1
2
3
4
5
6
// 被kill进程
com.gxatek.cockpit.atmospherelampservice
com.gxatek.cockpit.scenesengine
com.iflytek.autofly.naviselect
com.gxatek.cockpit.vpamultimode
com.gxa.service.messagecenter

2.问题定位

看日志大概问题是FAILED BINDER TRANSACTION,binder传输数据失败,parcel size = 932116parcel大小为932116字节。

然后一看是BroadcastQueue类报出来的,于是乎找到报错的地方

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

报错点.png

可以看到调用对端的scheduleRegisteredReceiver方法的时候报了异常,然后捕获异常中输出日志,最后throw一个异常,导致对端进程crash。

3.问题调查

在源码中添加日志如下,打出两端进程信息,看看广播交互情况。

调查添加日志.png

1
2
3
4
5
6
7
BroadcastQueue: performReceiveLocked CallingPid = 786, CallingUid = 1000
BroadcastQueue: intent = Intent { act=com.iflytek.autofly.ACTION_MAP_SEND flg=0x10 (has extras) }, data = null
BroadcastQueue: processname = com.gxatek.cockpit.atmospherelampservice, thread name = android.app.IApplicationThread$Stub$Proxy@d42f0e6

BroadcastQueue: performReceiveLocked CallingPid = 786, CallingUid = 1000
BroadcastQueue: intent = Intent { act=com.iflytek.autofly.ACTION_MAP_SEND flg=0x10 (has extras) }, data = null
BroadcastQueue: processname = com.gxatek.cockpit.scenesengine, thread name = android.app.IApplicationThread$Stub$Proxy@9f803ef

找到交互双方之后就开始调查是哪一方发送了过大广播。首先注销掉地图的接收广播,只给地图发广播,发现消息中心不会被kill,然后一个一个广播试监听那个广播报的传输数据量过大。最后发现监听com.iflytek.autofly.ACTION_MAP_SEND这个广播,一交互就报toolargeException而崩溃,基本定位到地图发送该广播intent内容超限。

经过地图调查发现:AR导航测试的功能广播打开,导致数据量过大。