GNU 项目调试程序 (GDB) 是常用的 Unix 调试程序。本页详细介绍了如何使用 gdb
调试 Android 应用和进程。
要连接到已在运行的应用或本机守护进程,请配合使用 gdbclient
和 PID。例如,要调试 PID 为 1234 的进程,请运行:
gdbclient 1234
此脚本会设置端口转发,在设备上启动相应的 gdbserver
,在主机上启动相应的 gdb
,配置 gdb
以找出符号,然后将 gdb
连接到远程 gdbserver
。
要在进程启动时对其进行调试,请使用 gdbserver
或 gdbserver64
(适用于 64 位进程)。例如:
adb shell gdbserver :5039 /system/bin/MY_TEST_APP
输出示例:
Process MY_TEST_APP created; pid = 3460 Listening on port 5039
接下来,从 gdbserver
输出中找出应用 PID,并将其用于其他终端窗口。
gdbclient APP_PID
最后,在 gdb
提示处输入 continue。
注意:如果您指定了错误的 gdbserver
,将会收到没任何帮助的错误消息(例如“Reply contains invalid hex digit 59
”)。
有时,您需要在应用启动时对其进行调试;例如在应用发生崩溃时,您需要逐步检查代码,以查看崩溃之前发生的情况。
附加调试程序有时能解决问题,有时不能解决问题,因为应用可能会在您可以附加调试程序之前崩溃。logwrapper
方法(用于 strace
和 valgrind
)不一定能解决所有的问题,因为应用可能没有权限打开端口,而 gdbserver
会继承这项限制。
要调试应用启动,请使用“设置”中的开发者选项,指示应用等待附加 Java 调试程序:
am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
gdbserver
/gdbclient
,设置断点,然后继续运行该进程。要让应用实际运行,请附加 Java 调试网络协议 (JDWP) 调试程序,例如 Java 调试程序 (jdb):
adb forward tcp:12345 jdwp:XXX # (Where XXX is the pid of the debugged process.)
jdb -attach localhost:12345
如果您希望 debuggerd
暂停崩溃的进程,以便您可以附加 gdb
,请设置相应的属性:
# Android 7.0 Nougat and later.
adb shell setprop debug.debuggerd.wait_for_gdb true
# Android 6.0 Marshmallow and earlier.
adb shell setprop debug.db.uid 999999
在寻常的崩溃输出结束后,debuggerd
会提供有关如何使用命令连接 gdb
的说明:
gdbclient PID
对于 32 位 ARM,如果您没有符号,gdb
就会搞不清楚要反汇编的指令集(ARM 或 Thumb)。要在缺失符号信息时指定已选为默认项的指令集,请设置以下属性:
set arm fallback-mode arm # or thumb