Android 异常问题分析

1. Introduction

解决问题通常分为以下几个步骤:

a) 确定问题,这是个什么样的问题,有什么外在表现;

b) 分析问题,根据log里面的蛛丝马迹,定位出问题的原因;

c) 对症下药,尽量用最少的代码解决问题,并确保不会引入新的问题;

d) 验证修改,把自己的修改导入,确保自己的修改起了作用,并已经彻底解决了问题,同时观察是否引入新的问题;

此文档主要面对的是几类问题:

a) 重启;

b) 死机(定屏);

c) 开机;

d) 黑屏;

下面会介绍各个问题,但基本只会从理论上介绍如何分析,所以不要期望看了这个文档,你就能解决问题,这就像抓鱼一样,知道了如何抓鱼,不代表你能抓得到鱼;

2. 重启问题

重启问题分为两类,一类是内核重启(包含Modem重启),一类是上层重启,如何区分?

如果有震动,那么就是内核重启,反之则是上层重启;如果不记得有无震动,也可以通过开机时间来判断,设置里面可以看开机经过了多少时间,dmesg的输出也有时间标签;还可以通过ps看进程号来判断,如果zygoteservicemanager等的进程号比较小(一般100左右),那么通常是内核重启,否则就是上层重启;如果你没有看到现场,就只能通过Log来判断了,后面会说到。

2.1 上层重启

对于上层导致的重启,这个比较普遍,一般有watch dog导致的重启,需要进一步分析anr,一般是应用死锁导致的问题,很遗憾这里没有例子;还有一种常见的问题就是native crash。重启问题需要关注的就是时间点,一般在重启之前一定有异常的log,往上继续查找出现的异常,通常不远处就是系统重启的原因,并会打印出具体的栈信息。

如果是watch dog触发的重启,就需要分析anr里面的文件traces.txt,如果前面的进程名字不是system_server,通常意味着这个anr已经被覆盖了,这时候需要去dropbox里面找到对应时间的文件,里面会保留下来;如果是system_server,就搜索ServerThread,这个是主线程,里面会告诉你它阻塞在了什么地方,然后顺着它阻塞的路径,一直追,就可以找到真正触发系统阻塞的原因,通过栈信息,找到具体的文件,函数,并联系上下文,猜测出可能的路径;这里是非常需要灵感的地方,不同的情景不同的原因,基本上没有一个万能的方法,全靠分析者自己的造化。

如果是native crash引发,当发生native crash的时候,一般在tombstone目录下都能找到记录。native调用栈一般都是在tombstone或者applogcat-log中打印出来。会有类似以下的log信息出现。

pid: 2363,tid: 2756, name: rild >>> /system/bin/rild <<<

