由ContactsProvider的升级引发的OTA首次开机卡白米问题分析
上午的宁静被一个OTA卡白米问题打破,接下来不断有人反馈不同机型都复现了OTA后卡白米,10.9号OTA升级到10.10号的版本,全机型问题,线刷没有问题,好吧,接下来就根据这些信息开始初步分析log吧!
初步分析
查看问题log,发现Boot phase到了PHASE_SYSTEM_SERVICES_READY
并且走到了PackageManagerService.systemReady
10-10 15:26:47.762 3152 3152 W ContextImpl:
Calling a method in the system process without a qualified user:
android.app.ContextImpl.bindService:1295
miui.provider.ExtraGuard.init:69
com.android.server.pm.PackageManagerServiceInjector.initExtraGuard:429
com.android.server.pm.PackageManagerService.systemReady:15195
com.android.server.SystemServer.startOtherServices:1133
继续看log发现以下异常信息
10-10 15:27:07.784 3152 3221 E ActivityManager:
Attempt to launch receivers of broadcast intent Intent
{ act=android.net.conn.DATA_ACTIVITY_CHANGE (has extras) } before boot completion
这说明系统启动没有正常完成,ActivityManager的状态还没有就绪,难道system server的启动流程出现了异常?
赶紧打出system server的traces看一下
"main" prio=5 tid=1 Native| group="main" sCount=1 dsCount=0 obj=0x75f14fb8 self=0x558db1ec10| sysTid=3152 nice=-2 cgrp=default sched=0/0 handle=0x7fb6a3afc8| state=S schedstat=( 5043600992 157397768 10523 ) utm=367 stm=137 core=5 HZ=100| stack=0x7fe85de000-0x7fe85e0000 stackSize=8MB| held mutexes=kernel: __switch_to+0x70/0x7ckernel: SyS_epoll_wait+0x2a0/0x32ckernel: SyS_epoll_pwait+0xa4/0x120kernel: cpu_switch_to+0x48/0x4cnative: #00 pc 0000000000069be4 /system/lib64/libc.so (__epoll_pwait+8)native: #01 pc 000000000001cca4 /system/lib64/libc.so (epoll_pwait+32)native: #02 pc 000000000001be88 /system/lib64/libutils.so (_ZN7android6Looper9pollInnerEi+144)native: #03 pc 000000000001c268 /system/lib64/libutils.so (_ZN7android6Looper8pollOnceEiPiS1_PPv+80)native: #04 pc 00000000000d2580 /system/lib64/libandroid_runtime.so (_ZN7android18NativeMessageQueue8pollOnceEP7_JNIEnvP8_jobjecti+48)native: #05 pc 000000000000082c /data/dalvik-cache/arm64/system@framework@boot.oat (Java_android_os_MessageQueue_nativePollOnce__JI+144)at android.os.MessageQueue.nativePollOnce(Native method)at android.os.MessageQueue.next(MessageQueue.java:323)at android.os.Looper.loop(Looper.java:135)at com.android.server.SystemServer.run(SystemServer.java:299)at com.android.server.SystemServer.main(SystemServer.java:181)at java.lang.reflect.Method.invoke!(Native method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
看起来主线程没有什么异常,已经进入主消息循环了,也就是说startOtherServices已经走完了,都走完了为啥activitymanager的状态还没有就绪?看代码吧
已知PMS的systemready已经走了,整个startOtherServices也走完了,所以AMS的systemready一定调用了,但是调用了为什么没有ready?
仔细看上面的代码可以看到一些端倪,因为调用AMS的systemready时传入的是一个runnable,runnable里面是启动systemui并通知一堆系统service running,从代码中可以看到这个runnable是在systemready函数的后半部分执行的,而当前出问题的状态是这个runnable并没有执行。
除了这个runnable之外还有一个关键的状态就是AMS的mSystemReady,通过am start发现log中打出来AMS没有ready的信息,产生这种状态的唯一的可能就是在AMS的systemready函数中没有正常执行完毕。
查看代码发现OTA后第一次调用到AMS的systemready之后mDidUpdate为false,mWaitingUpdate也是false,继续往下走到deliverPreBootCompleted,这里又传入了一个runnable,非常关键的一步,如果是OTA后第一次调用deliverPreBootCompleted会返回true给mWaitingUpdate,以为在deliverPreBootCompleted里面会发送ACTION_PRE_BOOT_COMPLETED给所有注册的receiver,并且添加FLAG_RECEIVER_BOOT_UPGRADE,在发送广播的时候就从同步调用变成了异步,返回后继续执行,mWaitingUpdate为true,然后return出去,mSystemReady在这一次没有机会设置为true,那什么时候设置呢?AMS ready的剩余代码什么时候执行呢?带着问题继续看代码
深入分析
还记得上面调用deliverPreBootCompleted时传入的runnable吗?当OTA后第一开机的ACTION_PRE_BOOT_COMPLETED广播发送给所有的receiver之后就会调用这个runnable,它里面会将mDidUpdate置为true并再次调用AMS的systemready函数,这次会正常执行完所以的流程,包括设置mSystemReady等状态为true,调用startOtherServices传入的runnable启动systemui和notify systemservice running,启动home等,但是现在这些都没有做。。。好吧,一言不合说不做就不做,Android就是任性!
赶紧看看它为啥没做,deliverPreBootCompleted也调用了,runnable也传过去,那问题就出在deliverPreBootCompleted里面的广播发送了?要想知道,还得看代码和log
好了,代码和log看到这里,基本定位到了大概原因,这个广播是有序发送的,并且是显式指定component的方式,每个发送完了都会把结果给PreBootContinuation并调用performReceive发送下一个,如果都发完了会把之前传入的runnable post 到消息队列里面,显而易见,没有走到post这一步,也就是说上面的广播在发送过程中出问题了,出什么问题了呢?还好这个问题可以必现,赶紧复现追一下代码,发现需要给6个receiver发送广播,出问题时只发送到第二个contactsproviders的时候就断了,log也对应了这一点,并且log中发现了contactsproviders升级数据库版本的信息,同时又仔细看了一下system server的trace,发现有个关于getprovider的线程不是太正常,一直处于waiting状态
contactsproviders执行之后一直没有完成,而AMS这么又有一个binder 线程一直在等待provider,这是不是有某种对应关系?赶紧看一下contactsproviders所在进程的traces,发现真有关系,在ContactsUpgradeReceiver里面执行数据库升级之后去请求一个content provider的时候block住了
真是踏破铁鞋无觅处,得来好不费功夫啊,system server一直在等待你完成通知它,你却在这睡大觉,但是又引来一个问题,这里的调用为什么会一直block?继续看代码,断点追代码,在getContentProviderImpl里发现了蹊跷,为contactsprovider 请求的yellowpage provider去startProcessLocked的时候由于system还没有ready所以start的操作被hold住了,所以导致contactsprovider的query操作被一直block
通过分析代码发现,不允许yellowpageprovider的进程起来是合理的,不合理的是contactsprovider在OTA过第一次开机upgrade的过程中不合理的请求了query yellowpageprovider,从而block整个系统启动,导致卡白米
后续问题
到这里可能有细心的同学会问,为什么之前OTA没问题,今天就有问题了?
原因是contactprovider的数据库版本有升级,在升级的同时触发了T9索引重建,重建的过程中用到了yellowpageprovider,来一下change再配合上面的traces可能会更直观
这个索引重建不是不能做,而是不能在OTA第一次开机过程中调用upgradereceiver的做,可以等正常开机后,BOOT_COMPLETED广播发出去的时候再触发做
可能还有更细心的同学会问,为什么卡住之后再重启一下就好了呢?
这是因为在ContactsUpgradeReceiver中会先判断DB VERSION,第一次因为升级了所以不相等,就走升级流程,升级之前先把最新的DB VERSION put到了preference中,这样第二次的时候因为相等了就不会再走升级流程了,所以就不会卡白米了
由ContactsProvider的升级引发的OTA首次开机卡白米问题分析相关推荐
- SQLSERVER 2012之AlwaysOn -- 一次硬件升级引发的问题
原文:SQLSERVER 2012之AlwaysOn -- 一次硬件升级引发的问题 这是上周遇到的一个案例:对已有的硬件进行升级而引发的问题,期间还触发了一个比较严重的BUG,可谓多灾多难:不过值得庆 ...
- 汽车在线升级系统(OTA)开发浅析
本文由姜楠,姜姗姗,韩小鹏联合创作 摘要 介绍了汽车在线升级系统(OTA)的应用场景及功能,阐明了升级系统中车端及云端模块开发策略及架构:同时明确了与整车其他 ECU 的交互需求:最后介绍了在线升级系 ...
- 58 ESP32 OTA升级(双OTA分区无factory APP)
1 引言 产品功能实现后,就要对产品的维护进行考虑.产品出来后,卖了N台出去,如果突然发现自己一行代码写错了,怎么办,肯定不能去现场吧N台设备,免费出差旅游也累啊,所以一般需要有远程升级设备的功能,此 ...
- android系统开机启动很慢,为什么安卓手机升级系统后,首次启动会比较慢?
原标题:为什么安卓手机升级系统后,首次启动会比较慢? 点击 很多小伙伴对安卓手机进行系统升级后,可能都会遇到一种情况:手机首次启动的时间好久,首次打开应用的时间也比往常要长. 为什么会出现这种情况? ...
- RTOS设备如何快速实现OTA升级--快速接入OTA平台
目录 一. 创建产品和零件 1.1 登陆平台 1.2 添加产品 1.3 配置产品 1.4 添加升级零件 二. 添加设备 2.1 单个添加 2.2 批量添加 三. 设备注册激活 3.1 发起请求 3.2 ...
- ESP32 OTA升级之HTTP OTA
ESP32 OTA升级之 HTTP OTA 文章目录 ESP32 OTA升级之 HTTP OTA 1. 前言 2. 搭建http本地服务器 2. HTTP OTA 3. 补充学习 1. 前言 在所有电 ...
- 启明云端分享|sigmastar SSD201/ssd202核心板升级参考,可实现开机自动从 SD 卡升级固件或开机自动从 SD 卡烧录 MAC 地址
实现功能 1.开机自动从 SD 卡升级固件: 2.开机自动从 SD 卡烧录 MAC 地址: 一.实现方法 自动升级固件 示例:# vi project/image/configs/i2m/script ...
- 计算机启动时蓝屏后自动重起,升级Win10系统之后一开机就蓝屏且电脑不断重启怎么解决?...
升级Win10系统之后一开机就蓝屏且电脑不断重启怎么解决?这一点其实和用户使用的计算机硬件环境有关系,目前就笔者所知的最容易引起该问题的硬件是显卡,很多显卡驱动都不能很好的兼容Win10系统.所以我们 ...
- Windows 11 首次开机OOBE阶段跳过连接网络及登录微软账户,使用本地账号登录的方法
2022/11/25更新: 以下方法最新版本的Win11 22H1上已失效,最新的方法是在第二步呼出cmd窗口,输入oobe\bypassnro,电脑会重启,再次来到连接网络的页面时选择"我 ...
- deepin升级到20.2,开机显示deepin LOGO之后屏幕黑屏解决办法
deepin升级到20.2,开机显示deepin LOGO之后屏幕黑屏解决办法 黑屏后按快捷键: ctrl+atl +F2进入终端. 在终端执行命令: sudo apt install deepin- ...
最新文章
- linux7 kernel.sem,centos7.4内核调优,tcp单服务器万级并发
- 开启虚拟化技术之旅---1什么是虚拟化?
- sklearn之XGBModel:XGBModel之feature_importances_、plot_importance的简介、使用方法之详细攻略
- 【转】Thunderbird中配置签名
- mysql改表字段类型导致数据丢失_故障分析 | 记一次 MySQL 主从双写导致的数据丢失问题【转】...
- lcc-win32使用指南
- jQuery DOM操作之查找结点
- 平方方程应该都有整数解
- Atitit 物联网之道 艾龙著 attilax著 1. 理论基础(控制理论 信息理论)	2 2. 1.5 物联网的关键技术12 	2 2.1. 1.5.1 网络与通信技术12 1.5.2 无线传感
- 平安银行股票数据涨跌预测
- U8恢复记账操作步骤
- pthread_join()详解及实验
- 何小鹏快跑:身家暴涨50亿美元,他还愿坐经济舱吗?
- 【“您未被授权查看该页”的原因和解决办法】
- PTA-数据库作业题(二)
- matlab中应用surf函数画球形物体的三维坐标变换,从球坐标系转换到笛卡尔坐标系
- CSDN竞赛6期题解
- UVA10158- War
- Word如何让不同页显示不同的页码,页眉
- 如何理解「数据驱动业务」?
热门文章
- 办公计算机配件,办公电脑加装傲腾如丝般顺滑的办公体验
- GMSSL双证书认证C/S(Linux版)
- MyBatis下载和环境搭建
- Oracle使用sqluldr2
- Win10修改EFI分区文件
- Docker下载Nginx镜像并运行Nginx容器
- Python(PyCharm)的下载安装汉化(2022)
- android 移动网络定位服务器地址,安卓定位方式全总结-gps定位,network定位,ip定位,基站定位...
- 精简版oracle客户端程序
- PHP读dwg,dwg文件阅读器