符号表是什么
- 符号表就是指在Xcode项目编译后,在编译生成的二进制文件.app的同级目录下生成的同名的.dSYM文件。
.dSYM文件其实是一个目录,在子目录中包含了一个16进制的保存函数地址映射信息的中转文件,所有Debug的symbols都在这个文件中(包括文件名、函数名、行号等),所以也称之为调试符号信息文件。
一般地,Xcode项目每次编译后,都会生成一个新的.dSYM文件。因此,App的每一个发布版本,都需要备份一个对应的.dSYM文件,以便后续调试定位问题。
符号表的作用
- 在Xcode开发调试App时,一旦遇到崩溃问题,开发者可以直接使用Xcode的调试器定位分析。
但如果App发布上线,开发者不可能进行调试,只能通过分析系统记录的崩溃日志来定位问题,在这份崩溃日志文件中,会指出App出错的函数内存地址,而这些函数地址是可以在.dSYM文件中找到具体的文件名、函数名和行号信息的。
atos工具(可以把地址转换为函数名(包括行号))
atos [-arch 架构名] [-o 符号表] [-l 模块地址] [方法地址]
来编写我们的自动解析脚本吧
import os
import sys
import time
default_appName = "/Contents/Resources/DWARF/CCTVVideo"
def atos(dsym_dir_path, crash_file_path, arm_str="arm64"):
"""
自动解析ios crash日志
:param dsym_dir_path:
:param crash_file_path:
:param arm_str:
:return:
"""
dsym_dir_path = dsym_dir_path + default_appName
str_time = time.strftime('%Y-%m-%d_%H:%M:%S', time.localtime(time.time()))
# 读取 crash 文件,正常写入到result中,如果遇到需要解析的堆栈,需要解析后,将解析后的内容再写到result文件中
with open(crash_file_path, 'r')as fr:
for i in fr:
list_i = i.split()
with open(str(str_time) + "result.crash", 'a+')as fw:
# 判断有加号,而且分割后第三个元素和第四个元素是 0x 开头
if "+" in i and list_i[2].startswith("0x") and list_i[3].startswith("0x"):
atos_result = os.popen(
f"atos -arch {arm_str} -o {dsym_dir_path} -l {list_i[3]} {list_i[2]}").read()
new_line_list = str(i.split('0x')[0]) + str(atos_result)
fw.write(new_line_list)
else:
fw.write(i)
def check_params():
"注意:堆栈信息的文件名不要有空格"
try:
assert sys.argv[1].endswith(".app.dSYM") # 判断是否是符号表
assert os.access(sys.argv[2], os.R_OK) # 判断是否可读
if len(sys.argv) == 3:
atos(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 4:
atos(sys.argv[1], sys.argv[2], arm_str=sys.argv[3])
except Exception as e:
print(e.args)
if __name__ == '__main__':
# dsym_dir_path = sys.argv[1] # .app.dSYM符号表的文件路径
# crash_file_path = sys.argv[2] # crash文件路径(可以是导出的 crash 文件路径,也可是待解析的原始堆栈)
# arm_str = sys.argv[3] # 架构名
check_params()
git地址
https://github.com/shishanshanTest/AtosCrash.git