IOS 使用DSYM文件定位Bug 的具体位置
在项目的开发中,我们通常需要排查和修改测试中和发布后线上的一些bug,现在有一些第三方的bug分享和查找工具SDK,如腾讯的Bugly和听云等,包括苹果的开发工具xcode也自带 bug查找工具。那么这些工具又是如何获取到程序中的bug日志的?这里就要谈到DSYM文件了,一个很重要的东西。
什么是DSYM文件?——DSYM是符号表文件
那什么是符号表了?——符号表是内存地址与函数名、文件名、行号的映射表。符号表元素如下所示:<起始地址> <结束地址> <函数> [<文件名:行号>]
类似于android构建release包时的mapping文件,我们利用mapping文件可以将混淆后的APP运行时的现成堆栈信息还原成混淆前的堆栈信息(利用retrace 工具)。所以当应用crash时,我们可以利用crash时的堆栈信息得到对应到源代码的堆栈信息,还能看到出错的代码在多少行,所以能快速定位出错的代码位置,以便快速解决问题。而iOS应用crash时也有堆栈,release版的应用,crash时的堆栈信息,全是二进制的地址信息。如果利用这些二进制的地址信息来定位问题是不可能的,因此我们需要将这些二进制的地址信息还原成源代码中的函数以及行号,这时候就需要符号表了。举个例子如下图
Xcode编译项目后,我们会看到一个同名的 dSYM 文件,dSYM 是保存 16 进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,并且每次编译项目的时候都会生成一个新的 dSYM 文件,位于 /Users/<用户名>/Library/Developer/Xcode/Archives 目录下。iOS 设备中会有日志文件保存我们每个应用出错的函数内存地址,通过 Xcode 的 Organizer 可以将 iOS 设备中的 DeviceLog 导出成 crash 文件,这个时候我们就可以通过出错的函数地址去查询 dSYM 文件中程序对应的函数名和文件名。
如何将文件一一对应
每一个 xx.app 和 xx.app.dSYM 文件都有对应的 UUID,crash 文件也有自己的 UUID,只要这三个文件的 UUID 一致,我们就可以通过他们解析出正确的错误函数信息了。
1.查看 xx.app 文件的 UUID,terminal 中输入命令 :dwarfdump --uuid xx.app/xx (xx代表你的项目名)
2.查看 xx.app.dSYM 文件的 UUID ,在 terminal 中输入命令:dwarfdump --uuid xx.app.dSYM
3.crash 文件内第一行 Incident Identifier 就是该 crash 文件的 UUID。
在腾讯bugly和听云中都实现了符号表自动上传功能,可以直接在管理后台查看到bug报错的具体位置。原理也是把DSYM文件上传到他们自己的服务器。
例如听云的实现方式如下:
在Xcode工程对应Target的Build Phases
中新增Run Scrpit Phase
使用Xcode 自带的Crashes工具也能查找bug位置,这个是能查找release线上版本的,debug的无法查找。
iOS—lj