GDB on android

GNU 项目调试程序 (GDB) 是常用的 Unix 调试程序。本页详细介绍了如何使用 gdb 调试 Android 应用和进程(面向平台开发者)。对于第三方应用开发,请参阅调试您的应用

搜罗的(native 限定?)

需要注意的是gdbserver和gdb的版本要匹配,否则会出错, 所以都用NDK提供的即可

对于已经在run的process

  1. gdbserver到target device

    1
    adb push $ANDROID_NDK/prebuilt/$ARCH/gdbserver/gdbserver /data/local/tmp/
  2. attach gdbserver到target process

    1
    2
    3
    xxx$ /data/local/tmp/gdbserver :1234 --attach 18440 
    Attached; pid = 18440
    Listening on port 1234

    表示gdbserver已经attach到进程18440上了,在tcp端口1234上监听,gdb这边只要也连上1234这个端口就可以了

  3. forward target device的1234到PC的4321上

    1
    adb forward tcp:4321 tcp:1234
  4. gdb连接到4321即可

    1
    2
    3
    4
    5
    $ANDROID_NDK/prebuilt/linux-x86_64/bin/gdb
    ...
    (gdb) target remote localhost:4321
    Remote debugging using localhost:4321
    0x40011384 in ?? ()

搞定


Android developer介绍的

reference: https://source.android.com/devices/tech/debug/gdb

  • 条件:android source GOT

##调试运行中的应用或进程
要连接到已在运行的应用或本机守护进程,请配合使用 gdbclient.py 和 PID。例如,要调试 PID 为 1234 的进程,请运行:

1
$ANDROID_SRC_ROOT/development/scripts/gdbclient.py -p 1234

此脚本会设置端口转发,在设备上启动相应的 gdbserver,在主机上启动相应的 gdb,配置 gdb 以找出符号,然后将 gdb 连接到远程 gdbserver。

* 注意:在 Android 6 及更低版本中,该脚本是一个名为 gdbclient 的 Shell 脚本,而不是名为 gdbclient.py 的 Python 脚本。 *

调试本机进程启动

要在进程启动时对其进行调试,请使用 gdbserver 或 gdbserver64。
对于 64 位可执行文件:

1
adb shell gdbserver64 :5039 /system/bin/MY_TEST_64_BIT_APP

对于 32 位可执行文件:

1
adb shell gdbserver :5039 /system/bin/MY_TEST_32_BIT_APP

输出示例:

Process MY_TEST_64_BIT_APP created; pid = 3460
Listening on port 5039

接着,从 gdbserver 输出内容中找到应用 PID,并在另一个终端窗口中使用:

1
gdbclient.py -p APP_PID

最后,在 gdb 提示处输入 continue。

注意:如果您指定了错误的 gdbserver,将会收到没任何帮助的错误消息(例如“Reply contains invalid hex digit 59”)。

调试应用启动

有时,您需要在应用启动时对其进行调试;例如在应用发生崩溃时,您需要逐步检查代码,以查看崩溃之前发生的情况。 附加调试程序有时能解决问题,有时不能解决问题,因为应用可能会在您可以附加调试程序之前崩溃。logwrapper 方法(用于 stracevalgrind)不一定能解决所有的问题,因为应用可能没有权限打开端口,而 gdbserver 会继承这项限制。

要调试应用启动,请使用“设置”中的开发者选项,指示应用等待附加 Java 调试程序:

  1. 依次转到“设置”>“开发者选项”>“选择调试应用”,并从列表中选择您的应用,然后按等待调试程序
  2. 启动应用,您可以从启动器启动,也可以在命令行中运行以下命令来启动:

    1
    $ adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
  3. 等待应用加载,然后等待系统显示一个对话框提示您应用正在等待附加调试程序。

  4. 正常附加 gdbserver/gdbclient,设置断点,然后继续运行该进程。

要让应用实际运行,请附加 Java 调试网络协议 (JDWP) 调试程序,例如 Java 调试程序 (jdb):

1
2
adb forward tcp:12345 jdwp:XXX  # (Where XXX is the pid of the debugged process.)
jdb -attach localhost:12345

调试崩溃的应用或进程

如果您希望 debuggerd 暂停崩溃的进程,以便您可以附加 gdb,请设置相应的属性:

1
2
3
4
5
# 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 的说明:

1
gdbclient.py -p PID

无符号调试

对于 32 位 ARM,如果您的指令中没有符号,gdb 就不清楚自己正在反汇编哪个指令集(ARM 或 Thumb)。要指定缺少符号信息时选用的默认指令集,请设置以下属性:

1
set arm fallback-mode arm  # or thumb