记一次数组越界的BUG

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

(这是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的博客-CSDN博客_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
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值