iOS通过dSYM文件分析crash

http://blog.csdn.net/hjy_x/article/details/20929095
重点是dwarfdump --uuid命令

我们在ios开发中会碰到的很多crash问题,如果Debug调试模式的话,我们可以往往很容易的根据log的输出定位到导致crash的原因,但对于已经上线的应用,或者是release环境包导致的crash,我们就需要一些特殊的手段来通过crash log进行分析定位了。

通过参考网上的一些资料,总结了一下,下面介绍一下通过dSYM文件以及crash log分析定位的方法。

1.导出crash log

通过Xcode的Organizer查看某台iphone设备的DeviceLog,选择需要的crash log,导出XXX.crash文件。

2.找到对应的app文件

找到当前iphone设备上安装的ipa文件,更改文件后缀名为zip,解压后得到Payload文件夹,你需要的app文件就在其中了。

3.找到对应build版本的dSYM文件

dSYM文件是iOS编译后保存16进制函数地址映射信息的文件,每次应用程序build后,都会生成对应的xxx.app, xxx.app.dSYM文件。

4.确定dSYM、app以及crash文件的关系

每一个xx.app, xxx.app.dSYM文件都拥有相应的uuid,crash文件也有uuid,只有三者uuid一至才表明之三者可以解析出正确的日志文件。
查看xx.app文件的uuid的方法,在terminal中输入命令:

dwarfdump --uuid xxx.app/xxx (xxx工程名)

查看xx.app.dSYM文件的uuid的方法,在terminal中输入命令:

dwarfdump --uuid xxx.app.dSYM (xxx工程名)

而.crash的uuid位于,crash日志中的Binary Images:中的第一行尖括号内。如:

armv7 <8bdeaf1a0b233ac199728c2a0ebb4165>

将对应的xxx.app.dSYM文件以及xxx.app文件以及xxx.crash文件拷贝到同一文件夹中,如:~/Desktop/DebugLog。

5.通过symbolicatecrash分析crash文件

Xcode有自带的symbolicatecrash工具,可以通过dSYM文件将crash文件中的16进制地址转换成可读的函数地址。symbolicatecrash工具位于:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash(Xcode 4.5)
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash(Xcode 5.0)

该文件是隐藏文件,可以通过如下命令查找并拷贝到系统目录下,并建立快捷方式。

1)打开终端,进入到symbolicatecrash工具所在的文件夹目录

cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/

2)查找确认是否存在symbolicatecrash

ls -al | grep symbolicatecrash

3)将symbolicatecrash工具拷贝到/usr/bin目录下

sudo cp symbolicatecrash /usr/bin/symbolicatecrash

4)设置DEVELOPER_DIR系统变量

cd ~/

vi .bash_profile

并输入如下内容
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

保存并退出

source .bash_profile

5)重启终端,确认是否已正确设置DEVELOPER_DIR系统变量

echo $DEVELOPER_DIR

查看输出结果是否为/Applications/Xcode.app/Contents/Developer

6)查看PATH系统变量是否存在如下路径/usr/bin

echo $PATH

7)如果PATH不存在如下路径/usr/bin,可在~/.bash_profile中添加如下代码

export PATH="/usr/bin:$PATH"

保存并退出

source .bash_profile

8)上述准备工作完成后,进入dSYM和crash文件对应的文件夹目录,如

cd ~/Desktop/DebugLog

9)执行如下命令,即可正确解析crash文件

symbolicatecrash xxx.crash xxx.app.dSYM > test.txt

注意:symbolicatecrash的参数顺序,否则会报类似如下错误

