Manuals
Manuals




This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English

原生代码调试

Defold 经过充分测试,在正常情况下应该很少崩溃。然而,无法保证它永远不会崩溃,特别是当您的游戏使用原生扩展时。如果您遇到崩溃或原生代码行为不符合预期的问题,有几种不同的解决方法:

  • 使用调试器逐步执行代码
  • 使用打印调试
  • 分析崩溃日志
  • 符号化调用堆栈

使用调试器

最常见的方法是通过 调试器 运行代码。它允许您逐步执行代码,设置 断点,如果发生崩溃,它将停止执行。

每个平台都有几种调试器。

  • Visual studio - Windows
  • VSCode - Windows, macOS, Linux
  • Android Studio - Windows, macOS, Linux
  • Xcode - macOS
  • WinDBG - Windows
  • lldb / gdb - macOS, Linux, (Windows)
  • ios-deploy - macOS

每个工具可以调试特定平台:

  • Visual studio - Windows + 支持 gdbserver 的平台(例如 Linux/Android)
  • VSCode - Windows, macOS (lldb), Linux (lldb/gdb) + 支持 gdbserver 的平台
  • Xcode - macOS, iOS (了解更多)
  • Android Studio - Android (了解更多)
  • WinDBG - Windows
  • lldb/gdb - macOS, Linux, (iOS)
  • ios-deploy - iOS (通过 lldb)

使用打印调试

调试原生代码的最简单方法是使用 打印调试。使用 dmLog 命名空间 中的函数来观察变量或指示执行流程。使用任何日志函数都会在编辑器的 控制台 视图和 游戏日志 中打印输出。

分析崩溃日志

如果 Defold 引擎发生硬崩溃,它会保存一个 _crash 文件。崩溃文件将包含有关系统以及崩溃的信息。游戏日志输出 将写入崩溃文件所在的位置(它根据操作系统、设备和应用程序而变化)。

您可以使用 崩溃模块 在后续会话中读取此文件。建议您读取文件,收集信息,将其打印到控制台,然后将其发送到支持收集崩溃日志的 分析服务

在 Windows 上,还会生成一个 _crash.dmp 文件。此文件在调试崩溃时很有用。

从设备获取崩溃日志

如果崩溃发生在移动设备上,您可以选择将崩溃文件下载到您自己的计算机并在本地解析它。

Android

如果应用是 可调试的,您可以使用 Android Debug Bridge (ADB) 工具adb shell 命令获取崩溃日志:

$ adb shell "run-as com.defold.example sh -c 'cat /data/data/com.defold.example/files/_crash'" > ./_crash

iOS

在 iTunes 中,您可以查看/下载应用程序容器。

Xcode -> Devices 窗口中,您也可以选择崩溃日志。

符号化调用堆栈

如果您从 _crash 文件或 日志文件 获取调用堆栈,您可以对其进行符号化。这意味着将调用堆栈中的每个地址转换为文件名和行号,这反过来有助于找出根本原因。

重要的是,您必须将正确的引擎与调用堆栈匹配,否则很可能会让您调试错误的内容!使用 --with-symbols 标志与 bob 捆绑,或者从编辑器的捆绑对话框中选中 “Generate debug symbols” 复选框:

  • iOS - build/arm64-ios 中的 dmengine.dSYM.zip 文件夹包含 iOS 构建的调试符号。
  • macOS - build/x86_64-macos 中的 dmengine.dSYM.zip 文件夹包含 macOS 构建的调试符号。
  • Android - projecttitle.apk.symbols/lib/ 捆绑输出文件夹包含目标架构的调试符号。
  • Linux - 可执行文件包含调试符号。
  • Windows - build/x86_64-win32 中的 dmengine.pdb 文件包含 Windows 构建的调试符号。
  • HTML5 - build/js-webbuild/wasm-web 中的 dmengine.js.symbols 文件包含 HTML5 构建的调试符号。

非常重要的一点是,您必须为您发布的每个公共版本保存调试符号,并且您知道调试符号属于哪个版本。如果您没有调试符号,您将无法调试任何原生崩溃!此外,您应该保留引擎的未剥离版本。这样可以最好地对调用堆栈进行符号化。

将符号上传到 Google Play

您可以 将调试符号上传到 Google Play,以便在 Google Play 中记录的任何崩溃都将显示符号化的调用堆栈。将 projecttitle.apk.symbols/lib/ 捆绑输出文件夹的内容压缩。该文件夹包含一个或多个具有架构名称的子文件夹,如 arm64-v8aarmeabi-v7a

符号化 Android 调用堆栈

  1. 从您的构建文件夹中获取引擎
	$ ls <project>/build/<platform>/[lib]dmengine[.exe|.so]
  1. 解压到一个文件夹:
	$ unzip dmengine.apk -d dmengine_1_2_105
  1. 查找调用堆栈地址

    例如,在未符号化的调用堆栈中,它可能看起来像这样

    #00 pc 00257224 libmy_game_name.so

    其中 00257224 是地址

  2. 解析地址

    $ arm-linux-androideabi-addr2line -C -f -e dmengine_1_2_105/lib/armeabi-v7a/libdmengine.so _address_

注意:如果您从 Android 日志 获取堆栈跟踪,您可能可以使用 ndk-stack 对其进行符号化

符号化 iOS 调用堆栈

  1. 如果您正在使用原生扩展,服务器可以为您提供符号(.dSYM)(将 --with-symbols 传递给 bob.jar)
	$ unzip <project>/build/arm64-darwin/build.zip
	# 它将产生一个 Contents/Resources/DWARF/dmengine
  1. 如果您没有使用原生扩展,下载原始符号:
	$ wget http://d.defold.com/archive/<sha1>/engine/arm64-darwin/dmengine.dSYM
  1. 使用加载地址进行符号化

    出于某种原因,简单地放入调用堆栈中的地址不起作用(即加载地址 0x0)

		$ atos -arch arm64 -o Contents/Resources/DWARF/dmengine 0x1492c4
# 直接指定加载地址也不起作用
		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp -l0x100000000 0x1492c4
将加载地址添加到地址中起作用:
		$ atos -arch arm64 -o MyApp.dSYM/Contents/Resources/DWARF/MyApp 0x1001492c4
		dmCrash::OnCrash(int) (in MyApp) (backtrace_execinfo.cpp:27)