VS Code中开启GDB的pretty-printer功能

准备pretty-printer

pretty-printer是干什么的

众所周知,C++的STL容器的实现并不直观,直接使用gdb之类的debugger查看内存是需要周转多次才能看到具体的内容的。
在Visual Studio之类的IDE中内置了一些脚本,用来较为友好的显示容器内的元素。

GDB的pretty-printer脚本提供了类似的功能。

举个例子:
假设我们有如下c++代码

std::vector<int> vec{1,2,3,4};
std::string s="this is my string.";

在关闭和开启pretty-printer的情况下,我们使用GDB查看vec和s的时候看到的会是诸如下面这样的输出。在前面关闭prety-printer时,现实的是它们的具体实现中用到的成员变量,而开启之后显示的是具体的内容。

(gdb) disable pretty-printer 
163 printers disabled
0 of 163 printers enabled
(gdb) p vec
$1 = {<std::_Vector_base<int, std::allocator<int> >> = {
    _M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, _M_start = 0x615c20, _M_finish = 0x615c30, 
      _M_end_of_storage = 0x615c30}}, <No data fields>}
(gdb) p s
$2 = {static npos = 18446744073709551615, 
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x615c40 "this is my string."}, 
  _M_string_length = 18, {
    _M_local_buf = "\022\000\000\000\000\000\000\000-\031@\000\000\000\000", 
    _M_allocated_capacity = 18}}

(gdb) enable pretty-printer 
163 printers enabled
325 of 325 printers enabled
(gdb) p vec
$3 = std::vector of length 4, capacity 4 = {1, 2, 3, 4}
(gdb) p s
$4 = "this is my string."

安装pretty-printer

很遗憾虽然pretty-printer是GDB官方提供的,但是并没有默认安装/开启。所以需要手动安装。
需要注意的是,这个脚本是使用python开发的,所以需要7.0及以后的版本的GDB。

可以很方便的通过gcc官网下载 :
https://gcc.gnu.org/svn/gcc/trunk/libstdc+±v3/python/ 。
然后配置.gdbinit文件,开启它。

官网并没有自动打包,所以直接下载需要下载很多文件,推荐使用svn下载,或者解压我打包好的这个文件。
https://pan.baidu.com/s/11mWDYO60CsSNt8hcz66zOw

推荐将下载好的文件放在 ~/.gdb 目录下,如果没有可以自行创建。

# 使用svn下载的方法示例(前提是已经安装了svn)
mkdir ~/.gdb
cd ~/.gdb
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python stlprettyprinter

2021年10月更新:
GCC的代码管理模式从SVN更换到Git, 上面的那个链接和方式已经失效。
大家可以通过 https://gcc.gnu.org/git/?p=gcc.git;a=tree;f=libstdc%2B%2B-v3/python/libstdcxx;hb=HEAD 来访问并下载v6目录(随着gcc版本更新,这个目录名后续可能会变)下的printers.py脚本到你的~/.gdb目录(或其他你喜欢的地方)。


.gdbinit文件的配置也很简单(它要放在home目录下,如果没有配置过gdb那么很可能需要自己创建):
其中“/home/xxx/”为当前用户的home目录,假设脚本文件被放在了“/home/xxx/.gdb/stlprettyprinter/”。

python
import sys
sys.path.insert(0, '/home/xxx/.gdb/stlprettyprinter') # 按实际情况修改目录
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

配置成功之后,它就是默认开启的了,不需要再像我在演示中那样在GDB中使用enable/disable pretty-printer命令控制。

其他

早期的pretty-printer脚本不支持Python 3.0,但是现在已经没有这个问题了,无论你配置的默认python版本是什么,它都可以正常运行。
所以不要按照你在网上搜到的旧文章的指导去修改它。

在VS Code中自动开启pretty-printer

VS Code的Variables窗口默认显示的是内存映像,即使你的GDB已经开启了pretty-printer。

此时如果pretty-printer配置正常,在VS Code的debug console中输入-exec print vec命令是可以看到处理后的输出的。

在VS Code的debug console中输入-exec -enable-pretty-printing命令,可以临时开启pretty-printer,但是下次调试的时候需要重新输入。

使用VS Code的launch.json的setupCommands,可以自动执行这句指令。在MIMode同一级添加一个setupCommands。它可能是第一级的(和name在同一级),也可能是在特定平台的配置下(一般为linux下)。

"setupCommands": [
                    { "text": "-enable-pretty-printing", "description": "enable pretty printing", "ignoreFailures": true }
                ]

注意:在VS Code中,这个配置的名字叫做pretty-printing,而不是pretty-printer。

Configuring launch.json for C/C++ debugging: https://github.com/Microsoft/vscode-cpptools/blob/master/launch.md
一个相关的issue:
https://github.com/Microsoft/vscode-cpptools/issues/69

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