完善 使用 GDB 调试 Native 程序.
Signed-off-by: lion.chan <cy187lion@sina.com>
This commit is contained in:
parent
7c5e98d449
commit
7d388fa52f
|
@ -1,3 +1,127 @@
|
|||
# 使用 GDB 调试 Native 程序
|
||||
# [使用 GDB 调试 Native 程序](https://source.android.google.cn/devices/tech/debug/gdb?hl=zh-cn)
|
||||
|
||||
TODO: <https://source.android.google.cn/devices/tech/debug/gdb?hl=zh-cn>
|
||||
## 1.前提条件
|
||||
|
||||
要使用 GDB 调试应用和进程,请执行以下操作:
|
||||
|
||||
* 使用 envsetup.sh 命令设置环境
|
||||
* 运行 lunch 命令
|
||||
* 在对应程序的 Android.md/Android.dp 文件中修改编译选项,增加 -O0 -g 参数
|
||||
* Android 镜像中包含的程序一般不带调试信息,需要到 out/target/product/\<product\>/symboles 下获取带调试信息的程序/库,然后将其 adb push 到设备
|
||||
|
||||
注意:
|
||||
|
||||
1. 由于 Android 构建系统中大量使用了 Python2,构建系统中应将 Python 默认环境配置为 Python2;
|
||||
2. Android GDB 调试依赖于 gdbclient.py 脚本,改脚本在源码的 development/scripts 下;
|
||||
|
||||
## 2.调试正在运行的应用或进程
|
||||
|
||||
如需连接到正在运行的应用或本机守护程序,请配合使用 gdbclient.py 和 PID。例如,如需调试 PID 为 1234 的进程,请于 Android 源码目录下运行以下命令:
|
||||
|
||||
```bash
|
||||
gdbclient.py -p 1234
|
||||
```
|
||||
|
||||
此脚本会设置端口转发,在设备上启动相应的 gdbserver,在主机上启动相应的 gdb,配置 gdb 以查找符号,然后将 gdb 连接到远程 gdbserver。
|
||||
|
||||
注意:在 Android 6 或更低版本的系统中,该脚本是一个名为 gdbclient 的 Shell 脚本,而不是名为 gdbclient.py 的 Python 脚本。
|
||||
|
||||
## 3.调试时启动应用或进程
|
||||
|
||||
如需在进程启动时对其进行调试,请先在 Android 设备上使用 gdbserver 或 gdbserver64 启动应用程序。对于 64 位可执行文件:
|
||||
|
||||
```bash
|
||||
adb shell gdbserver64 :<port> /<path>/<bin>/<program> [program args]
|
||||
```
|
||||
|
||||
对于 32 位可执行文件:
|
||||
|
||||
```bash
|
||||
adb shell gdbserver :<port> /<path>/<bin>/<program> [program args]
|
||||
```
|
||||
|
||||
接着,从 gdbserver 输出内容中找到应用 PID,例如:
|
||||
|
||||
```bash
|
||||
Process <program> created; pid = <program pid>
|
||||
Listening on port <port>
|
||||
```
|
||||
|
||||
在 Android 源码目录另一个终端窗口,使用:
|
||||
|
||||
```bash
|
||||
gdbclient.py -p <program pid> --port <port>
|
||||
```
|
||||
|
||||
最后,在 gdb 提示符处输入 gdb 调试命令进行调试即可。
|
||||
|
||||
注意:如果您指定了错误的 gdbserver,将会收到没有任何帮助的错误消息(例如“Reply contains invalid hex digit 59”)。
|
||||
|
||||
## 4.调试应用启动
|
||||
|
||||
有时,您需要在应用启动时对其进行调试;例如在应用发生崩溃时,您需要逐步检查代码,以查看崩溃之前发生的情况。附加调试程序有时能解决问题,有时不能解决问题,因为应用可能会在您可以附加调试程序之前崩溃。logwrapper 方法(用于 strace)不一定能解决所有的问题,因为应用可能没有权限打开端口,而 gdbserver 会继承这项限制。
|
||||
|
||||
如需调试应用启动,请使用“设置”中的开发者选项来指示应用等待附加 Java 调试程序:
|
||||
|
||||
1. 依次转到设置 > 开发者选项 > 选择调试应用,并从列表中选择您的应用,然后点击等待调试程序。
|
||||
2. 启动应用,您可以从启动器启动,也可以在命令行中运行以下命令来启动:
|
||||
|
||||
adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
|
||||
|
||||
3. 等待应用加载,然后等待系统显示一个提示您应用正在等待附加调试程序的对话框。
|
||||
4. 正常附加 gdbserver/gdbclient,设置断点,然后继续运行该进程。
|
||||
|
||||
为了让应用运行,请附加 Java 调试网络协议 (JDWP) 调试程序,例如 Java 调试程序 (jdb):
|
||||
|
||||
```bash
|
||||
adb forward tcp:12345 jdwp:XXX # (Where XXX is the PID of the debugged process.)
|
||||
jdb -attach localhost:12345
|
||||
```
|
||||
|
||||
## 5.调试崩溃的应用或进程
|
||||
|
||||
如果您希望 debuggerd 暂停崩溃的进程,以便您可以附加 gdb,请设置相应的属性:
|
||||
|
||||
```bash
|
||||
# Android 7.0 Nougat 及更高版本
|
||||
adb shell setprop debug.debuggerd.wait_for_gdb true
|
||||
# Android 6.0 Marshmallow 及更低版本
|
||||
adb shell setprop debug.db.uid 999999
|
||||
```
|
||||
|
||||
在寻常崩溃输出的结尾处,debuggerd 会提供有关如何使用以下命令来连接 gdb 的说明:
|
||||
|
||||
```bash
|
||||
gdbclient.py -p <pid>
|
||||
```
|
||||
|
||||
## 6.无符号调试
|
||||
|
||||
对于 32 位 ARM,如果您的指令中没有符号,gdb 就不清楚自己正在反汇编哪个指令集(ARM 还是 Thumb)。如需指定缺少符号信息时选用的默认指令集,请设置以下属性:
|
||||
|
||||
```bash
|
||||
set arm fallback-mode arm # or thumb
|
||||
```
|
||||
|
||||
## 7.使用 VS Code 进行调试
|
||||
|
||||
GDB 支持在 Visual Studio Code 上调试平台代码。您可以使用 VS Code 调试程序前端(而非 GDB CLI 接口)来控制和调试在设备上运行的原生代码。
|
||||
|
||||
在使用 VS Code 进行调试之前,请安装 C/C++ 扩展程序。
|
||||
|
||||
使用 VS Code 调试代码的步骤:
|
||||
|
||||
1. 确保运行 gdbclient.py 所需的所有构建工件(例如符号)都存在。
|
||||
2. 运行以下命令:
|
||||
|
||||
gdbclient.py -p pid | -n proc-name | -r ... --setup-forwarding vscode ANY_OTHER_FLAGS
|
||||
|
||||
这将输出一个 JSON 对象,并且 gdbclient.py 将继续运行。这是预期结果;请不要终止 gdbclient.py 程序。
|
||||
3. 在 VS Code 的“调试”标签页中,选择添加配置,然后选择 C/C++ gdb 附加。这将打开一个 launch.json 文件,并将新的 JSON 对象添加到列表中。
|
||||
4. 删除新添加的调试程序配置。
|
||||
5. 复制 gdbclient.py 输出的 JSON 对象并将其粘贴到您刚删除的对象中。保存更改。
|
||||
6. 如需重新加载窗口以刷新调试程序列表,请按 Ctrl+Shift+P 并输入 reload window。
|
||||
7. 选择新的调试程序配置,然后按运行。调试程序应在 10 到 30 秒后连接。
|
||||
8. 完成调试后,请转到运行 gdbclient.py 的终端,然后按 Enter 结束 gdbclient.py 程序。
|
||||
|
||||
首次设置调试程序配置后,您可以跳过步骤 3 到 6。
|
||||
|
|
Loading…
Reference in New Issue