必须用同一工具链编译的arm-linux-gnueabihf-gdb和gdbserver,否则连接失败或断点不命中;gdbserver需绑定目标程序运行,如gdbserver :2345 ./myapp,且程序须带-g调试符号、路径可执行。

必须用同一工具链编译的 arm-linux-gnueabihf-gdb 和 arm-linux-gnueabihf-gdbserver,否则会卡在连接阶段或断点不命中——这是最常被忽略的前提。
gdbserver 在目标板上怎么启动才有效
它不是后台服务,而是和你要调试的程序“绑定”运行的进程。启动方式直接决定能否调试成功:
- 调试新程序:
gdbserver :2345 ./myapp arg1 arg2(监听 2345 端口,./myapp必须带调试符号,且路径在目标板上可执行) - 附加到已有进程:
gdbserver :2345 --attach 1234(1234是目标程序 PID,需有权限读取其内存) - 别用
localhost或127.0.0.1:目标板上gdbserver必须监听通向开发主机的网卡地址,推荐直接用:2345(等价于0.0.0.0:2345),再靠防火墙或网络策略控制访问 - 确认端口未被占用:
netstat -tuln | grep 2345,避免和 SSH、其他调试实例冲突
arm-linux-gnueabihf-gdb 连接后为什么没反应
常见假死现象,其实多数是卡在符号加载或库路径上:
- 先确保已加载符号:
file ./myapp(本地编译出的带-g的可执行文件,必须和目标板上运行的二进制完全一致) - 再连接:
target remote 192.168.3.193:2345(IP 是目标板真实 IP,不是虚拟机或宿主机的) - 如果卡住不动,立刻检查:
show solib-search-path;若为空或路径错误,用set sysroot /path/to/target/sysroot或set solib-search-path /opt/rk3568/sysroot/lib:/opt/rk3568/sysroot/usr/lib - 遇到
Cannot access memory at address,大概率是libthread_db.so.1缺失——这个库必须从交叉工具链对应 sysroot 中拷贝到目标板/usr/lib或/lib,不能只靠gdbserver自带
断点设置失败或不触发的典型原因
不是 gdb 命令写错了,而是底层机制被绕过:
-
break main失败?先info functions确认符号表里真有main;若没有,说明编译时没加-g,或用了-fvisibility=hidden+-O2导致函数内联消失 - 断点命中但
step不进函数?检查是否编译了-O0 -g;-O2下编译器可能把函数全内联,step就变成跳过整段逻辑 - 修改代码后重新编译,但 gdb 仍停在旧行号?
file ./myapp必须重执行一次,否则 gdb 还在用旧符号表 - 用
list看不到源码?确认当前目录是源码根目录,且myapp编译时用了绝对路径(如arm-linux-gnueabihf-gcc -g -o myapp src/main.c),否则 gdb 找不到src/main.c
真正难调的从来不是命令记不牢,而是符号、路径、优化等级、库依赖这四者之间微妙的耦合——任何一个环节错位,gdb 就会安静地“假装正常”,直到你发现变量打印出来全是 <optimized out></optimized> 或断点根本不动。