Use of uninitialized value $data in substitution (s///) at /usr/bin/symbolicatecrash line 678.

Use of uninitialized value $data in substitution (s///) at /usr/bin/symbolicatecrash line 681.

Use of uninitialized value $data in substitution (s///) at /usr/bin/symbolicatecrash line 685.

Use of uninitialized value in pattern match (m//) at /usr/bin/symbolicatecrash line 404.

Use of uninitialized value in scalar assignment at /usr/bin/symbolicatecrash line 418.

No crash report version in XXX.app.dSYM/ at /usr/bin/symbolicatecrash line 954.

今天就先到这里,希望对大家有所帮助。

方法1 使用XCode
这种方法可能是最容易的方法了。
 
需要使用Xcode符号化 crash log,你需要下面所列的3个文件:
1. crash报告(.crash文件)
2. 符号文件 (.dsymb文件)
3. 应用程序文件 (appName.app文件,把IPA文件后缀改为zip,然后解压,Payload目录下的appName.app文件), 这里的appName是你的应用程序的名称
 
把这3个文件放到同一个目录下,打开Xcode的Window菜单下的organizer,然后点击Devices tab,然后选中左边的Device Logs。
 
然后把.crash文件拖到Device Logs或者选择下面的import导入.crash文件。
 
这样你就可以看到crash的详细log了。 如下图: 
 
方法2 使用命令行工具symbolicatecrash
有时候Xcode不能够很好的符号化crash文件。我们这里介绍如何通过symbolicatecrash来手动符号化crash log。
 
在处理之前,请依然将“.app“, “.dSYM”和 ".crash"文件放到同一个目录下。现在打开终端(Terminal)然后输入如下的命令:
  
  
  1. export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer 
 
然后输入命令:
  
  
  1. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log 
 
现在,符号化的crash log就保存在appName.log中了。
 
方法3 使用命令行工具atos
如果你有多个“.ipa”文件,多个".dSYMB"文件,你并不太确定到底“dSYMB”文件对应哪个".ipa"文件,那么,这个方法就非常适合你。
 
特别当你的应用发布到多个渠道的时候,你需要对不同渠道的crash文件,写一个自动化的分析脚本的时候,这个方法就极其有用。
 
这里先介绍一个概念: UUID
 
什么是UUID
每一个可执行程序都有一个build UUID来唯一标识。Crash日志包含发生crash的这个应用(app)的 build UUID以及crash发生的时候,应用加载的所有库文件的[build UUID]。
 
那如何知道crash文件的UUID呢?
 
可以用:
  
  
  1. grep "appName armv" *crash 
 
或者
  
  
  1. grep --after-context=2 "Binary Images:" *crash 
 
可以得到类似如下的结果:
  
  
  1. appName.crash-0x4000 - 0x9e7fff appName armv7 <8bdeaf1a0b233ac199728c2a0ebb4165> /var/mobile/Applications/A0F8AB29-35D1-4E6E-84E2-954DE7D21CA1/appName.crash.app/appName 
 
(请注意这里的0x4000,是模块的加载地址,后面用atos的时候会用到)
 
如何找到app的UUID
可以使用命令:
  
  
  1. xcrun dwarfdump -–uuid <AppName.app/ExecutableName> 
 
比如:
  
  
  1. xcrun dwarfdump --uuid appName.app/appName 
 
结果如下:
  
  
  1. UUID: 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165 (armv7) appName.app/appName 
  2. UUID: 5EA16BAC-BB52-3519-B218-342455A52E11 (armv7s) appName.app/appName 
 
这个app有2个UUID,表明它是一个fat binnary。
 
它能利用最新硬件的特性,又能兼容老版本的设备。
 
对比上面crash文件和app文件的UUID,发现它们是匹配的:
  
  
  1. 8BDEAF1A-0B23-3AC1-9972-8C2A0EBB4165 
 
用atos命令来符号化某个特定模块加载地址
命令是:
  
  
  1. atos [-o AppName.app/AppName] [-l loadAddress] [-arch architecture] 
 
亲测,下面3种都可以:
  
  
  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7 
  2. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -arch armv7 
  3. xcrun atos -o appName.app/appName -arch armv7 
(注:这3行选任意一行执行都可以达到目的,其中0x4000是模块的加载地址,从上面的章节可以找到如何得到这个地址。)
 
文章开头提到crash文件中有如下两行,
  
  
  1. * 3 appName 0x000f462a 0x4000 + 984618  
  2. * 4 appName **0x00352aee** 0x4000 + 3468014   
 
在执行了上面的:
  
  
  1. xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 0x4000 -arch armv7 
 
之后,输入如下地址:
  
  
  1. 0x00352aee 
 
(crash文件中的第4行:4 appName **0x00352aee** 0x4000 + 3468014)
 
可以得到结果:
  
  
  1. -[UIScrollView(UITouch) touchesEnded:withEvent:] (in appName) (UIScrollView+UITouch.h:26) 
 
这样就找到了应用种到底是哪个模块导致的crash问题。
 
总结
本文分析了拿到用户的.crash文件之后,如何符合化crash文件的3种方法,分别有其适用场景,方法3适用于自动化crash文件的分析。

http://www.cocoachina.com/industry/20140514/8418.html



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值