iOS crash log 解析
iOS开发中,经常遇到App在开发及测试时不会有问题,但是装在别人的设备中会出现各种不定时的莫名的 crash,因为iOS设备会保存应用的大部分的 crash Log,所以可以通过 crash Log 来定位 crash 原因。
一. 获取iOS设备上的 crash log
1. 将iOS设备连接到电脑上,打开 Xcode -> Organizer -> Devices,找到该台设备,在 Device logs 中找到 crash log(后缀为 .crash 的 log 文件),将其导出即可。
2. 如果你的应用已经上架App Store,那么开发者可以通过iTunes Connect(Manage Your Applications - View Details - Crash Reports)获取用户的crash log。不过这并不是100%有效的,而且大多数开发者并不依赖于此,因为这需要用户设备同意上传相关信息,详情可参见iOS: Providing Apple with diagnostics and usage information摘要。
二. 解析iOS crash log
获取到的 crash log 中的相关信息都是 16 进制的内存地址,并不能定位崩溃的代码,所以需要将 16 进制的内存地址解析为对应的类及方法。
解析 crash log 需要使用上传应用时所发送的 .app 及 .sYSM 两个文件(所以每次上传新版本时都要保存这两个文件,不然没法解析 crash log),可以将 .app .dYSM 及crash log文件拷贝到同一个文件夹下,使用 Symbolicatecrash 进行解析。
获取 .app 及 .dYSM 文件:在iOS开发中,需要使用Xcode打包生成 .xcarchiver 文件,可以在Xcode - > Organizer - > archive 中进行管理并导出相应的 .xcarchiver 文件,.xcarchiver 文件中就包含 .app 及 .dYSM 文件。
Symbolicatecrash 是一个隐藏文件,并且独立于Xcode,位置在:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash
在利用 Symbolicatecrash 进行解析之前,要检查 .app .dYSM 及 crash log 三个文件的uuid是否一样,只有三者都一样才能进行解析。查看三个文件的 uuid 方法如下:
1. 查看xx.app文件的uuid的方法,在 terminal.app 中输入:
$ dwarfdump --uuid xxx.app/xxx (xxx工程名)
2. 查看xx.app.dSYM文件的uuid的方法,在命令行输入:
$ dwarfdump --uuid xxx.app.dSYM (xxx工程名)
3. 查看 crash log 文件的 uuid的方法:
在 crash log 文件中,找到 Binary Images: 项目名后面第一个尖括号中的一串码就是改 crash log 文件的 uuid。
利用 Symbolicatecrash 进行解析:
在 terminal.app 中输入如下命令:
$ ./symbolicatecrash xxx.crash xxx.app.dSYM > test.log
该命令会将 crash 文件解析成 test.log 文件,test.log 就是可读的函数文件。
输入上述命令可能会出现Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 53.这个错误。
如果出现上述错误,输入命令:export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer,
然后继续执行./symbolicatecrash xxx.crash xxx.app.dSYM > test.log可以成功
三. 其他解析(根据地址解析):
解析某一个地址的内容
方法一:
$ xcrun atos -o xxx.app/xxx -arch armv7 0x38ad42f9 0x38ad42f9 0x38ad42f9(多个16进制地址,使用空格分开)
方法二:
$ dwarfdump -–lookup 0x000036d2 -–arch armv6 xxx.app.dSYM
如果根据以上两个方法操作,均提示找不到地址的话,可以使用方法三:
方法三:
查找以下内容所对应的地址:
(当前代码行地址 = 当前地址 + 地址偏移量,地址偏移量为十进制数值)
10 TestTransform 0x00057132 0x4f000 + 33074
1. 先说第一种比较简单的方法利用 "当前地址" 和 "当前代码行地址"
$ xcrun atos -o TestTransform.app/TestTransform -arch armv7 0x3d000 0x0004fc5c
//输出结果:
bddeMacBook-Pro:1 baidu$ xcrun atos -o /Users/baidu/Desktop/1/TestTransform.app/TestTransform -l 0x3d000 0x0004fc5c
got symbolicator for /Users/baidu/Desktop/1/TestTransform.app/TestTransform, base address 4000
main (in TestTransform) (main.m:16)
2. 第二种相对复杂一点,涉及到地址的偏移,首先查看起始地址,即使每次iOS app启动都会加载(main module)主模块在不同的内存地址,但是dSYM文件假设你的main module加载在地址0x1000(大多数情况是这个,也有0x4000的)。
获取此地址的方法:
$ otool -arch armv7 -l /Users/cnstar-tech/crash/xxx.app/xxx | grep -B 1 -A 10 "LC_SEGM" | grep -B 3 -A 8 "__TEXT"
调用以上方法返回结果如下:
Load command 1
cmd LC_SEGMENT
cmdsize 600
segname __TEXT
vmaddr 0x00004000
vmsize 0x00014000
fileoff 0
filesize 81920
maxprot 0x00000005
initprot 0x00000005
nsects 8
flags 0x0
看到vmaddr显示为0x00004000。
然后查看 "TestTransform 0x00057132 0x4f000 + 33074" 使用 起始地址+地址偏移量如:
0x4000 + 33074 = 0xc132 (注意:前面为前面为16进制后面为10进制相加,要都转换成10进制相加,把得出的结果转换成16进制)
就可以使用 "0xc132" 地址查看内容了:
//方法一:
$ dwarfdump --lookup 0xc132 --arch armv7 TestTransform.app.DSYM
//输出结果:
----------------------------------------------------------------------
File: TestTransform.app.DSYM/Contents/Resources/DWARF/TestTransform (armv7)
----------------------------------------------------------------------
Looking up address: 0x000000000000c132 in .debug_info... found!
0x00003947: Compile Unit: length = 0x00007b6e version = 0x0002 abbr_offset = 0x00000000 addr_size = 0x04 (next CU at 0x0000b4b9)
0x00003952: TAG_compile_unit [1] *
AT_producer( "Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)" )
AT_language( DW_LANG_ObjC )
AT_name( "/Users/baidu/Desktop/TestTransform/TestTransform/ViewController.m" )
AT_low_pc( 0x0000a950 )
AT_stmt_list( 0x0000089f )
AT_comp_dir( "/Users/baidu/Desktop/TestTransform" )
AT_APPLE_major_runtime_vers( 0x02 )
0x00003c22: TAG_subprogram [39] *
AT_name( "__29-[ViewController aaaaaaaaaa:]_block_invoke" )
AT_decl_file( "/Users/baidu/Desktop/TestTransform/TestTransform/ViewController.m" )
AT_decl_line( 191 )
AT_prototyped( 0x01 )
AT_APPLE_isa( 0x01 )
AT_accessibility( DW_ACCESS_public )
AT_low_pc( 0x0000c09c )
AT_high_pc( 0x0000c182 )
AT_frame_base( r7 )
0x00003c46: TAG_lexical_block [34] *
AT_low_pc( 0x0000c0d6 )
AT_high_pc( 0x0000c17e )
Line table dir : '/Users/baidu/Desktop/TestTransform/TestTransform'
Line table file: 'ViewController.m' line 193, column 0 with start address 0x000000000000c11e
Looking up address: 0x000000000000c132 in .debug_frame... found!
0x00000160: FDE
length: 0x0000000c
CIE_pointer: 0x00000000
start_addr: 0x0000c09c __29-[ViewController aaaaaaaaaa:]_block_invoke
range_size: 0x000000e6 (end_addr = 0x0000c182)
Instructions: 0x0000c09c: CFA=4294967295+4294967295
//方法二:
$ xcrun atos -o /Users/baidu/Desktop/1/TestTransform.app/TestTransform 0xc132
//输出结果:
__29-[ViewController aaaaaaaaaa:]_block_invoke (in TestTransform) (ViewController.m:193)
四. 如何判断两个 crash log 文件的 crash 是同一个原因:
1. 可以先比较 Triggered by Thread 看看是否为同一个线程,不同,则不是同一原因。
2. 如果有 Last Exception Backtrace,可以先比较 Last Exception Backtrace 中地址的行数,行数不同则原因不同,行数如果相同可以将两个 Last Exception Backtrace 中的地址逐个进行比较,(一般最开始几行和最后几行都是调用系统函数,所以地址都是一样的),直到出现第一个不一样的地址,可以用 dwarfdump 分别解析两个地址,如果解析得到的方法不一样,则 crash 原因可不一样。
五. Xcode 中 Organizer 自动解析:
如果项目是在自己机器上打包的,可以将iOS设备连接到电脑上,这样该设备中的 crash log 就会被 Organizer 自动进行解析,如果没有自动解析,可以 右击 crash log 选择 re-symbolicate 进行解析。(之所以 Organizer 可以进行自动解析,是因为在打包的时候会建立 .app 及 .dYSM 两个文件的索引,所以可以自动解析 crash log 文件)
也可以进行手动建立索引,即将该 App 的 .app 及 .dYSM 两个文件拷贝到同一个文件夹中,然后再用 midimport foldername 命令进行手动建立索引,然后,将 crash log 文件导入 Xcode Organizer 中,就会进行自动解析。(可以批量导入 crash log 文件,批量进行解析)
六. 使用专门的 crash log 解析工具进行解析:
比如QuincyKit, Crashlytics, Flurry等。
iOS crash log 解析的更多相关文章
- iOS crash log 解析 symbol address = stack address - slide 运行时获取slide的api 利用dwarfdump从dsym文件中得到symbol
概述: 为什么 crash log 内 Exception Backtrace 部分的地址(stack address)不能从 dsym 文件中查出对应的代码? 因为 ASLR(Address spa ...
- iOS: Crash文件解析(一)
iOS Crash文件的解析(一) 开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退.脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断. ...
- ios crash log
1.IOS策略 1.1 低内存闪退 前面提到大多数crash日志都包含着执行线程的栈调用信息,但是低内存闪退日志除外,这里就先看看低内存闪退日志是什么样的.我们使用Xcode 5和iOS 7的设备模拟 ...
- ios Crash Log 分析汇总
方法一: 1.xcode 有自带的symbolicatecrash,可以将.crash文件中的16进制地址转换成可读的函数地址. symbolicatecrash位于: /Applications/X ...
- AtoS查看iOS Crash log中的16进制代码日志
注意:crash_log一定要和打包时的archive对应上: 方法1)在Orgnizer里找到某一个archive,即:/Users/handywang/Library/Developer/Xcod ...
- 别用symbolicatecrash来解析crash Log了
今天突然发现了一个解析iOS crash log的好方法,忍不住来分享一下. 相信每个做iOS开发的TX都应该不会对symbolicatecrash陌生,我们第一次遇到真机上产生的崩溃日志时,在网上搜 ...
- 浅谈 iOS 之 Crash log 符号化
其实,对于做移动 APP 开发的同学来说,质量和体验都是同等重要的.一个 APP 应用如果经常「闪退」,是产品质量很差的一个体现,那么用户体验就更不用再提了. *** 上面是笔者截取的国外一家公司对用 ...
- iOS Crash文件的解析
iOS Crash文件的解析 开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退.脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断.联想起 ...
- iOS 几种常用的 crash log 崩溃信息调试方法
前言:crash log 对 定位崩溃问题 ,并且不容易复现,尤其是及时对appstore 上正在运营的 app 的迭代改进来说 非常重要. 1 crash两种情况 1.1 测试环境下 追踪bug 1 ...
随机推荐
- [php] phar
build.php打包www目录: <?php class A{ public $a = 1; } $p = new Phar('test.phar',0,'test.phar'); $p-&g ...
- YottaChain主网全面上线预示商业应用的落地区块链云存储不一样的云
Yottachain存储网12月24日平安夜全面启动,意味着全球首个可商用的区块链存储公链全面落地.对于数据存储来说,小到我们个人的照片文档,大到政企机构数据库资料,都是互联网生活中如影随形的标配. ...
- 父工程 pom版本
<!-- 集中定义依赖版本号 --> <properties> <junit.version>4.12</junit.version> <spri ...
- 对logistic回归分析的两重认识
logistic回归,回归给人的直观印象只是要求解一个模型的系数,然后可以预测某个变量的回归值.而logistic回归在应用中多了一层含义,它经常应用于分类中.第一重认识:logistic是给真正的回 ...
- python每日练习0730
""" 1. 现有面包.热狗.番茄酱.芥末酱以及洋葱,数字显 示有多少种订购组合, 其中面包必订,0 不订,1 订,比如 10000,表示只订购面包 "&quo ...
- xcode7 添加个人账户 is not on any development teams
XCODE7已经可以免费真机测试, 但添加个人账户后,显示 is not on any development teams , 解决办法: 点击 “-” 删除当前账户,退出XCODE重新打开再添加即可 ...
- win7连接无线网出现黄色感叹号怎么办?
用win7连接无线网,出现黄色感叹号: 1.IP冲突,“网络中心”-“无线网属性”,手动改下IP,子网掩码,网关,DNS 2.360断网急救箱修复问题
- 【2019 Multi-University Training Contest 10】
01: 02: 03:https://www.cnblogs.com/myx12345/p/11671692.html 04: 05:https://www.cnblogs.com/myx12345/ ...
- C# 调用delphi编写的dll
技术实现 如何逐步实现动态库的加载,类型的匹配,动态链接库函数导出的定义,参考下面宏定义即可: #define LIBEXPORT_API extern "C" __declspe ...
- [CSP-S模拟测试]:Park(树上DP)
题目描述 公园里有$n$个雕像,有$n-1$条道路分别连接其中两个雕像,任意两个雕像可以直接或间接相连.现在每个景点$i$聚集着$P_i$只鸽子,旅行家手里有$v$数量的面包屑. 一旦旅行家在雕像$i ...