(这是19年遇到的一个问题,现在回来看看,有了不一样的收获~)
问题:Android下执行reboot recovery后, 黑屏无输出,重新上电也还是黑屏
具体现象:执行reboot recovery后,进入recovery下黑屏能够输入命令,但是recovery服务已经挂了,busybox reboot 重启后仍然进入recovery;断电后再次上电还是进入recovery。
背景:
(1)3月26号发现该问题
(2)3月23号reboot recovery正常
这个问题要怎么解决呢?下面开始我们的探索之旅吧~
Day one -- 正面干!
reboot recovery进去抓个log看看啥情况
[ 28.645975@2] fb: osd_open, 1491, fb_index=0,fb_rmem_size=26738688
[ 28.646537@2] fb: osd_release now.index=0,open_count=1
[ 28.752360@2] init: Service 'recovery' (pid 2986) received signal 6
[ 28.753016@2] init: Sending signal 9 to service 'recovery' (pid 2986) process group...
[ 28.761056@2] libprocessgroup: Successfully killed process cgroup uid 0 pid 2986 in 0ms
[ 28.769150@2] init: Untracked pid 2987 exited with status 1
从上面的log可以看到recovery这个Service挂了,received signal 6?signal 6是啥呢,
百度一下看看,程序运行产生SIGABRT信号的原因_Season_hangzhou的博客-优快云博客_sigabrt信号
上文提到SIGABRT信号即signal 6的信号,可能的原因有:
1、多次free导致的SIGABRT
2、执行abort函数
3、执行到assert函数
嗯,很有道理,opengrok搜一波"received signal"试试,这个搜索要充分利用opengrok的功能

这里可以指明File Path可以帮助我们过滤问题,这个操作就如cd 到File Path里面grep一下
换一个"process group..."试试
这个在/android/system/core/init/service.cpp KillProcessGroup函数里面,看了一下代码,功能就是把pid同组的进程全部杀死
从log中我们也可以看到recovery服务一直在被杀,杀完又起,如此循环往复

