启动概率性卡屏案例分析
·
背景及现象:以OpenHarmony-v5.1.0-Release为基线版本的某大屏产品上,系统启动时概率出现卡在开机logo,无法进入系统情况。
分析定位过程:
- 首先定位问题服务。卡屏出现在开机logo处,开机动画未播放,串口是可用的,可以使用串口命令param get | grep boot.time查看投票情况,观察发现render_service投票已完成,但bootanimation未投票,查看系统进程信息发现bootanimation进程是在运行的,那么为何bootanimation进程没有投票呢?



结合日志信息,很容易判断出问题出在了render_service,bootanimation在循环等待render_service服务句柄,说明render_service未完成初始化。


- 上面已经知道render_service已投票但是获取不到render_service的服务句柄,那么render_service进程一定是阻塞在了投票与服务发布之间的某个操作上,接下来需要定位阻塞的具体位置,走读一下render_service的初始化代码,在可疑位置加上一些打印信息进一步定位具体位置:


- 由于render_service只是卡住没有异常退出,我们看不到任何freeze或crash信息,这里可以在卡屏现场使用下面的指令来获取render_service的堆栈信息来帮助分析程序卡在了哪里
dumpcatcher -p $(pidof render_service)
或者
kill -11 $(pidof render_service)

从上面的堆栈信息可以看出阻塞点在OHOS::HDI::Display::Composer::V1_2::IDisplayComposer::Get()函数,堆栈的顶端是WriteBinder函数,这个IPC堆栈信息表明客户端的请求未得到服务端的响应。
- 结合日志和堆栈信息,梳理screenManager_->Init()的调用链

- 精确定位程序问题点
在卡屏时的日志信息中,发现上面调用链的函数7中“hdi v1_2 start”已打印,但“hdi v1_2 end”未打印,这也论证了上述调用链是正确的

继续在DisplayComposerProxy中加入打印来跟踪程序,这部分代码可能由于是框架自动生成的缘故,路径比较特殊在out目录下
out/product_name/gen/drivers/interface/display/composer/v1_2/display_composer_proxy.cpp


- servMgr->GetService是HDF框架devmgr提供的接口,我们查看了系统进程信息,composer_host服务是已经启动的,获取不到服务句柄,难道是HDF框架有问题,这种可能性比较小,于是我们分析了相关仓的提交记录,果然有一笔提交似乎有点问题,这笔提交修改了HDF的锁机制,存在死锁风险,回退该PR进行压测,不再出现卡logo问题。

至此问题根因浮出水面:HDF引入的概率死锁问题造成render_service卡死,开机流程会阻塞在bootanimation播放前。
- 总结
对于此类卡logo或开机动画的问题的分析定位,先根据投票情况确定出现问题的服务或进程,再结合日志和错误堆栈来定位程序bug点。
更多推荐

所有评论(0)