iOS_怎么分析AppStore上面的Crash Log

如果用户的手机同意了发送诊断内容,那么,app崩溃的时候就会把log发送的app store,然后我们就能够下载,分析。

以下是crash log的一部分

Last Exception Backtrace:
0 CoreFoundation 0x30acaf46 exceptionPreprocess + 126
1 libobjc.A.dylib 0x3af0b6aa objc_exception_throw + 34
2 CoreFoundation 0x30a0152e -[__NSArrayM objectAtIndex:] + 226
3 appName 0x000f462a 0x4000 + 984618
4 appName 0x00352aee 0x4000 + 3468014
…
18 appName 0x00009404 0x4000 + 21508

其中,第3、4、18行的16进制地址代表什么内容我们不得而知,需要去解析才能获得。


1、使用工具symbolicatecrash

使用工具synbolicatecrash必须依赖于.dSYM文件,.dSYM文件是archive的时候从.archive文件中提取的,每次release版本的时候读需要保存好它,以便今后分析各个版本的crash log。
synbolicatecrash工具是xcode自带的一个工具,我的Xcode6.3在以下目录中能找到它。
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/synbolicatecrash
synbolicatecrash是一个独立的工具,可以拷贝出来使用。

我们把synbolicatecrash、.crash文件、.dSYM文件、.app文件(可以从.dSYM文件中提取)放到一个文件夹下。

首先让我们确认下.crash文件、.dSYM文件、.app文件的UUID是否相同,只有UUID相同了才能解析。
提取.app文件的UUID:
执行命令:xcrun dwarfdump --uuid appname.app
得到结果:UUID: E70CA32E-303D-387D-9A60-7D4402511F42 (armv7) appname.app

提取.dSYM文件的UUID:

执行命令:xcrun dwarfdump --uuid appname.app.dSYM
得到结果:UUID: E70CA32E-303D-387D-9A60-7D4402511F42 (armv7) appname.app.dSYM/Contents/Resources/DWARF/appname.app

提取.crash文件的UUID:

执行命令:grep "appName armv" *crash 或者 grep --after-context=2 "Binary Images:" *crash

得到结果:appname.crash:0x9000 - 0x320fff appname armv7 <e70ca32e303d387d9a607d4402511f42> /var/mobile/Containers/Bundle/Application/772F5038-6FA1-4D18-9057-F57BAF1EC240/appname.app/appname
其中<e70ca32e303d387d9a607d4402511f42>就是UUID
提取.crash文件的UUID不仅可以用命令行,还可以直接打开.crash文件,找到Binary Images:区域,同样会有以上命令行得出的结果

可以看到以上三个文件的UUID是相同的,代表我们可以去解析了。

先执行命令:export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
然后再执行命令:symbolicatecrash appname.crash appname.app.dSYM > appname.log
这样解析过后的crash log就在appname.log文件中了。


2、使用命令行工具atos

使用atos之前,先理解下什么是模块加载地址。模块加载地址就是每次app启动都会加载主模块(main module)到一个地址,这个地址相当于一个起始地址。
Last Exception Backtrace:
0 CoreFoundation 0x30acaf46 exceptionPreprocess + 126
1 libobjc.A.dylib 0x3af0b6aa objc_exception_throw + 34
2 CoreFoundation 0x30a0152e -[__NSArrayM objectAtIndex:] + 226
3 appName 0x000f462a 0x4000 + 984618
4 appName 0x00352aee 0x4000 + 3468014
…
18 appName 0x00009404 0x4000 + 21508

上面crash log中的0x4000就是模块加载地址。
先执行命令:
xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName 0x4000 -arch armv7
然后再输入:
0x00352aee
得出结果:
-[UIScrollView(UITouch) touchesEnded:withEvent:] (in appName) (UIScrollView+UITouch.h:26)
这样就解析出来了。

有时候的crash log是下面这样的:
0 appname 0x001b27d7 appname + 1394647
1 appname 0x001b2f05 appname + 1396485

看不出起始地址,只有最终地址和地址偏移量。但是起始地址可以算出来。
先把1394647转换成16进制,在用0x001b27d7减去前面转换的值,得出的值就是起始地址。

你可能感兴趣的:(iOS_怎么分析AppStore上面的Crash Log)