自动化工具之python崩溃日志解析脚本
很多测试人员在测试途中,或者开发者在自测的途中,会遇到APP crash的情况。
一般的bug,一个合格的测试可以给出明确的重现步骤让开发者清晰地知道bug原因;
也有不少bug,很多时候是偶现的,很可能无法再次重现出来,无法重现出来的bug是开发者头疼的,测试一般会给出bug的截图和重现步骤;
而一般crash是比较严重的问题,这个时候崩溃日志就尤为重要了,把崩溃日志send给开发人员,如此才能让开发者快速定位到错误的原因和位置。
旧的解析崩溃日志的方式
在以前我们是这么解析崩溃日志的
- 桌面新建一个Crash文件夹
- 去目录
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/
下把symbolicatecrash
文件拷贝到我们刚才的Crash文件夹中 - 找到溃程序对应的.dSYM文件,拷贝到我们刚才的Crash文件夹中 比如叫
test.dSYM
- 把测试人员给我们的崩溃日志也当道Crash文件夹中,比如叫
1.crash
- 打开终端 CD到Crash文件夹中 执行命令
./symbolicatecrash 1.crash test.dSYM > 1.log
这样解析好的日志就到了1.log文件中,我们用文本编辑器只需打开即可查看
但是有的时候,一不小心放进去的符号文件版本不对应,那么解析出来的1.log和原来的1.Crash内容是一样的,这时候我为了匹配崩溃日志和符号文件的版本,还要使用下面的命令
-
首先查看dSYM文件的UUID 才刚才的Crash文件夹中执行
dwarfdump --uuid test.dSYM
终端会输出类似这样的信息UUID: F28A8BE6-4B0B-38C9-9F28-829B4121C88B (armv7) test.dSYM/Contents/Resources/DWARF/*******
UUID: C8424837-BC0F-3F9F-A109-A42271C3E14E (arm64) test.dSYM/Contents/Resources/DWARF/*******
2.用文本编辑器打开1.crash
,拉到其中一处Binary Images:
的地方,如图找到UUID
- 若步骤1中包含步骤2中的uuid,那么是匹配的,能正确解析崩溃日志,否则会解析失败
用自己的脚本去解析
前面的步骤去解析崩溃日志有点繁杂,所以写了一个python脚本,用于一步解析崩溃日志并校验uuid
废话不多说,上代码(decode.py)
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import sys
def txt_wrap_by(start_str, end, html):
start = html.find(start_str)
if start >= 0:
start += len(start_str)
end = html.find(end, start)
if end >= 0:
return html[start:end].strip()
def getCrashFileUUID(filePath):
f = open(filePath) # 返回一个文件对象
line = f.readline() # 调用文件的 readline()方法
uuid = ''
while line:
if line.startswith('Binary Images:'):
desLine = f.readline()
uuid = txt_wrap_by("<",">",desLine)
break
line = f.readline()
f.close()
return uuid.upper()
def getTagFileUUID(filePath):
ines = os.popen('dwarfdump --uuid ' + filePath).readlines()
uuids = []
for item in ines:
uuid = txt_wrap_by('UUID:', ' (', item)
uuid = uuid.replace('-','').upper()
uuids.append(uuid)
return uuids
def getDevDir():
return os.popen('xcode-select -p').readlines()[0].replace('\n', '')
def getSymbolicatecrashPath():
return getDevDir().replace('Developer', '') + 'SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash'
if len(sys.argv) <= 2:
print "sorry! you must input 2 arg like this:"
print "\t python decode.py 1.crash xxxx.app.dSYM"
exit(0)
crashFilePath = sys.argv[1]
dsymFilePath = sys.argv[2]
print "crashFilePath:" + crashFilePath
print "dsymFilePath:" + dsymFilePath
outPutFilePath = crashFilePath + ".log"
#检查uuid是否匹配
crashUUID = getCrashFileUUID(crashFilePath)
tagUUIDS = getTagFileUUID(dsymFilePath)
if crashUUID in tagUUIDS:
print "UUID match success! " + crashUUID
else:
print "UUID not match"
exit(0)
#设置环境变量
cmd = "export DEVELOPER_DIR=\"" + getDevDir()+"\"\n"
symbolicatecrashPath = getSymbolicatecrashPath()
cmd += symbolicatecrashPath + " " + crashFilePath + " " + dsymFilePath + ' > ' + outPutFilePath + '\n'
cmd += 'open '+outPutFilePath
print os.popen(cmd)
这段脚本在解析崩溃日志之前自己做了UUID的校验,若UUID不匹配则不取解析,直接提示UUID不匹配
运行环境
- mac OS系统
- python 2.7(系统自带的版本)
- 终端执行
使用步骤
- 建立一个Crash文件夹
- 将崩溃日志1.crash,符号文件test.dSYM放到Crash文件夹中
- 终端cd到Crash文件夹中,执行如果解析成功,终端显示如下
dsymFilePath:test.dSYM
UUID match success! 2DD2DDA45509307BBABD93ADCF36492A
解析后的日志写到了1.log中,这里输出的文件名不用写
如果UUID不匹配,提示如下
dsymFilePath:test.dSYM
UUID not match