欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 【Unity3D杂谈】使用NDK命令行工具翻译Android Vitals上的内存堆栈

【Unity3D杂谈】使用NDK命令行工具翻译Android Vitals上的内存堆栈

2025/2/21 3:23:46 来源:https://blog.csdn.net/a310989583/article/details/145612779  浏览:    关键词:【Unity3D杂谈】使用NDK命令行工具翻译Android Vitals上的内存堆栈

在Android游戏开发中,崩溃日志的分析至关重要,尤其是在Unity3D项目中,libunity.so 等动态库中的堆栈信息往往难以直接解读。本文介绍如何使用NDK提供的 addr2line 工具解析 Android Vitals 上的崩溃堆栈,以便快速定位问题。

1. addr2line 工具介绍

addr2line 是NDK提供的一个命令行工具,可将崩溃日志中的地址转换为具体的代码位置。

1.1 addr2line 命令示例

addr2line -f -e libunity.so 0x00000000001ea00c
  • -f:显示函数名称。

  • -e:指定符号文件(libunity.so)。

  • 0x00000000001ea00c:崩溃日志中的内存地址。

1.2 使用 addr2line 工具

如果 addr2line 没有在环境变量中配置,可以直接使用完整路径:

D:\Program Files\Unity\Editor\Unity 2021.3.44f1\Editor\Data\PlaybackEngines\AndroidPlayer\NDK\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch64-linux-android-addr2line.exe

其中 aarch64 代表 ARM64 架构。

2. Unity符号库 so 文件的获取

要正确解析崩溃堆栈,需要符号化的 .so 文件。这要求在打包的时候Build Setting的Create symbol.zip开关打开。或者打包代码实现:

EditorUserBuildSettings.androidCreateSymbolsZip = true

将zip解压后会获得一些so符号库,比如:

  • Crash/arm64-v8a/libunity.so

  • Crash/armeabi-v7a/libunity.so

3. 堆栈解析示例

3.1 崩溃堆栈

  #00  pc 0x000000000038858c  /data/app/com.demo.examples/lib/arm64/libunity.so#01  pc 0x00000000003885c4  /data/app/com.demo.examples/lib/arm64/libunity.so#02  pc 0x000000000078c044  /data/app/com.demo.examples/lib/arm64/libunity.so#03  pc 0x0000000000786dc4  /data/app/com.demo.examples/lib/arm64/libunity.soat com.unity3d.player.UnityPlayer.nativeDone (Native method)at com.unity3d.player.UnityPlayer.shutdown (SourceFile)

3.2 addr2line 解析结果

_ZN14ConstantString7cleanupEv
_ZN14ConstantStringaSERKS_
_ZN13sorted_vectorINSt6__ndk14pairI14ConstantStringP11AssetBundleEE9erase_oneIS2_EEmRKT_
_ZN18AssetBundleManager23UnloadAssetBundleAtPathEP11AssetBundle

4. Python脚本实现自动解析

为了简化 addr2line 解析过程,可以编写一个 Python 脚本逐行解析崩溃堆栈。

4.1 解析崩溃堆栈的Python脚本

import os
import reoriginal_stack = """000000038858c  /data/app/com.demo.examples/lib/arm64/libunity.so#01  pc 0x00000000003885c4  /data/app/com.demo.examples/lib/arm64/libunity.so#02  pc 0x000000000078c044  /data/app/com.demo.examples/lib/arm64/libunity.so#03  pc 0x0000000000786dc4  /data/app/com.demo.examples/lib/arm64/libunity.soat com.unity3d.player.UnityPlayer.nativeDone (Native method)at com.unity3d.player.UnityPlayer.shutdown (SourceFile)
"""valid_so_list = ["libil2cpp.so", "libunity.so", "libmain.so"]class StackInfo:def __init__(self, address, arch, lib_name):self.address = addressself.arch = archself.libName = lib_namedef parse_stack_info():stackInfoList = []for line in original_stack.splitlines():if "pc" in line:address = re.findall(r"0x[0-9a-fA-F]+", line)[0]cpu_arch = "arm64" if "arm64" in line else "arm"lib_name = re.findall(r"lib[\w]+\.so", line)[0]if lib_name in valid_so_list:stackInfoList.append(StackInfo(address, cpu_arch, lib_name))return stackInfoListdef translate_stack(current_dir, address, cpu_arch, lib_name):addr2line_path = "D:/Program Files/Unity/Editor/Unity 2021.3.44f1/Editor/Data/PlaybackEngines/AndroidPlayer/NDK/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin"addr2line_name = "./aarch64-linux-android-addr2line.exe"current_dir = current_dir + ("/Crash/armeabi-v7a/" if cpu_arch == "arm" else "/Crash/arm64-v8a/")lib_name = f'"{current_dir}{lib_name}"'cmd = f'{addr2line_name} -f -e {lib_name} {address}'os.chdir(addr2line_path)result = os.popen(cmd).read()return result.splitlines()[0]if __name__ == '__main__':current_dir = os.getcwd()stack_info_list = parse_stack_info()translated_stack = "".join(translate_stack(current_dir, s.address, s.arch, s.libName) for s in stack_info_list)print(f"原始堆栈:\n{original_stack}\n\n翻译后:\n{translated_stack}")

4.2 脚本解析结果示例

原始堆栈:#00  pc 0x0000000000373714  /data/app/com.demo.examples/lib/arm64/libunity.so#01  pc 0x0000000000370848  /data/app/com.demo.examples/lib/arm64/libunity.so翻译后:
_ZN14ConstantString7cleanupEv
_ZN14ConstantStringaSERKS_

5. 结论

通过 addr2line 工具结合符号库 .so,可以有效解析 Android Vitals 上的崩溃日志,帮助开发者快速定位问题。此外,使用 Python 自动化脚本可以批量解析堆栈,提高调试效率。

只要具备完整的符号表 (so 文件),这种方法适用于大多数崩溃日志的解析,极大提升了问题排查速度。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词