从上面的分析也得不出什么原因,这些都是公共的东西,只能得出有问题导致了这些打印。
直接分析log有很多不熟悉的地方,也不确定是不是这个原因导致的,这个时候对比法就很重要了,我们升级一下23号的软件进recovery抓个log
从log的对比,我大概了解到以下几点信息:
正常的是:
[ 12.896990@0] fb: osd_open, 1491, fb_index=0,fb_rmem_size=26738688
[ 12.897613@0] fb: osd_release now.index=0,open_count=1
[ 12.906375@0] fb: osd_open, 1491, fb_index=0,fb_rmem_size=26738688
[ 12.909027@0] fb: malloc_osd_memory, cma:c18d3a8c
[ 12.913535@0] fb: malloc_osd_memory, 1188, base:0x3f800000, size:8388608
[ 12.920218@0] fb: use ion buffer for fb memory, fb_index=0
[ 12.934219@0] meson-fb fb: create ion_client c9ee5980, handle=e59cc640
[ 12.935111@0] meson-fb fb: ion memory(0): created fb at 0x2b400000, size 25 MiB
[ 12.942564@0] fb: Frame buffer memory assigned at[ 12.946927@0] fb: 0, phy: 0x2b400000, vir:0xeb400000, size=26112K
[ 12.946927@0]
[ 12.954723@0] fb: logo_index=0,fb_index=0
[ 12.958755@0] fb: ---------------clear fb0 memory eb400000
[ 12.974833@0] fb: osd[0] canvas.idx =0x40
[ 12.974857@0] fb: osd[0] canvas.addr=0x2b400000
[ 12.977737@0] fb: osd[0] canvas.width=7680
[ 12.981812@0] fb: osd[0] canvas.height=2160
[ 12.985965@0] fb: osd[0] frame.width=1920
[ 12.989995@0] fb: osd[0] frame.height=1080
[ 12.994032@0] fb: osd[0] out_addr_id =0x1
[ 13.023258@0] fb: osd[0] enable: 0 (recovery)
[ 13.039920@0] fb: osd[0] enable: 1 (recovery)
[ 13.496240@1] fb: osd[0] enable: 0 (recovery)
异常的是:
[ 28.645975@2] fb: osd_open, 1491, fb_index=0,fb_rmem_size=26738688
[ 28.646537@2] fb: osd_release now.index=0,open_count=1
[ 28.752360@2] init: Service 'recovery' (pid 2986) received signal 6
[ 28.753016@2] init: Sending signal 9 to service 'recovery' (pid 2986) process group...
[ 28.761056@2] libprocessgroup: Successfully killed process cgroup uid 0 pid 2986 in 0ms
[ 28.769150@2] init: Untracked pid 2987 exited with status 1
为啥osd_open,osd_release之后挂了呢?osd这部分代码有人修改?
/android/common/drivers/amlogic/media/osd/osd_fb.c
查看一下这个仓库的修改,发现修改不在问题发生的区间,pass
追下代码看看osd_release之后发生了什么,半小时后,无果
问了自己一个问题,是因为osd这部分有问题导致的recovery挂掉?还是recovery挂掉导致的这部分代码没跑下去?好像有点鸡和蛋的关系
和同事讨论分析了一下目前的情况,我这边没有进展,他分析可能是remotecfg这个服务的原因,因为在正常的里面:
Line 1674: [ 7.869074@3] init: starting service 'remotecfg3'...
Line 1675: [ 7.870146@3] init: starting service 'remotecfg1'...
Line 1676: [ 7.871185@3] init: starting service 'remotecfg2'...
Line 1678: [ 7.873270@3] init: Service 'remotecfg3' (pid 2916) exited with status 253
Line 1679: [ 7.873398@3] init: Service 'remotecfg1' (pid 2918) exited with status 253
Line 1681: [ 7.874162@3] init: Service 'remotecfg2' (pid 2922) exited with status 253
异常的是:
Line 1462: [ 7.436788@2] init: starting service 'remotecfg3'...
Line 1464: [ 7.437824@2] init: starting service 'remotecfg1'...
Line 1465: [ 7.438317@0] init: cannot execve('/sbin/remotecfg'): No such file or directory
Line 1466: [ 7.439033@2] init: starting service 'remotecfg2'...
Line 1467: [ 7.439078@3] init: cannot execve('/sbin/remotecfg'): No such file or directory
Line 1469: [ 7.440309@3] init: cannot execve('/sbin/remotecfg'): No such file or directory
尝试直接将remotecfg从好的里面拷贝到异常的里面去,还是不能执行。
每日小结:
1、搜索代码有技巧
2、对比分析
Day two -- 反面迂回
目前看来正面是暂时无法找到原因了,既然这个问题是改出来的,那么必然会有一个修改导致这个问题。
接着开始愉快的夹版本了,一开始是要通过代码回退版本然后编译升级,后面想了一下,直接用dailybuild就行了
最后发现这两版软件
dailybuild软件:
20190325_083028 OK
20190325_120226 NG
多亏这每天几个版本的dailybuild,很快的,用二分法的方法定位到了出问题的前后版本
用dailybuild还有一个好处就是Jenkins上编译信息最后面有这次编译修改的内容,很方便就可以查看到本次编译版本的所有修改,但是这个因为时间久了没了
不过也可以通过命令来导出修改:
repo forall -p -c git log -n 30 --format="%Cgreen%h %Cred[%ci] %Creset <%cn>%C(yellow)%d%Creset %Creset %Cgreen%s %Creset " --after="2019-03-25 08:30:28" --before="2019-03-25 12:02:26"
修改包含了:
project android/common/
6fc8254 [2019-03-25 11:38:04 +0800] <xxxxx> log messagexxxx
project customers/public_alltv/
3338689 [2019-03-25 11:22:59 +0800] <xxxxx> log messagexxxx
还原6fc8254 修改reboot recovery正常
至此,已经找到了罪魁祸首了吗?
我们看一下修改了什么吧~
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index cd2be1c..4ebab8b 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -199,6 +199,7 @@ header-y += in.h
header-y += inotify.h
header-y += input.h
header-y += input-event-codes.h
+header-y += key_define.h
header-y += in_route.h
header-y += ioctl.h
header-y += ip6_tunnel.h
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 3af60ee..4884bad 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -507,7 +507,7 @@
#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
#define KEY_FRAMEFORWARD 0x1b5
#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
-#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
+//#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
#define KEY_IM

本文详细记录了一位工程师在解决Android设备在执行reboot recovery后出现黑屏问题的过程。通过日志分析、版本对比、代码调试,最终发现问题出在ioctl调用的参数错误,导致了内存越界。修复方法包括修改ioctl调用参数或更新系统中的KEY_MAX值。此外,文章还强调了问题排查中的关键步骤和技巧,如使用dailybuild快速定位问题、简化代码进行调试等。
最低0.47元/天 解锁文章
881





