获取crash日志一般有两种:
iphone 手机自动收集的.crash 会存储在手机上,通过Xcode 可以导出来。
Mac控制台等其他工具抓取到的 crash日志。
1. 在iphone 手机自动收集的crash,可以通过Xcode 上的工具导出xxx.crash文件使用xcode 自带的symbolicatecrash命令就可以复原
*** 作如下:
将“.dSYM”和 “.crash”文件放到同一个目录下,终端设置如下环境:
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
然后
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash > appName.log
就好了
2. 其他形式的控制台的crash堆栈日志如下这个时候,我们就需要手动来还原这个符号表了。
mac 自带了atos 命令可以还原符号地址,这个命令的使用参数:
atos -arch -o /Contents/Resources/DWARF/ -l
Binary Architecture: arm64、armv6、armv7 armv7s 根据自己的情况来写。
Path to dSYM file: dSYM文件的路径。
binary image name: 你工程的名字。
load address: 是运行时起始地址(基地址),如果我们的崩溃日志中没有这个信息(比如上面的Crash信息中就没有包含),就需要我们手动去计算这个load * address:laod address = address to symbolicate - offset,比如:0x0000000102838119转化为十进制为4337139993,再减去偏移量265,为4337139728,在转化为十六进制0x0000000102838010
address to symbolicate:运行时堆栈地址,当前方法的内存地址。
实际crash日志中除了项目的工程调用堆栈还有系统库的调用堆栈,为了方便快速解析,我们使用python脚本来批量解析地址,例如这是我自己调试我们项目写的脚本
# coding=utf-8
import re
import os
def findLibSystemSyboPath(libName):
systemLibRootPath = "/Users/xxx/Library/Developer/Xcode/iOS DeviceSupport/13.6 (17G68)"
cmd = "find \"" + systemLibRootPath + "\" -name " + libName
p = os.popen(cmd)
s = p.read().strip()
return s
def decodeIosCrashLog():
UAGameSyboFile = "/Users/xxx/Downloads/xxxxx.dSYM/Contents/Resources/DWARF/Game"
logFile = "/Users/xxx/Downloads/game_06121026.log"
newlogFile = "/Users/xxx/Downloads/game_06121026_decode.log"
with open(logFile, "r", encoding="utf-8") as f:
lines = f.readlines()
content = ""
reg = re.compile(".+\+ \d+$")
for line in lines:
if len(line.strip()) > 0 and reg.match(line):
arr = re.split("\s+", line)
if len(arr) == 7:
print(arr[1], arr[2], arr[3])
if arr[1] == "Game":
symboFile = UAGameSyboFile
else:
symboFile = findLibSystemSyboPath(arr[1])
cmd = "atos -o \"" + symboFile + "\" -arch arm64 -l " + arr[3] + " " + arr[2]
print(cmd)
try:
p = os.popen(cmd)
s = p.read()
print(s)
content += "\t".join(arr[:2]) + "\t" + s + "\r\n"
continue
except:
print("find symbo error")
content += line
with open(newlogFile, "w", encoding="utf-8") as f:
f.write(content)
f.close()
if __name__=="__main__":
decodeIosCrashLog()
大家按照自己项目的改下路径啥的,也就能直接用了,方便快捷。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)