crash 潜水
参考:https://blog.csdn.net/qq_22795513/article/details/74590956?utm_source=bbsseo 及其他贡献值
App crash(全称Application crash) 潜水 分为:对于Crash可分为Framework/App Crash, Native Crash,以及Kernel Crash
crash 种类如下:
1.空指针
原因 :试图对空指针进行操作时(如读取空指针指向的内存),处理器就会产生一个异常
解决:在使用指针前加以判断,如果为空,则是不可访问的。
2.野指针:
原因:指向的是一个无效的地址,该地址如果是不可读不可写的,那么会马上Crash;如果访问的地址为可写,而且通过野指针修改了该处的内存,那么很有可能会等一段时间(其它的代码使用了该处的内存后)才发生Crash
解决:
1.在指针变量定义时,一定要初始化,特别是在结构体或类中的成员指针变量。
2.在释放了指针指向的内存后,如该指针不再置为NULL
3.通过代码分析工具也很难找出,只有通过专业的内存检测工具,如:bangerlee
1、指针变量有两层含义
1) 指针变量里存的是地址(它指向的变量的首地址)。
2) 指针变量有类型,类型说明了该指针指向的变量在内存中的大小
野指针和空指针的区别:
空指针:一般声明一个指针变量赋值为NULL,这就是空指针,各个类型的空指针都存在确确实实的内存地址,但是不会指向任何有效的值的内存地址,对空指针操作,例如访问属性和方法,会抛出空指针异常,因为空指针指向的内存地址没有对应的物理地址。
野指针:指那些释放内存,但是指针赋值为空,这时候的指针指向任意地址,(一个被删除的对象或没有申请访问受限内存区域的指针,野指针无法通过null逻辑进行区分,靠良好的编程规范)例如指向内核地址或不属于本程序的内存地址,程序会被kill,crash。
补充 :
内存泄漏:分为堆泄露和资源泄露 两种,内存分配失败或者内存分配成功却没有指针指向它(即无法操作该内存),会导致内存分配的越来越多,导致系统内存不够而终止程序
内存泄漏指系统未能及时释放已经不再使用的内存对象,多由代码逻辑导致
3.数组越界
原因:访问无效的地址。如果该地址不可读写,则会马上Crash;如果修改了该处的内存,造成内存破坏,那么有可能会等一段时间才在别处发生Crash。
解决:
所有数组遍历的循环,都要加上越界判断。
用下标访问数组时,要判断是否越界。
通过代码分析工具可以发现绝大部分的数组越界问题
4.整数除以零或其他数学异常
原因:整数除以零默认的处理方式是终止进程
解决:做整数除法时,要判断被除数是否为0的情况。
5.格式化输出参数错误
原因:与野指针类似,但是只会读取无效地址的内存,而不会造成内存破坏。其结果是要么打印出错乱的数据,要么访问了无读写权限的内存而立即宕机。
解决:在书写输出格式和参数时,要做到参数个数和类型都要与输出格式一致
6.操作数据库异常如:连接超时,获取数据为空格,主从库不一致
7.数据类型转换异常 如自动转换 和强制转换(数据丢失)
8.方法及参数错误
9.没有访问权限
10.存储异常
11.调用的方法或类 不存在
如何测试这些问题呢:
1.多线程运行应用
2.长时间负载
3.代码走查
概括crash 发生的层面:
1.接口返回值 异常
如:
[直接原因]:app无法解析接口返回值/获取不到要获取的参数/参数类型不对 导致客户端代码报错
[引起原因]:垃圾数据/网络问题导致接口超时或漏了数组元素/前后台没有统一参数类型标准/参数名错误/实体消失
[解决办法]:在网络顺畅/不顺畅情况下抓包,对着api文档一个一个的参数对比,返回值有数组可以横向对比,可能是其中某个元素内的某个参数和其他元素内的这个参数有内容不同/类型不同/为空/不存在/规范不同。
[测试方法]:1:后台不要返回这种垃圾数据,或者有垃圾数据要进行处理再返回给app。2:app要有一定的容错性,不能因为一个参数这么一点小事就导致崩溃(低级bug瞬间升级到致命bug)。所以要从俩边测试。1:先进行正常的接口测试,保证正常数据返回没有问题。再通过操作数据库或其他手段进行构造脏数据,测试服务器的错误处理能力。2:再利用mock或抓包工具,强行修改返回值,测试app端的容错能力。用脚本或手动把所有/特定 的参数进行更改,包括 类型/内容长度/为空/删除掉/不符合规范 等情况来测试app的容错性和成熟性。
其次网络问题也是有概率引起崩溃,就是在网络环境很恶劣 或变动频繁的情况下进行所有接口测试,保证返回值全面完整。观察接口返回是否有拉下的数组元素。因为app的超时判定 和服务器的超时判定是不统一的。可能接口超时要60秒,但是app只等待10秒钟,10秒没到就判定失败了,但这不是导致崩溃的原因。导致崩溃的原因在于服务器返回超时后(不是无网络,不是关掉wifi或数据流量),接口报什么http状态码,一般是502,app原则上是要对所有接口502都有对应处理和提示,但实际情况是,很多接口有提示不崩溃,更多的接口会崩溃。所以测试的时候要构造特殊环境,来让所以接口依次超时。方法可以是在抓包工具上打断点,然后不进行继续操作,挺着看app最终会不会崩溃。
实体消失问题导致崩溃,其实是接口规范上的原因,当因为先后操作,页面未及时刷新的情况,导致app对一个已经在后台数据库
2.内存问题
如:
[引起原因]:兼容不好/内存不足/内存泄露造成app开辟内存空间失败/内存泄漏。
[解决办法]:提醒用户更换手机或关掉后台其他app进程,崩溃的app要进行全面测试,定位到具体什么操作导致崩溃。
[测试方法]:先进行兼容性测试,用不同的操作系统/手机型号/品牌/系统版本/蓝牙版本去执行一些跟写入读取有关的功能的用例。用emmagee(7.0以上不可用)监控app,看到各种操作后,占用的内存是否超过预期。让开发规范代码,及时释放掉占用的存储空间。手机安装很多app,然后后台都打开,然后再运行自家app,观察其是否会崩溃频繁,可以用monkey测试(虽然monkey无法表明到底是什么原因引起崩溃,但是可以通过 观察后台干净/后台运行过多app 这俩种情况下多次测试,看是否因为后台运行过多app 就导致monkey崩溃概率高。
3.越界问题
如:
[引起原因]:需要操作的元素已经消失/代码错误,超出实体数量/读取or写入本地文件或缓存时的IO错误
[解决办法]:调查引起崩溃的具体操作步骤,然后提交开发解决,前端代码容错率需要提高。
[测试方法]:边界值测试为核心思想,测试正常情况有关数量的功能用例
要进行代码review1:保证代码没有错误,循环中没有超出实体数量。2:保证代码容错性高,每个循环都要有越界异常捕获并处理。/
要进行手动破坏性测试,1:如删除本地文件,比如app要调取本地缓存的4张图片,在app刚要调用的时候,已经选择好的时候,切换到本地文件管理中,删掉其中一个,那么app就会访问到一个不存在的文件,会引发越界等代码报错。2:破坏掉这个文件。那么app就会读取的时候发生io错误。等情况来进行测试
4.渲染问题
如:
[直接原因]:控件生成/调用受阻,导致前端app代码报错
[引起原因]:渲染过慢,操作过快,兼容性不好
[解决办法]:让用户换手机,或慢点点,重新设计避免用户连点造成的操作过快,重新设计减轻页面加载渲染负担,异步处理
[测试方法]:对复杂/卡顿页面进行快速操作来让本不应该出现在一起的俩个控件出现在一起,或用monkey最大速度测试(出现控件调用不及时 的情况较多)
5.权限问题
如:
[直接原因]:客户端未对无权限情况处理,导致代码报错
[引起原因]:用户访问未获取到系统相关权限的功能,客户端又未对此情况进行处理
[解决办法]:修改崩溃bug,设计此情况的处理机制,如提示用户去手动开权限,或自动退出等情况。
[测试方法]:关掉app所有的系统权限,然后去访问所有系统权限相关的页面和功能。例如:相册,照相,定位,开启wifi,蓝牙,gps 等等权限
6.优先级与交叉事件问题:
如:
[直接原因]:导致自家app突然被挂起或放置后台
[引起原因]:突然来电话,突然收短信,闹钟,会议提醒系统原生app等情况
[测试方法]:在各个页面,功能运行前中后。进行接电话/短信来测试。主要测试是否会影响电话/短信/长时间视频/同类消息推送或广告,电话/短信结束后 app是否能恢复到之前的页面,还是已经闪退被强关了。
7.系统自动旋转问题
如:
原生页面和h5页面 横竖屏切换
8.切换系统语言和弱网问题
如:
[直接原因]:客户端无法解析json返回值或接口响应较长或请求的接口中包含较多的api
[引起原因]:网络差,json串过长,图片没有压缩处理
[解决办法]:用户换更快网络,客户端对此操作增加等待时间。接口返回进行异步处理。增加翻页功能。
[测试方法]:用抓包工具模拟出弱网环境,包含丢包率,稳定性等元素。然后对接口返回值构造超长数据进行测试。
crash 原理 :
https://www.jianshu.com/p/bdd7d6cc75ef
crash 定位 与分析
1.gc 回收 工具monitor 监控
2. 查看异常
3.下载本地代码 进行try catch 捕获