signal 11(SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000

检查发生错误的类型,比如SIGSEGVSIGBUSSIGPIPE等,这里是SIGSEGV表示地址错误,那就检查访问地址。

这里有一个上层导致的重启例子:

pid: 2363,tid: 2756, name: rild >>> /system/bin/rild <<<

signal 11(SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000

r0 00000000r1 00000000 r2 1e7c32c2 r3 00000000

r4 b6d65565r5 b6d561a4 r6 00000000 r7 00000000

r8 b6d6be1cr9 b6b25cf8 sl b6d58e17 fp b6d6c1e8

ip b6d6beecsp b6b25a08 lr b6d3be41 pc b6f79140 cpsr 600f0030

d0676f6c522d657352 d1 6464615f79617749

d272207473756a204c d3 756e2074726f705f

d4002d00650074006c d5 007000750067006c

d6002e00730075006c d7 006b002e006f0063

d80000000000000000 d9 0000000000000000

d100000000000000000 d11 0000000000000000

d120000000000000000 d13 0000000000000000

d140000000000000000 d15 0000000000000000

d164150c82e3d2f1aa0 d17 0000000000000000

d18 41b7ccaa7c000000d19 0000000000000000

d200000000000000000 d21 0000000000000000

d220000000000000000 d23 0000000000000000

d240000000000000000 d25 0000000000000000

d260000000000000000 d27 0000000000000000

d280000000000000000 d29 0000000000000000

d30 0000000000000000d31 0000000000000000

scr 00000010

backtrace:

#00 pc00023140 /system/lib/libc.so (strlen+83)

#01 pc00015e3d /system/lib/libbalong-ril.so

#02 pc0001a1a3 /system/lib/libbalong-ril.so

#03 pc0001a903 /system/lib/libbalong-ril.so (on_data_call_list_changed+42)

#04 pc0002dffd /system/lib/libbalong-ril.so

#05 pc0000d410 /system/lib/libc.so (__thread_entry+72)

#06 pc0000d5a8 /system/lib/libc.so (pthread_create+240)

#07 pc00001014 [heap]

2.2 Modem重启

关键log: sys rebootreason: Software EXCE CP

出现内核重启问题,首先应该看看是不是Modem重启,在目前发现的重启问题来看,大部分是Modem导致的,当然随着版本的稳定,现在也比较少了。

相关问题log

06-0915:29:00.746 <6>[17425.253448] [1198.0, rdr_init_thread] rdr:sys rebootreason: Software EXCE CP

06-0915:29:00.748 <6>[17425.271850] [1198.0, rdr_init_thread] rdr:we shouldsave file to emmc before reboot!

06-0915:29:01.774 <6>[17426.294281] [1198.1, rdr_init_thread] save resetlog:rdr:system reboot reason: Software EXCE CP

06-0915:29:11.739 <6>[17436.260955] [1198.2, rdr_init_thread] we need rebootnow ...

06-09 15:29:14.645<6>[17439.164001] [1198.3, rdr_init_thread] sysreboot reason: SoftwareEXCE AP, tick: 20140609072914_17857.690150, systemError para: ModId=0x82000006,Arg1=5, Arg2=0

06-0915:29:14.648 <6>[17439.169677] [1198.3, rdr_init_thread] rdr:we shouldsave file to emmc before reboot!

06-0915:29:15.599 <6>[17440.122100] [1198.0, rdr_init_thread] save resetlog:sysreboot reason: Software EXCE AP, tick: 20140609072914_17857.690150

2.3 内核重启

关键logsysreboot reason: Software EXCE AP

导致内核重启的原因主要是以下两种:

1、代码异常直接主动panic、被动panic(一般出现了踩了内存、非法指针等致命错误)

2、硬件狗复位

内核检测到异常,直接调用BUG函数触发panic,这里的BUG函数是一个宏定义,最终会调用panic函数打印出调用栈,同时导致手机重启。在kmseg中能看到oops字串和backtrace调用栈,另外会生成dontpanic/APANIC_CONSOLEdontpanic/APANIC_THREAD两个文件,前者能看出引起重启的时刻每个核的调用栈,后者能看出重启时刻所有线程的调用栈信息。

panic信息位于apanic_console的末段,首先的找到panic信息的有关描述。通过分析堆栈信息可以找到问题的根因。

如果是因为指针异常一般会有以下log信息:

Unable tohandle kernel NULL pointer dereference at virtual address 00000000

踩内存log一般如下:

Unable tohandle kernel paging request at virtual address 656d616e

踩内存问题一般很难定位,需要往前追溯看看有没有异常的log警告也需要重点关注。例如:字符串操作不当,引起的内存越界问题。

3. 开机问题

这个问题的现象就是机器一直在开机界面,有两种情况,一是静态LOGO;一种是动态LOGO

3.1 静态的LOGO的情景

1、硬件故障,基本adb都无法连接上,需要硬件同事帮忙分析。

主要可能出现的硬件故障有:

CPU(包括L1,L2 cache)、DDR EMMC BUS PMU(电源管理)

2、内核(BOOT)故障,不能连接adb,需要连接串口分析。

3zygote反复重启引起的问题,导致systemserver没有起来。

4、如果不是以上问题,就需要分析内核日志。

3.2 停在动态的LOGO界面

一般是因为开机时因为各种异常导致系统应用层面出现崩溃,一般还是可以正常使用adb shell的。

1、如果动画界面,是否卡死Systemserver

2、反复播放动画,是否Systemserver反复重启。

3、关注内核死锁问题。关注dmesg_sysrq.txt文件,文件的尾部都有SYSRQ信息,会打印出当前的D进程状态,可以逐个查看是否有死锁的情况。

4. 死机(定屏)问题

如何判断一个问题是否是一个死机问题?

对于Android平台,从现象上说,就是屏幕以及按键没有任何反应,给此设备打电话,也不会有任何反应,但是对于分析者来说,是插入USB线没有反应,也就是Windows的设备管理器,不会因为插USB线而出来新的设备(如果屏幕按键无反应,但出现了新的设备,那这个是后面要说的白屏问题)

需要收集哪些现场?

对于这类问题,我们当前的策略通常是需要抓取串口log,也就是说,如果出现这种情况的时候,没有连接串口,基本上是无能为力的(Google默认提供了一种机制叫做last_kmsg,似乎是可以在重启的时候把上次crashkernel log写到/proc/last_kmsg里面去),如果连接了串口,通过判断串口是否有输出,可以定位出内核到底死了没有,如果是kernel死,会打印出kernel crash的栈信息以及寄存器信息,可以根据栈信息,定位出是什么模块导致的;

简单点说,如果是对于死机问题,我们需要抓取串口log

如何分析:

如果一定要有秘籍的话,那么就是认真观察死之前的遗言!

通常都会有栈信息出来,根据栈信息就可以看到是那个函数引起的,所以相对来说好定位,当然也出现过出事的函数只是替罪羊,真正的罪魁祸首在幕后的情况,但是,打印的信息都会做出一定的暗示,透过现象看本质,不轻易下结论。

给出一些判断建议:

1、连接不了adb,也没有按键中断,只能连接jtag调试了;

2、连接不了adb,有按键中断,连接串口、按键触发panic

3、可以连接adb,触发SYSRQ,检查是否内核异常卡死,OOM(分析卡死原因、内存是否真的少了)。

5getevent是否上报,找出不上报原因;

6InputDispatch出现异常,队列爆了,无法正常分发事件;

7、界面无刷新,分析surfacefingerLCD驱动(显示异常定位)。

5. 黑屏问题

黑屏问题,很好确认,屏变黑了,拨电话没反应,并且维持这个状态很长一段时间,如果插入USB没有反应,那么它就是一个死机问题,请看死机部分;如果有反应,那么它就是我们这里说的黑屏问题了;

正常情况下,都应该是系统重启,所以它的情报搜集以及分析过程和上面说的重启是一样的!(但是,有种黑屏的现象是触屏,按键都无法响应,但是打电话还有反应,是我们说的点不亮的问题,这个问题通常是在睡眠或者唤醒的时候被阻塞住了,它的分析,比较复杂,需要在内核里的睡眠唤醒的核心加大量的信息来定位,通常是suspend的线程被阻塞了,导致后面的late_resume函数,也就是点亮lcd的动作一直没有被触发执行,因为它们是放在同一个work queue suspend_work_queue来做的,需要去检查为什么前面的suspend被阻塞了,当然,如果你对内核非常的熟悉,也能从串口或者dmesg信息里面看出蛛丝马迹,然后做对应的测试,这里就不讨论了)

6. 总结

1、当我们被测试部的同事急急忙忙的叫去看现场的时候,通常并不知道这是个什么样的现象,所以要尽量抓取足够多的信息。尤其是需要知道出现问题的时间点。

2、根据现场,初步判断是死机,重启,白屏中的哪种?

3、根据第二步的判断,如果是内核死机,则重点查看dmesg信息;如果是上层死机,重点查看tombstonebugreportlogcatanr;如果是内核重启,重点查看dmesg信息;如果是上层重启,重点查看logcatanr

4、然后就根据面的介绍,逐个分析,如果还无法定位的话,就需要添加自己的打印信息。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469468.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像目标分割_1 概述

6.1.1 什么是目标分割 定义&#xff1a;在计算机视觉领域&#xff0c;图像分割&#xff08;Object Segmentation&#xff09;指的是将数字图像细分为多个图像子区域&#xff08;像素的集合&#xff09;的过程。 图像分割的目的&#xff1a;简化或改变图像的表示形式&#xff0…

字符数组和strcpy

已知strcpy函数的原型是char *strcpy(char *strDest, const char *strSrc);&#xff0c;其中strDest是目的字符串&#xff0c;strSrc是源字符串。 &#xff08;1&#xff09;Write the function strcpy, dont call C/C string library.&#xff08;不调用C/C的字符串库函数&…

Django开发中问题和报错集合

记录django项目开发过程中的遇到的问题&#xff0c;导致原因和已经奏效的解决方法 常见报错UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xbc in position 852: invalid start byte 这个问题在一些电脑上做django开发时经常出现 要么是py文件运行是就报这个类似…

图像目标分割_2 FCN(Fully Convolutional Networks for Semantic Segmentation)

6.2.1 FCN 背景介绍 图像语义分割&#xff1a;给定一张图片&#xff0c;对图片上每一个像素点进行分类&#xff01;但是与图像分类目的不同&#xff0c;语义分割模型要具有像素级的密集预测能力才可以。 6.2.2 FCN介绍 6.2.2.1 全卷积网络 全卷积网络&#xff0c;模型由卷积…

Adbshell相关命令

Adb&shell相关命令 作者&#xff1a;韦启发 1、 过滤显示字符 adb logcat | grep MyApp adb logcat | grep -i myapp #忽略大小写。 adb logcat | grep --colorauto -i myapp #设置匹配字符串颜色。更多设置请查看 grep 帮助。 adb logcat | grep --colorauto 1679 …

求4个数字组成的不重复三位数,Python简洁解法

求4个数字组成的不重复三位数&#xff0c;Python解法 题目要求&#xff1a; 求所有由5,6,7,8组成的数字不重复的三位数 不重复的三位数&#xff0c;即不能出现555,566这种 通过分析&#xff0c;可以使用画树的方法来确定要求的三位数的值与个数 按照上图所示可以确定由5&am…

图像目标分割_3 SegNet + U-Net

6.3.1 SegNet背景 SegNet的主要动机是场景理解的应用。 难点&#xff1a;因此它在设计的时候考虑了要在预测期间保证内存和计算时间上的效率。分割的任务其实应用非常地广&#xff0c;需要理解各个像素之间的关系&#xff0c;比如要区分出人行道和车行道&#xff0c;建筑物和…

MIPI屏数据发送命令解析

MIPI数组发送那里有一个数组&#xff0c;这个数组包含寄存器和寄存器的值&#xff1a; 相当于: 0XC480寄存器下参数0X9C&#xff1b; 0XFF00寄存器下参数0XFF,0XFF,0XFF&#xff1b; 0XC0B5 尝试一下寄存器 0x08 0x18 0x48 0x58 试一下能不能旋转

面向对象之类的内建函数

类的特殊成员 上文介绍了Python的类成员以及成员修饰符&#xff0c;从而了解到类中有字段、方法和属性三大类成员&#xff0c;并且成员名前如果有两个下划线&#xff0c;则表示该成员是私有成员&#xff0c;私有成员只能由类内部调用。无论人或事物往往都有不按套路出牌的情况&…

图像目标分割_4 DeepLab-V1

6.4.1 DeepLab 背景 相比于传统的视觉算法(SIFT或HOG)&#xff0c;Deep-CNN以其end-to-end方式获得了很好的效果。这样的成功部分可以归功于Deep-CNN对图像转换的平移不变性(invariance)&#xff0c;这根本是源于重复的池化和下采样组合层。平移不变性增强了对数据分层抽象的能…

Python多线程单例的几种实现方式

目录&#xff1a; 单例模式在类中实现装饰器批量装饰实现单例模式 &#xff0c;且不丢失类型提示限制实例个数 1.重写__new__方法实现多线程情况下的单例模式 用new方法实现单例模式 import time, threadingclass Singleton:"""单例模式————最多只允许创…

图像目标分割_5 DeepLab V2 V3 V3+

6.5.1 DeepLab V2 6.5.1.1 改变特点 atrous convolution采用ASPP ( atrous spatial pyramid pooling) 多尺度获得更好的分割效果合并深度卷积网络和概率图模型方法&#xff0c;增强对物体边界的定位。基础层由VGG16转为ResNet 和v1不同&#xff1a; 通过多尺度输入处理或者多…

jQuery / zepto ajax 全局默认设置

jQuery / zepto 的 $.ajax 方法需要配置很多选项, 有些是很常用的每个 ajax 请求都要用到的, 可以全局设置, 避免每次都写. 注意: 此处用的 jQuery 版本是 1.8.3, zepto 版本是 1.1.6 和 1.2.0. 使用别的版本的要自己测试下. jQuery 的方法是 jQuery.ajaxSetup() $.ajaxSetup(…

Python导包、模块报错的问题

import报错No module named "xxx"的问题 如何将指定目录作为项目根目录&#xff0c;让项目根目录下的包/模块都可以直接导入&#xff1f;&#xff08;linux下&#xff09; Python导入模块时&#xff0c;解释器如何定位模块&#xff1a; 1.当前目录 2.内置模块列表 3…

CC2540 串口0 通道2配置

从图里面可以看出来&#xff0c;串口0有两个通道&#xff0c;一个通道是P02 P03两个GPIO口。 还有一个通道是P14 P15两个GPIO口。 在软件配置的时候&#xff0c;主要是配置的是一个通道相关的寄存器。 7.6.4 USART 0 The SFR register bit PERCFG.U0CFG selects whether to u…

图像目标分割_6 Mask RCNN

6.6.0 背景 目标检测和语义分割的效果在短时间内得到了很大的改善。在很大程度上&#xff0c;这些进步是由强大的基线系统驱动的&#xff0c;例如&#xff0c;分别用于目标检测和语义分割的Fast/Faster R-CNN和全卷积网络(FCN)框架。这些方法在概念上是直观的&#xff0c;提供…

cf 621E. Wet Shark and Blocks

神奇&#xff0c;矩阵乘法23333333333333333 递推式是很简单的&#xff08;连我这种不会DP的人都写出来了。&#xff09; 需要求出的是转移矩阵&#xff08;还是叫系数矩阵的&#xff09;&#xff0c;也是最这个东西用快速幂。 这个东西的i&#xff0c;j大概就表示从i到j的方案…

Python enum的使用总结

Python enum的使用总结 枚举(enumeration)在许多编程语言中常被表示为一种基础的数据结构使用&#xff0c;枚举帮助组织一系列密切相关的成员到同一个群组机制下&#xff0c;一般各种离散的属性都可以用枚举的数据结构定义&#xff0c;比如颜色、季节、国家、时间单位等 在Pyt…

ascii码转字符

在C语言中&#xff0c;ASCII码转字符非常简单。但是之前因为没有用到就没有去关注这方面的问题。 printf("%c\n",char(69)); E 下面是ASCII码表&#xff1a; BinDecHex缩写/字符解释0000 0000000NUL(null)空字符0000 0001101SOH(start of headline)标题开始0000…

SCI论文写作训练营笔记汇总01_概述+文献检索与管理

1 概述 1.1 适用人群 ①初涉科研&#xff0c; 目前或将来有英文科技论文发表需求的科研工作者 ②正在撰写或准备撰写英文科技论文的科研工作者 1.2 科技论文的基本结构 1.3 科技论文组成部分的写作方法 1.4 阅读文献的重要性 2、文献检索与管理 2.1 如何查找文献参考 2.2 文…