介绍
一般在ndk崩溃的时候,完全看不懂崩溃日志,在网上了解以后,发现ndk有提供解析的工具,我使用的add2line,参考网上的python脚本的实例,最后借助Android Studio的External Tools,最后的效果如下:
只要在当前工程下随便创建一个文件,存储对应backtrace的log,右键运行External Tools,就可以解析出错的文件了
步骤
python脚本
#!/usr/bin/env python
# coding=utf-8
import argparse
import os
import re
import sys
NdkPath = "D:/Android/Sdk/ndk/22.1.7171670" #ndk路径
ProjectDir = "D:/WorkSpace/Android/xxx" #对应安卓工程路径
def getOptions(args=sys.argv[1:]):
parser = argparse.ArgumentParser(description="Parses command.")
parser.add_argument("-n", "--ndk", help="Your ndk path.")
parser.add_argument("-p", "--project", help="Your project path.")
parser.add_argument("-f", "--file", help="crash log file.")
options = parser.parse_args(args)
return options
def parser(projectDir, ndkPath, crashFilePath):
print("开始解析")
symbolDir = f"{projectDir}/app/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a"
addr2lineFilePath = f"{ndkPath}/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin" \
"/aarch64-linux-android-addr2line.exe "
p = re.compile(r"(.*#\d* pc) ([\da-zA-Z]*) /data/app/.*==/lib/arm64/([\w.]*).*", re.MULTILINE)
with open(crashFilePath, "r") as file:
for line in file:
if line.find("\n") < 0:
line += "\n"
matched = p.search(line)
if matched is not None:
head = matched.group(1)
pc = matched.group(2)
soName = matched.group(3)
# 解析调用栈
command = f"{addr2lineFilePath} -f -e {symbolDir}/{soName} {pc}"
f = os.popen(command)
read = f.read()
f.close()
print(line, end="")
print(f"{head} \u001b[31m{read}\u001b[0m", end="")
if __name__ == '__main__':
option = getOptions()
print(option)
if option.project is None:
option.project = ProjectDir
if option.ndk is None:
option.ndk = NdkPath
if option.file is None:
option.file = os.path.dirname(os.path.realpath(__file__)) + "/NdkCrash.txt"
parser(option.project, option.ndk, option.file)
以上脚本解析的是arm64-v8a的包,自己可以根据情况改改,然后symbolDir可以得看看你的as版本了,生成的so是不是在这个路径下
AS External tools配置
AS菜单 File > Setting > Tools > External Tools
ndk位置我在python脚本里面写死了,上面就没加