ndk-gdb

NDK 包含一个名为 ndk-gdb 的 shell 脚本,用于启动命令行原生调试会话(历史上是 gdb,现在是 lldb)。偏好使用 GUI 的用户应阅读在 Android Studio 中调试的文档。

要求

要使命令行原生调试正常工作,必须满足以下要求:

  • 使用 ndk-build 脚本构建您的应用。ndk-gdb 脚本不支持使用旧版 make APP=<name> 方法进行构建。
  • 在您的 AndroidManifest.xml 文件中,通过包含一个将 android:debuggable 属性设置为 true<application> 元素来启用应用调试。
  • 将您的应用构建为可在 Android 2.2(Android API 级别 8)或更高版本上运行。
  • 在运行 Android 2.2 或更高版本的设备或模拟器上进行调试。对于调试目的,您在 AndroidManifest.xml 文件中声明的目标 API 级别无关紧要。
  • 在 Unix shell 中开发您的应用。在 Windows 上,使用 Cygwin 或实验性的 ndk-gdb-py Python 实现。
  • 使用 GNU Make 3.81 或更高版本。

用法

要调用 ndk-gdb 脚本,请进入应用程序目录或其下的任何目录。例如:

cd $PROJECT
$NDK/ndk-gdb

此处,$PROJECT 指向您的项目根目录,$NDK 指向您的 NDK 安装路径。

调用 ndk-gdb 时,它会配置会话以查找您的源文件和生成的原生库的符号/调试版本。成功附加到您的应用进程后,ndk-gdb 会输出一系列很长的错误消息,指出找不到各种系统库。这是正常的,因为您的主机不包含目标设备上这些库的符号/调试版本。您可以安全地忽略这些消息。

接下来,ndk-gdb 会显示通常的 lldb 提示符。

您与 ndk-gdb 交互的方式与使用 lldb 相同。如果您不熟悉 lldb 但了解 gdb,请参阅有用的 [GDB 到 LLDB 命令映射](https://lldb.llvm.org/use/map.html)。

ndk-gdb 处理许多错误情况,并在发现问题时显示有用的错误消息。这些检查包括确保满足以下条件:

  • 检查 ADB 是否在您的路径中。
  • 检查您的应用是否在其清单中声明为可调试。
  • 检查在设备上,已安装的具有相同包名的应用是否也为可调试。

默认情况下,ndk-gdb 会搜索一个已在运行的应用进程,如果找不到,则会显示错误。但是,您可以使用 --start--launch=<name> 选项在调试会话开始前自动启动您的 Activity。有关更多信息,请参阅选项

选项

要查看完整的选项列表,请在命令行中键入 ndk-gdb --help。表 1 显示了一些更常用的选项及其简要说明。

表 1. 常用的 ndk-gdb 选项及其说明。

使用此选项启动 ndk-gdb 将启动应用清单中列出的第一个可启动 Activity。使用 --launch=<name> 启动下一个可启动 Activity。要转储可启动 Activity 列表,请在命令行中运行 --launch-list

选项 说明
--verbose

此选项告诉构建系统打印有关原生调试会话设置的详细信息。仅当调试器无法连接到应用,并且 ndk-gdb 显示的错误消息不足以调试问题时,才需要此选项。

--force 默认情况下,如果 ndk-gdb 发现同一设备上已在运行另一个原生调试会话,它会中止。此选项会杀死其他会话,并将其替换为新的会话。请注意,此选项不会杀死正在调试的实际应用,您必须单独杀死该应用。
--start

启动 ndk-gdb 时,它默认尝试附加到目标设备上已在运行的应用实例。您可以通过使用 --start 选项在调试会话之前显式启动目标设备上的应用来覆盖此默认行为。

--launch=<name>

此选项类似于 --start,但它允许您从应用中启动特定的 Activity。仅当您的清单定义了多个可启动 Activity 时,此功能才有用。

--launch-list

此便捷选项会打印在您的应用清单中找到的所有可启动 Activity 名称的列表。--start 使用第一个 Activity 名称。

--project=<path> 此选项指定应用项目目录。如果您想在不先切换到项目目录的情况下启动脚本,此功能会很有用。
--port=<port>

默认情况下,ndk-gdb 使用本地 TCP 端口 5039 与在目标设备上调试的应用通信。使用不同的端口可以原生调试连接到同一主机上的不同设备或模拟器上运行的程序。

--adb=<file>

此选项指定 adb 工具的可执行文件。仅当您尚未设置路径以包含该可执行文件时,才需要此选项。

  • -d
  • -e
  • -s <serial>
  • 这些标志类似于同名的 adb 命令。如果您的主机连接了多个设备或模拟器,请设置这些标志。它们的含义如下:

    -d
    连接到单个物理设备。
    -e
    连接到单个模拟器设备。
    -s <serial>
    连接到特定设备或模拟器。此处,<serial>adb devices 命令列出的设备名称。

    或者,您可以定义 ADB_SERIAL 环境变量来列出特定设备,而无需特定的选项。

  • --exec=<file>
  • -x <file>
  • 此选项告诉 ndk-gdb 在连接到正在调试的进程后,运行在 <file> 中找到的调试器初始化命令。如果您想重复执行某些操作,例如设置断点列表,然后自动恢复执行,此功能会很有用。

    --nowait

    禁用暂停 Java 代码直到调试器连接。传递此选项可能导致调试器错过早期的断点。

    --tui -t

    如果可用,启用文本用户界面。

    --gnumake-flag=<flag>

    此选项是在查询 ndk-build 系统获取项目信息时传递给它的一个或多个额外标志。您可以在同一命令中使用此选项的多个实例。

    注意:本表中的最后三个选项仅适用于 Python 版本的 ndk-gdb