众所周知,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下载,推荐将下载好的文件放在 ~/.gdb 目录下,如果没有可以自行创建。
# 使用svn下载的方法示例(前提是已经安装了svn)
mkdir ~/.gdb
cd ~/.gdb
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python stlprettyprinter
.gdbinit文件的配置也很简单(它要放在home目录下,如果没有配置过gdb那么很可能需要自己创建):
其中“/home/xxx/”为当前用户的home目录。
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。