通过gdbserver调试时STL容器无法优雅打印的原因及解决方法
远程调试时GDB无法优雅打印STL容器的原因及解决办法
问题重现
编写如下C++代码:
#include <iostream> #include <string> using namespace std; int main() { string s{"qwe"}; while (true){} // 用于附加调试 cout << s << endl; }
执行以下操作后出现异常:
- 用
sudo gdbserver --attach localhost:2345 $(pidof my_proj)启动gdbserver - 本地GDB执行
target remote localhost:2345远程连接 - 程序停在
while (true){}处,打印变量s时显示内部结构(如_M_dataplus等成员),而非"qwe";但直接用gdb -p $(pidof my_proj)本地附加进程时,能正常显示字符串形式。
原因分析
GDB对STL容器的友好打印依赖libstdc++ pretty-printer——一套Python脚本,它需要读取程序的调试符号,解析STL容器的内部结构,再转换成易读的格式。
- 本地直接附加时:GDB能直接访问本地程序的完整调试符号,且自动加载了系统自带的pretty-printer,因此可以正常解析
std::string并输出友好格式。 - 远程调试时:gdbserver仅负责传输调试指令和内存数据,不处理STL打印逻辑。如果本地GDB未加载目标程序的完整调试符号,或未启用pretty-printer,就只能打印容器的原始内部结构。
解决步骤
编译时保留完整调试信息
编译必须添加-g(或-g3以获取更详细的调试信息),禁止用strip命令去除符号:g++ -g -o my_proj my_proj.cpp本地GDB加载目标程序的符号文件
- 若远程与本地为同一编译环境(如同一机器、相同架构系统),连接远程前在GDB中执行:
file my_proj - 若为交叉编译(如远程是嵌入式设备),需将远程程序的符号文件(未strip的
my_proj)拷贝到本地,再加载:file /path/to/local/copy/of/my_proj
- 若远程与本地为同一编译环境(如同一机器、相同架构系统),连接远程前在GDB中执行:
启用并验证pretty-printer
在GDB中执行以下命令:# 开启漂亮打印格式 set print pretty on # 检查是否加载了libstdc++打印机 info pretty-printer若输出中无
libstdcxx相关条目,需手动加载对应版本的脚本(路径根据GCC版本调整):source /usr/share/gcc-11/python/libstdcxx/v6/printers.py验证调试效果
重新连接远程目标后打印变量:target remote localhost:2345 p s此时应输出
$1 = "qwe"的友好格式。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

