NDK 包含一个名为 ndk-gdb
的 Shell 脚本,可以启动命令行原生调试会话。偏好使用 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
会显示一个正常的 GDB 提示。
您可能熟悉与 GNU GDB 的互动方式,与 ndk-gdb
的互动方式与之相同。例如,您可以使用 b <location>
设置断点,并使用 c
(表示“continue”)继续执行。有关完整的命令列表,请参阅 GDB 手册。如果您更喜欢使用 LLDB 调试程序,请在调用 ndk-gdb
脚本时使用 --lldb
选项。
请注意,如果您退出 GDB 提示,那么您正在调试的应用进程将停止。此行为是一种 gdb 限制。
ndk-gdb
可处理许多错误情况,并会在发现问题时显示可提供有用信息的错误消息。这些检查包括确保满足以下条件:
- 确保 ADB 位于您的路径中。
- 确保您的应用已在其清单中声明为可调试。
- 确保设备上安装的具有相同软件包名称的应用同样可调试。
默认情况下,ndk-gdb
会搜索已在运行的应用进程;如果没有搜索到,则会显示相应的错误。不过,您可以使用 --start
或 --launch=<name>
选项在调试会话前自动启动您的 Activity。有关详情,请参阅选项。
选项
要查看完整的选项列表,请在命令行中输入 ndk-gdb --help
。表 1 显示了许多比较常用的选项及其简要说明。
在指定了此选项的情况下启动 ndk-gdb
,将会启动应用清单中列出的第一个可启动 Activity。使用 --launch=<name>
可启动下一个可启动的 Activity。要转储可启动 Activity 的列表,请从命令行运行 --launch-list
。
选项 | 说明> |
---|---|
--lldb |
如果设置了此项,该脚本将对会话使用 LLDB 调试程序,而不是 gdb。 |
--verbose |
此选项指示构建系统打印有关原生调试会话设置的详细信息。仅在调试程序无法连接到应用且 |
--force |
默认情况下,如果 ndk-gdb 发现同一设备上已有另一个原生调试会话在运行,它将会中止运行。此选项将终止另一个会话,并将其替换为新的会话。请注意,此选项不会终止正在被调试的实际应用,您必须另行终止它。 |
--start |
当您启动 |
--launch=<name> |
此选项类似于 |
--launch-list |
这个便捷选项会输出在您的应用清单中找到的所有可启动 Activity 名称的列表。 |
--project=<path> |
此选项可指定应用项目目录。如果您希望不必先切换到项目目录就可启动脚本,则该选项会很有用。 |
--port=<port> |
默认情况下, |
--adb=<file> |
此选项可指定 adb 工具可执行文件。只有在您未指定包含该可执行文件的路径时才需要使用此选项。 |
-d -e -s <serial> |
这些标记与具有相同名称的 adb 命令类似。如果您有多个设备或模拟器连接至主机,请设置这些标记。其含义如下所示:
此外,您也可以定义 |
--exec=<file> -x <file> |
此选项可指示 |
--nowait |
解除 Java 代码的暂停状态,直到连上 GDB。传递此选项可能会导致调试程序错过早期的断点。 |
--tui
-t |
启用文本界面(如果可用)。 |
--gnumake-flag=<flag> |
此选项是在查询 |
注意:此表中的最后三个选项仅适用于 ndk-gdb
的 Python 版本。
线程支持
如果运行应用的平台版本低于 Android 2.3(API 级别 9),ndk-gdb
就无法正确调试原生线程。调试程序只能调试主线程,abd 会完全忽略其他线程的执行。
如果您在非主线程上执行的函数上放置一个断点,则程序将退出,而 GDB 将显示以下消息:
Program terminated with signal SIGTRAP, Trace/breakpoint trap. The program no longer exists.