556
查看BUG实例分析一:死机的源代码
BUG实例分析一:死机
0
←
BUG实例分析一:死机
跳转至:
导航
、
搜索
因为以下原因,你没有权限编辑本页:
你被禁止执行你刚才请求的操作。
您可以查看并复制此页面的源代码:
=== 一、现象 === 手机睡眠后按power键无法正常唤醒,具体表现如下: 现象一:无法点亮屏幕,按任意键无响应; 现象二:可以点亮屏幕,但触屏、按键无响应,电话也无法呼入,但插入usb偶尔可以更新状态栏时间 === 二、初步判断 === 从log上看,有两个案例log是有明显异常,在不停地打印同一条log,由于这些log是在有触屏事件时会出现的(包括但不限于),因此初步判断是input(如按键、触屏)事件出现异常,导致系统的input机制拥挤阻塞,但由于input及powerManager很多log屏蔽,无法作出进一步有效判断,故这里提供一个增加了大量log的image,请协助测试一下,力争抓到log(如能发掘必现规律就更好了)。 === 三、解决思路 === 一方面,由于input消息流程中大部分log是关闭的,因此仅从产品上抓取的log消息不足以定位问题点,因此决定发一版包含input所有log并在关键函数加入了不少log的软件给品质部测试(同时也鼓励内部试用机用户烧写这个软件),并且要求品质部一旦发现此问题立马将现场保留,以便我们进行adb分析。 另一方面,之前今天有过一台出现此问题的机器,在不停地打印按键的 "repeatCount=xxx",并且这个数值一直在递增,因此我们也做了第二手准备:即如果短期内无法重现这个问题,那则在打印 "repeatCount"这个地方进行判断,当 "repeatCount"大于某个值时则认为出现了异常,这样则重启手机。如此一来,至少问题会得到恢复,而不至于一直处理“死机”状态而不得不拔电池。这是为了不影响发货不得已的临时解决方案。 === 四、终得真机分析 === 几天过去,品质部同事重现了此问题! adb Go!!! 1、adb logcat,按键,inputDispatcher中的 notifyKey有无log产生?——无 2、adb shell getevent,按键,是否能接收到按键消息?——是 ==>驱动ok,问题发生在了framework 3、动态卸载、添加event2 ——无论卸载还是添加,均不成功 ==>怀疑 inputReader所在的 Thread阻塞 4、查看anr ——InputReader处于 WAIT状态,栈直指 interceptKeyBeforeQueueing中所调用的某一个函数,而这个函数调用了ContentResolver中的parse操作 ==>这就是卡的地方?! === 五、验证 === 又在上述关键的地方加了些log,发个了软件(品质的同事辛苦了!),幸运的是这次不到一天便出现了三台问题机器,其中有一台的log显示: <pre calss="prettyprint"> 7824 07-14 15:53:03.688 D/InputDispatcher( 278): before call interceptKeyBeforeQueueing, 2816 7825 07-14 15:53:03.688 W/WindowManager( 278): interceptKeyBeforeQueueing start 7888 07-14 15:53:03.694 W/WindowManager( 278): interceptKeyBeforeQueueing end 7891 07-14 15:53:03.694 D/InputDispatcher( 278): after call interceptKeyBeforeQueueing, 2818 7917 07-14 15:53:03.697 D/InputDispatcher( 278): before call interceptKeyBeforeQueueing, 2816 7918 07-14 15:53:03.697 W/WindowManager( 278): interceptKeyBeforeQueueing start 7923 07-14 15:53:03.699 W/WindowManager( 278): interceptKeyBeforeQueueing end 7926 07-14 15:53:03.699 D/InputDispatcher( 278): after call interceptKeyBeforeQueueing, 2818 22072 07-14 15:57:54.647 D/InputDispatcher( 278): before call interceptKeyBeforeQueueing, 2816 22073 07-14 15:57:54.647 W/WindowManager( 278): interceptKeyBeforeQueueing start 22135 07-14 15:57:54.652 W/WindowManager( 278): interceptKeyBeforeQueueing end 22141 07-14 15:57:54.654 D/InputDispatcher( 278): after call interceptKeyBeforeQueueing, 2818 22186 07-14 15:57:54.887 D/InputDispatcher( 278): before call interceptKeyBeforeQueueing, 2816 22187 07-14 15:57:54.887 W/WindowManager( 278): interceptKeyBeforeQueueing start 22192 07-14 15:57:54.888 W/WindowManager( 278): interceptKeyBeforeQueueing end 22195 07-14 15:57:54.888 D/InputDispatcher( 278): after call interceptKeyBeforeQueueing, 2818 40764 07-14 16:01:19.988 D/InputDispatcher( 278): before call interceptKeyBeforeQueueing, 2816 40765 07-14 16:01:19.988 W/WindowManager( 278): interceptKeyBeforeQueueing start 40767 07-14 16:01:19.989 W/WindowManager( 278): interceptKeyBeforeQueueing end 40770 07-14 16:01:19.989 D/InputDispatcher( 278): after call interceptKeyBeforeQueueing, 2818 40799 07-14 16:01:20.404 D/InputDispatcher( 278): before call interceptKeyBeforeQueueing, 2816 40800 07-14 16:01:20.404 W/WindowManager( 278): interceptKeyBeforeQueueing start </pre> 完美地验证了之前的猜测! === 六、后续规避 === 这个问题的原因主要是在关键的路径(所有input事件都要调用的函数)上,增加了比较复杂的、有风险的ContentResolver操作,而一旦操作超时则导致整个系统的input系统瘫痪,用户无法操作,手机也无法自动恢复,只有拔电池了。 所以在后续framework的修改时,一定要考虑到所作更改的影响,在这些地方的更改也尽量要使用简单的逻辑、可靠数据操作方式进行,同时也要兼顾到性能方面的影响,如这里的更改就会导致每个input事件都要去操作ContentResolver,且不论是否可靠,单从性能上讲也不太可取。
返回
BUG实例分析一:死机
。
导航菜单
个人工具
   
个人维基
注册
登录
名字空间
页面
变换
查看
阅读
查看源代码
统计
查看历史
操作
搜索
导航
首页
Ubuntu
Android
C&CPP
Java
Python
大杂烩
最近更改
工具箱
所有页面
文件列表
特殊页面