前言
在日常测试iOS中会经常遇到App崩溃的情况,然后给研发提bug。如果就提bug就有一两句话描述,研发很难精准排查问题,所以作为测试人员需要提供崩溃日志或者崩溃堆栈辅助研发排查问题。
本文介绍几种常用获取崩溃日志的方法,可以帮助大家在工作中提高工作效率和协作效率。
iOS获取日志方法
Xcode工具
先来介绍一种最简单的方式使用Xcode工具方式,手机和mac连接后,打开Xcode选择window进入Organizer,在Organizer窗口上,选中Devices 标签栏。
image
在左侧的导航面板上,选中View Device Logs,如下图所示:
Logs菜单就可以看到mac曾经同步过的iOS设备的崩溃日志。
libimobiledevice工具
可能有些同学电脑并没有安装Xcode工具,Xcode的安装下载和安装比较麻烦。这里介绍一种使用第三方工具libimobiledevice的方法。
libimobiledevice是什么?
libimobiledevice又称libiphone,是一个开源包,可以让Linux支持连接iPhone/iPod Touch等iOS设备。
ideviceinstaller是libimobiledevice中的一个命令行工具,ideviceinstaller可以实现安装app,卸载app查看当前电脑连接的设备等操作,和Android的adb命令相似。
libimobiledevice安装
- brew update
- brew install libimobiledevice libimobiledevice中并不包含ipa的安装命令,所以还需要安装
- brew install ideviceinstaller
- 卸载 brew uninstall libimobiledevice
ideviceinstaller常用命令
命令安装一个ipa文件到手机上,如果是企业签名的,非越狱机器也可以直接安装了。
- 安装ipa包,卸载应用
ideviceinstaller -i xxx.ipa
- 命令卸载应用,需要知道此应用的bundleID
ideviceinstaller -U [bundleID]
- 查看系统日志
idevicesyslog
- 查看当前电脑连接的设备
idevice_id --list
打印出来的是udid
- 屏幕截屏
idevicescreenshot
- 获取设备时间
idevicedate
- 获取设备名称
idevicename
idevicecrashrepor崩溃日志
libimobiledevice中的idevicecrashreport工具可以导出真机crash日志,工具位置在tools下。
参数介绍:
代码语言:javascript复制-e, --extract extract raw crash report into separate '.crash' file
-k, --keep copy but do not remove crash reports from device
保存到本地文件夹中,需要先手动创建
-d, --debug enable communication debugging
-u, --udid UDID target specific device by its 40-digit device UDID
设备的udid
-h, --help prints usage information
用法:
代码语言:javascript复制idevicecrashreport -u 86616cbaa40e52d3f9236ec982dd6f1e933a44bd -e -k /Users/xinxi/Desktop/crash
idevicecrashrepor工具有个缺点在,本地文件夹中导出手机所有的crash日志,没有过滤自定包名的功能、导出的数据量太大了,不方便查看。
但是可以通过修改源码可以增加grep包名功能,导出自定包名的crash日志,如果需要源代码可以关注公众号回复"崩溃日志"即可获取。
过滤包名用法:
代码语言:javascript复制idevicecrashreport -u 25228488f97b79c515ab32a2792b83e24ee022de -e -g LuoJiFM -k /Users/xinxi/Desktop/crashnew
文件格式: LuoJiFM-IOS-2017-05-18-180437.ips.synced,然后把.synced去掉。
崩溃日志符号解析
通过上面两种方式,我们可以拿到crash后的文件。但是crash日志包含很多字符是16进制的,无法看到具体的类名和方法名,所以需要通过把crash文件符号化。
准备工作:
创建一个crashlog的文件夹
转化符号工具:
dsym(符号表文件)
相当于类名和方法名的参考表,Xcode打包的时候会自动产生,我本地的路径在:
代码语言:javascript复制~/Build/Products/ONLINE-iphonesimulator/LuoJiFMIOS.app.dSYM
崩溃日志
用idevicecrashreport工具导出,或者用xcode查看
symbolicatecarsh
symbolicatecarsh是xcode自带解析crash的工具,一般会在xcode安装包下
搜索本地symbolicatecarsh文件
命令:
代码语言:javascript复制find /Applications/Xcode.app -name symbolicatecrash -type f
我本地的文件地址:
代码语言:javascript复制/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
给symbolicatecarsh文件权限
命令:
代码语言:javascript复制export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
把这三个都放到crashlog文件夹中
代码语言:javascript复制cd crashlog的文件夹下
转化执行命令:
代码语言:javascript复制./symbolicatecrash LuoJiFM-IOS-2017-04-26-152505.crash LuoJiFMIOS.app.dSYM > newcrash.log
执行过程有出现个warning,可以忽略
代码语言:javascript复制Warning: Unable to symbolicate from required binary: /Users/xinxi/Library/Developer/Xcode/iOS DeviceSupport/10.3.1 (14E304)/Symbols/System/Library/Frameworks/CoreMotion.framework/CoreMotion
手动制造一个崩溃
在启动的时候的增加一处断言失败
代码片段:
//判断是否点击了随便看看按钮。 if ([FMAccountUtils isAppLogin] || UDBool(kUserDefault_IsCasualLook) == YES){ NSAssert(1 == 2, @"NSAssert test"); NSLog(@"NSAssert test",1); //断言崩溃 return; }
崩溃日志分析
crash文件文件: LuoJiFMIOS_2018-04-14-211457_xinxideMacBook-Pro.crash
崩溃日志片段
进程信息
代码语言:javascript复制Process:
LuoJiFMIOS [49850]
Path: /Users/USER/Library/Developer/CoreSimulator/Devices/DDAC13B0-786D-4DC7-A920-4BEAF56CD616/data/Containers/Bundle/Application/75271871-1E72-4F00-94E0-DC7A353C939B/LuoJiFMIOS.app/LuoJiFMIOS
Identifier: LuoJiFMIOS
Version: 3.1.9 (3.2.3)
Code Type: X86-64 (Native)
Parent Process: launchd_sim [49410]
Responsible: LuoJiFMIOS [49850]
User ID: 501
设备信息
代码语言:javascript复制Date/Time: 2018-04-14 21:10:43.057 0800
OS Version: Mac OS X 10.13.2 (17C88)
Report Version: 12
Bridge OS Version: 3.0 (14Y661)
Anonymous UUID: B687F0B1-763A-73D8-85CC-AD93B3C9F5D8
Sleep/Wake UUID: E387E09E-8D4A-413B-B96F-01861A8A0708
Time Awake Since Boot: 53000 seconds
Time Since Wake: 1800 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
异常
代码语言:javascript复制Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
原因,其中reason就是具体原因
代码语言:javascript复制Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSAssert test'
terminating with uncaught exception of type NSException
abort() called
CoreSimulator 494.33 - Device: iPhone SE - Runtime: iOS 11.2 (15C107) - DeviceType: iPhone SE
特定于应用程序的追溯,Application Specific Backtrace 1:
从红框中可以看出在AppDelegate setRootController中