qidao123.com技术社区-IT企服评测·应用市场

标题: iOS常见瓦解简介 [打印本页]

作者: 祗疼妳一个    时间: 2024-12-5 17:52
标题: iOS常见瓦解简介
1. 瓦解

多指在移动装备(如iOS、Android装备)中或不可移动装备(如:Windows、Linux等装备),
在打开或使用应用步伐时出现的突然退出停止的环境(类似于Windows的应用步伐瓦解)。
多体现为:应用步伐画面一闪而过,随即退回到桌面。
瓦解会影响用户体验,造成用户流失,因此,我们要重视瓦解

根据差别场景,瓦解网络方式差别
Xcode编译期间:


测试机获取:

Xcode->Window->Devices and Simulators

或者
设置->隐私->分析与改进
线上瓦解采集:

封装好的三方,直接接入的:友盟、bugly、听云
开源的SDK:KSCrash、plcrashreporter
2. 瓦解产生的原因

分别方式一:


2.1 cpu无法执行的代码


2.2 被系统强杀


2.3 语言触发非常


分别方式二:

除了上面的分别方式,瓦解还可以按:软件非常、硬件非常分别
软件非常:
软件非常重要来自 kill(),pthread_kill()。iOS 中的 NSException 未捕捉,abort 都属于这种环境。
硬件非常:
硬件的信号始于处理器 trap,是和平台相关的。野指针瓦解大部分是硬件非常。
软件非常的流程是:
   软件非常 -> Unix信号
  硬件非常的流程是:
   硬件非常 -> Mach非常 -> Unix信号

  

Mach 非常:

UNIX 信号:

当我们拦截信号处理之后是可以让步伐不瓦解而继承运行的,但是不发起如许做,由于步伐已经处于非常不可知状态。
看上图内里最终都会转换为 “UNIX信号”, 是不是代表我们只用监听 “UNIX 信号” 就够了呢?为什么还要拦截 Mach 非常呢?
不是所有的 "Mach非常” 范例都映射到了 “UNIX信号”
“UNIX信号” 在瓦解线程回调,如果遇到 Stackoverflow 标题,已经没有条件(栈空间)再执行回调代码了。
捕捉到非常信号后,在处理方法 handleSignalException 里通过 backtrace_symbols 方法就能获取到当前的堆栈信息。
堆栈信息可以先生存在本地,下次启动时再上传到瓦解监控服务器就可以了。
Mach是一个XNU的微内核核心

3. 瓦解日志包罗信息

根本信息:瓦解发生的日期、iOS 版本等
进程信息:瓦解进程的相关信息,好比瓦解陈诉唯一标识符、唯一键值、装备标识
非常信息:非常范例、非常编码、非常的线程;
线程回溯:瓦解时的方法调用栈
瓦解日志调用栈内容:

如许直接看瓦解信息的调用栈,是看不懂的
我们需要一个.DSYM文件,dSYM 是生存 函数地址映射信息的中转文件,其中包罗文件名、方法名、行号等信息,是和可执行文件的16进制函数地址一一对应的,通过分析瓦解的瓦解文件可以准确知道详细的瓦解信息。

一个ipa包,对应一个.DSYM文件
每次编译天生的 dSYM都会有所差别,通常 dSYM 中会有一个唯一标识,称作 UUID ,用以区分差别的 dSYM 文件。
   UUID(Universally Unique Identifier):一个app包对应一个UUID
UDID(Unique Device Identifier):一个手机装备对应一个UDID
  

通过.DSYM文件的解析,就可以找到对应的文件名和函数名
详细的做法?

方法一:

详细的做法:

   相对于起始地址的偏移量为 29796,运行时堆栈地址为 0x102a47464,运行时APP起始地址为 0x102a40000。
     由于 iOS 加载 Mach-O 文件时为了安全使用了 ASLR(Address Space Layout Randomization) 机制,导致二进制 Mach-O 文件每次加载到内存的首地址都会不一样,但是偏移量,加载地址,起始地址的盘算规则是一样的;
