GDB Server远程调试

GDB Server远程调试是嵌入式或Linux开发中常用的调试方式,核心思路是在目标设备 (运行程序的地方)运行一个gdbserver服务,然后在开发主机上用GDB客户端连接并控制调试。

ubuntu操作:

chmod 777 DTX/0711/libs/mpp/build/out/ -R

sudo /etc/init.d/nfs-kernel-server start

在目标设备上启动 gdbserver操作:

拷贝gdbserver拷贝到板端(源文件在该目录:prebuilts/develop_32/gdbserver/usr/bin/gdbserver)

cp gdbserver /tmp/

拷贝要调试的可执行文件到板端

cp ap_main /tmp/

./gdbserver 192.168.11.25:1025 ap_main #这里配置的是板端的IP

执行之后打印:

Process /tmp/ap_main created; pid = 180

Listening on port 1025

可以进行下一步

在ubuntu主机上用 GDB 连接:

cd build

cp -a prebuilts/develop_32/gdb/lib/lib* out/rootfs/usr/lib/

cp out/rootfs/lib/libgcc_s.so.1 out/rootfs/usr/lib/

cp out/rootfs/lib/libstdc++.so.6.0.28 out/rootfs/usr/lib/libstdc++.so.6

(CROSS_COMPILE)gdb product_app/cc_hy/out/bin/ap_main #(CROSS_COMPILE)为配置的编译工具链的环境变量,这样写用不了的,自己转换一下

接下来在PC端开始GDB操作:

target remote 192.168.11.25:1025 #使用上面配置的板端的IP

#设置共享库路径

set solib-search-path out/rootfs/usr/lib/

输入c 程序运行

  • run / r :启动程序(通常远程调试时用 continue 替代,因为 gdbserver 启动时程序已载入)。

  • continue / c:继续执行程序,直到遇到断点或程序结束。

  • step / s单步进入。执行一行代码,如果遇到函数调用,会进入函数内部。

  • next / n单步跳过。执行一行代码,如果遇到函数调用,不进入内部,直接执行完整个函数。

  • finish执行完当前函数并返回,停在该函数的调用处。

  • until / u跳出循环。执行到当前循环体结束或指定的行号,常用于快速跳过冗长的循环。

  • kill:强制终止正在调试的程序(但 gdbserver 不会断开)。

  • break / b:设置断点。常用语法:

    • b main:在 main 函数处打断点。

    • b 10:在当前源文件的第10行打断点。

    • b source.c:20:在指定文件的第20行打断点。

    • b *0x40052a:在内存地址处打断点。

  • tbreak :设置临时断点。触发一次后自动删除,常用于调试只发生一次的异常分支。

  • watch :设置观察点 。当被监视的变量值被写入 时,程序会暂停。例如:watch my_var

  • rwatch :设置读观察点 。当变量被读取时暂停(部分平台支持)。

  • info break / i b:列出当前所有已设置的断点、观察点及其状态。

  • delete / d :删除断点。delete(删除所有)或 delete 2(删除编号为2的断点)。

  • disable / enable :临时禁用/启用断点。例如:disable 2

  • print / p查看变量或表达式的值 。如 p my_varp arr[0]@10(打印数组前10个元素)。

  • display自动显示变量 。每次程序暂停时,都会自动打印该变量的当前值(常用于循环调试)。例如:display i

  • info locals:打印当前栈帧中的所有局部变量及其值。

  • info registers / i r:显示 CPU 寄存器的当前值。

  • x查看内存地址 。格式为 x /<个数><格式><大小> <地址>。例如:

    • x /10xw 0x7fffffffe000:以十六进制格式,查看10个4字节(word)的内存数据。

    • x /20s buffer:以字符串格式,查看 buffer 地址起20个字节。

流程背后依赖Linux的 ptrace 系统调用。当你在GDB中设置断点时,gdbserver会把目标程序对应位置的指令临时替换为一条中断指令(INT3)。程序执行到此处会触发 SIGTRAP 信号,该信号被gdbserver截获后,会通知主机上的GDB,程序就停在了断点处。主机和gdbserver之间通过**GDB远程串行协议(RSP)**通信,以文本形式交换读写内存、寄存器等调试命令。