在Linux项目开发过程中使用命令行GDB进行C++程序STL调试时,会发现输出的内容很杂乱,真正有用的信息比较难找。 可以从GCC、Clang的官网下载一个GDB的美化插件: Clang的libcxx可以从 https://github.com/llvm/llvm-project/tree/main/libcxx/utils/gdb下载整个libcxx目录 GCC的libstdc++可以从 https://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3/python下载整个libstdcxx目录

下载完成后在用户主目录(比如笔者的主目录为/home/admin)创建一个gdbscripts目录,把下载的两个目录放在gdbscripts下,结果如下图所示:

然后再在主目录创建一个.gdbinit文件,内容如下:

1python
2import sys
3sys.path.insert(0, '/home/admin/gdbscripts')
4from libstdcxx.v6.printers import register_libstdcxx_printers
5register_libstdcxx_printers (None)
6
7from libcxx.printers import register_libcxx_printer_loader
8register_libcxx_printer_loader()
9end

如果是Windows,则需要设置HOME环境变量:

然后把上面脚本中的路径由:

‘/home/admin/gdbscripts’

改为:

C:/Users/Administrator/gdbscripts

这样就可以使用GDB直观地输出GCC的以及Clang的STL容器了。

特别注意,Windows版本的GDB有些版本可能不支持字符编码转换,所以在控制台显示中文会是乱码,目前测试过的SysGCC9.1以及MinGW64下的GDB都有这个问题,原MinGW下的GDB没这个问题,但是调试器有点老了。网上查了一下资料, 这篇文章说是在编译GDB时需要有iconv包,如果没有,可能导致编译出来的gdb在显示unicode字符的时候会变成乱码。 如果愿意自己折腾的话,可以网上查资料自己编译一个功能完整的GDB版本;不愿意折腾的,也可以使用VisualGDB+笔者增强的CSTLTypeVisualizer.dll库进行可视化调试,参见: VisualGDB可视化调试STL

如果成功加载了libc++的美化输出插件会有提示:

下面罗列了脚本对一些常用的数据类型的支持对比: 类型Clang libcxxGCC libstdcxxbasic_string支持支持string支持支持tuple支持支持unique_ptr支持支持shared_ptr支持支持weak_ptr支持支持bitset支持支持deque支持支持queue支持支持stack支持支持priority_queue支持支持map支持支持multimap支持支持set支持支持vector支持支持__map_iterator支持支持__map_const_iterator支持支持__tree_iterator支持支持__tree_const_iterator支持支持fpos支持支持unordered_set支持支持unordered_multiset支持支持unordered_map支持支持unordered_multimap支持支持__hash_map_iterator支持支持__hash_map_const_iterator支持支持__hash_iterator支持支持__hash_const_iterator支持支持pair不支持支持forward_list不支持支持

还有一些GCC支持的,Clang不支持的,这里就不一一罗列了,详情请查看源文件。

关于Clang的插件脚本,注意脚本中的一段话:

“”“GDB pretty-printers for libc++. These should work for objects compiled when _LIBCPP_ABI_UNSTABLE is defined and when it is undefined. “””

另外,如果使用Clang编译器进行编译,如果使用的是clang的libc++库,调试版需要定义宏:

_LIBCPP_DEBUG=1

如果使用的是GCC的libstdc++库,调试版需要定义宏:

_GLIBCXX_DEBUG

否则调试时看不到字符串的值。当然如果使用GCC编译器,调试版也建议加上。