从上面我们可以得到 0x102a47464 (运行时地址) = 0x102a40000 (起始地址) + 29796(偏移量)这个公式。
因此通过 dSYM 的起始地址和偏移量就可以盘算出 0x102a47464 对应在 dSYM 中的地址为 0x100007464 = 0x0000000100000000 + 29296。
  

OS 瓦解日志在线符号化实践
方法二:使用下令atos

跟前面那个方法的理论是同等的,只是下令不一样
  1. atos -o 项目名.app.dSYM/Contents/Resources/DWARF/项目名 -l 基地址(运行初始地址) 偏移后的地址
  2. 笔者使用的命令参考如下
  3. atos -o Test.app.dSYM/Contents/Resources/DWARF/Test -l 0x1026b4000 0x1026B9904
复制代码
iOS dSYM详解和分析crash,ips文件
方法三:使用symbolicatecrash脚本

symbolicate:象征
symbolicatecrash是一个Perl脚本,随Xcode提供,专门用于符号化瓦解日志。你需要找到这个脚本的位置(通常在Xcode的App包内),然后在下令行中使用它,如下:
使用下令find /Applications/Xcode.app -name symbolicatecrash -type f获取到symbolicatecrash
/path/to/symbolicatecrash /path/to/MyApp.crash /path/to/MyApp.dSYM > Symbolicated.crash
在桌面上新建一个文件夹,把.app文件、.app.dSYM文件、.crash文件、symbolicatecrash工具,一起放到新建的文件夹下:

然后执行下令:
  1. export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
  2. ./symbolicatecrash JCrashDemo.crash JCrashDemo.app.dSYM > new.crash
复制代码
即可获取一个新的解析好的crash文件
使用symbolicatecrash解析瓦解日志
方法四:使用其他更便捷的脚本

即,将好几步要执行的步调,简单化
4. 开发中常见瓦解


unrecognized selector crash

当一个对象找不到对应的方法实现的时候,会报此类错误
在找不到方法时,查找方法将会进入方法forward流程,系统给了三次调停的机会,
所以我们要办理这个标题,在这三次均可以办理这个标题

KVO crash

KVO监听对象属性值的改变
KVO 一样平常使用造成瓦解的原因通常有以下几个:

NSNotification crash

当一个对象添加了notification之后,如果dealloc的时候,仍然持有notification,就会出现NSNotification范例的crash。
在iOS9以及iOS9以后,可以不做移除关照操纵
NSTimer crash

一般是在定时器被target强引用没有被释放,产生内存泄漏,或者在定时器触发的时候导致瓦解
办理方案:
1.NSTimer使用Block,对其target不强引用
2.是否找到一个合适的时机,在确定NSTimer已经失效的环境下,让NSTimer自动invalidate
3.使用中心变量
类族(NSArray,NSMutableArray,NSDictonary,NSMutableDictionary)


发起:

非主线程刷UI

UI刷新,必须在主线程操纵
在子线程中,需要刷新UI的时候,要切换到主线程
野指针


定义:当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍然指向已经回收的内存地址,此环境下该指针便称野指针
若操纵系统将这部分已经释放的内存重新分配给另外一个进程,而原来的步伐重新引用如今的失路指针,则将产生无法预料的结果。由于此时失路指针所指向的内存如今包罗的已经完满是差别的数据。

办理方法:

Xcode开启僵尸对象监听

使用MLeaksFinder或其他三方库,排查内存泄漏标题

使用JJException,淘汰App闪退
固然,最好做到:开发过程不使用,正式包开启


参考资料:
iOS 野指针处理
iOS野指针定位总结

Chat-GPT有关野指针的解释
问:iOS野指针错误一般由什么引起的?怎么排查与避免?

答:

iOS 开发中的野指针错误通常是指向一个已经被释放的对象的指针仍然被访问时发生的错误。这种错误可能导致应用瓦解或不稳固的行为。野指针错误的重要原因包括但不限于:
如何排查野指针错误:

如何避免野指针错误:

通过接纳这些措施,你可以显著淘汰应用中野指针错误的发生,进步应用的稳固性和可靠性。
   不得不说,回复的还蛮好的

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4