本文中的VisualGDB开发调试环境为Visual Studio 2015加VisualGDB 5.4R12版本,并且使用了笔者改进过的STL可视化调试库CSTLTypeVisualizer.dll,原版的STLTypeVisualizer.dll不支持字符串转码,不支持Clang的STL调试。

一、 Windows项目

VisualGDB的Windows项目可以使用MinGW或者Cygwin作为开发环境,它们默认都是使用的GCC编译器,所以配置上没什么差别。笔者使用VisualGDB官方出的 SysGCC 9.1作为示例来说明(如果想使用更新一些的工具集,可以使用msys2中的MinGW32/MinGW64,它不仅支持GCC,还支持clang,目前最新的GCC版本为9.2,GDB为8.3.1,Clang为9.0)。

由于是Windows项目,控制台默认是使用的本地编码,简体中文使用的GBK,所以需要在编译时加上-fexec-charset=GBK参数,这样在控制台的输出才能正常显示,如果控制台是其它编码,编译时设置为一样的编码即可。但是这样设置后,调试字符串时会看到是乱码。所以还需要运行GDB的命令:

1set charset UTF-8
2set target-charset GBK

其中: set charset UTF-8是设置主机(host)字符编码为UTF8 set target-charset GBK是设置目标程序的编码为GBK。

这样设置后,GDB会将目标程序编码自动转换为主机(host)字符编码,即由GBK转为UTF-8,然后CSTLTypeVisualizer.dll会以UTF-8编码解析这个字符串(为了兼容性,CSTLTypeVisualizer.dll默认GDB的host-charset为UTF-8,即只接受以UTF-8编码的字符串)。如果是使用命令行GDB直接调试,则需要把charset与target-charset都设置为GBK,否则调试字符串时会显示乱码。 另外,由于GDB默认的输出字符串有长度限制,默认是200,如果字符串比较长,想要全部显示(会影响性能),可以使用命令:

1set print element 0

需要注意的是:不是所有Windows发行版本的GDB都完全支持这些命令,笔者使用的这个发行版本是完全支持的。

二、 Linux项目

Linux平台的下可以选择的组合就比较多了,构建方式VisualGDB支持Makefile以及CMake等,CMake又支持GNU make和ninja两种,编译器支持GCC以及Clang,所以喜欢怎么用就怎么用。

这里需要注意的是: 1.如果使用Clang编译器进行编译,如果使用的是clang的libc++库,调试版需要定义宏:

_LIBCPP_DEBUG=1

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

_GLIBCXX_DEBUG

否则调试时看不到字符串的值。当然如果使用GCC编译器,调试版也建议加上。 2.如果使用CMake时,在建立好项目后,点Underlying build system右边的按钮重新选择使用GNU Make还是Ninja时,下面一行的构建命令不会自动更新,需要手动设置。这一点也适用于Windows项目。

上面所示即是没有更新构建命令,需要如下图所示的更改:

关于编码及乱码处理: 由于Linux平台下默认是UTF-8编码,GCC、Clang以及GDB也默认使用的是UTF-8编码,所以只有源码使用的不是UTF-8编码的情况下容易出现乱码。GCC以及Clang在不指定任何源文件编码的情况下(即不使用-finput-charset参数指定源文件编码),是将源码中的字符串原样处理的,即如果源码中的字符串是GBK编码,编译后还是GBK编码。所以我们可以用以下方式进行处理: 1.只要源文件能完全编译通过,有非法字符串编码的警告:

warning : illegal character encoding in string literal [-Winvalid-source-encoding]

可以不用管。在调试时设置GDB目标字符串编码(target-charset)为GBK即可,但是VisualGDB控制台输出字符串会是乱码。

下图是查看GDB的target编码与host编码,默认都是UTF-8,通过上面的设置后target-charset会变为GBK。

2.GCC可以使用参数进行设置,比如源码是GBK编码,可以添加编译参数:

-finput-charset=GBK

至于Clang,目前不支持除UTF-8外的编码,所以最好是将所有使用了ANSI编码外的源文件转为UTF-8编码(如果是只有注释使用了非ANSI编码就可以不用转了)。

三、运行效果图

下面是Windows测试用例的运行效果图:

string字符串:

const char*字符串:

set:

下面是Linux项目的运行图: Clang的string字符串

Clang的map: