必须先用file命令加载带调试信息的可执行文件,再执行target remote;否则报“No symbol table is loaded”,断点失效或pending。正确顺序:file ./ap_main → target remote 192.168.11.25:1025。

target remote 必须在加载符号表之后执行
直接运行 target remote 会报错 “No symbol table is loaded”,因为 GDB 还不知道你要调试的是哪个程序。必须先用 file 命令加载带调试信息的可执行文件(和目标机上运行的二进制完全一致),GDB 才能解析符号、源码行号、变量名等。
常见错误现象:
-
(gdb) target remote 192.168.11.25:1025→ 报错No symbol table is loaded. Use the "file" command. - 即使连上了,
break main失败,或断点显示为 pending,说明符号没对上
正确顺序是:
-
gdb ./ap_main(本地启动 GDB,加载本地带调试信息的二进制) -
(gdb) file ./ap_main(如果已加载,可省略;但显式执行更稳妥) -
(gdb) target remote 192.168.11.25:1025(此时才连接)
IP 和端口要填目标机监听地址,不是开发机
target remote 的参数是 gdbserver 实际在监听的地址,也就是目标设备(板子、嵌入式设备、远程服务器)的 IP 和端口。这个地址必须能被开发主机网络访问到——不是 localhost,也不是开发机自己的 IP。
典型误配:
- 填成
target remote 127.0.0.1:1025:这是让 GDB 去连本机,但 gdbserver 在板子上,连不通 - 填成
target remote 192.168.1.100:1025,但板子实际 IP 是192.168.11.25:网络不可达,GDB 卡住或报Connection refused - 端口不一致:gdbserver 启动用
:1025,GDB 却连:2345,必然失败
验证方式:在开发机上执行 telnet 192.168.11.25 1025 或 nc -zv 192.168.11.25 1025,通了才能连。
连接后必须设 solib-search-path 才能加载动态库符号
如果目标程序依赖动态库(如 libstdc++.so.6、libgcc_s.so.1),而这些库在开发机上路径和目标机不一致,GDB 就无法解析调用栈里的函数名,bt 可能只显示 ??,step into 会卡住或跳过。
解决方法是告诉 GDB 去哪找这些库:
(gdb) set solib-search-path out/rootfs/usr/lib/:out/rootfs/lib/- 路径之间用冒号
:分隔(Linux/macOS),Windows 用分号 - 路径必须包含完整符号表的 .so 文件,不能是 stripped 版本
- 如果用了交叉编译,确保拷贝的是目标架构的库(比如 ARM 的
libstdc++.so.6.0.28,不是 x86_64 的)
漏设该路径的典型表现:print std::string 报错、finish 无法返回、info sharedlibrary 显示部分库为 No debugging symbols found。
协议类型影响 attach 行为,多数情况用 extended-remote
默认 target remote 使用的是传统 remote 协议,它要求 gdbserver 已经启动并绑定了程序。但如果你要用 gdbserver --multi 模式(即 gdbserver 先启动、再由 GDB 控制加载程序),就必须切换协议:
(gdb) set remote protocol extended-remote- 然后执行
target extended-remote 192.168.11.25:1025 - 之后可用
file ./ap_main+run启动目标程序,而不是靠 gdbserver 启动时就载入
不切协议就对 --multi gdbserver 执行 target remote,会报 Remote 'g' packet reply is too long 或直接断开。
绝大多数嵌入式调试场景用标准 target remote 就够了;只有需要动态加载多个程序、或调试 daemon 类进程时,才需 extended-remote。
最容易被忽略的一点:target remote 连上之后,GDB 并不会自动同步目标机当前状态——比如程序是否已暂停、寄存器值、内存映射。你得手动用 info registers、x/10i $pc 看现场,否则可能误判程序停在哪。


















