Linux 如何在 GDB 中漂亮地打印 STL 容器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11606048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pretty-print STL containers in GDB?
提问by Nick Hutchinson
I've followed the instructions on the GDB wikito install the python pretty-printers for viewing STL containers. My ~/.gdbinit
now looks like this:
我已经按照GDB wiki 上的说明安装了用于查看 STL 容器的 python 漂亮打印机。我~/.gdbinit
现在看起来像这样:
python
import sys
sys.path.insert(0, '/opt/gdb_prettyprint/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
However, when I run GDB and attempt to print an STL type, I get the following:
但是,当我运行 GDB 并尝试打印 STL 类型时,我得到以下信息:
print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.:
=
Can anyone shed some light on this? I'm running Ubuntu 12.04, which comes with GDB 7.4.
任何人都可以对此有所了解吗?我正在运行 GDB 7.4 附带的 Ubuntu 12.04。
回答by Omnifarious
I think you are using a non-GNU STL library, or possible a very old GCC libstdc++
. The type of a normal STL string on my compiler is: std::basic_string<char, std::char_traits<char>, std::allocator<char> >
. Note that this is not std::basic_string<char>
.
我认为您使用的是非 GNU STL 库,或者可能是非常旧的 GCC libstdc++
。我的编译器上普通 STL 字符串的类型是:std::basic_string<char, std::char_traits<char>, std::allocator<char> >
. 请注意,这不是std::basic_string<char>
.
The Python code has this in it:
Python 代码中包含以下内容:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
This look up a nested type ::Rep
of whatever the base string type actually is. The error message inidicates that the string class of whatever strange library you're using doesn't actually have a ::Rep
nested type.
这将查找::Rep
任何基本字符串类型的嵌套类型。该错误消息表明您使用的任何奇怪库的字符串类实际上都没有::Rep
嵌套类型。
回答by Fei
You can try with below GDB macro(append it to your ~/.gdbinitfile) to print STL containter types data and even their data members: https://gist.github.com/3978082
您可以尝试使用以下GDB 宏(将其附加到您的~/.gdbinit文件)来打印 STL 容器类型数据甚至它们的数据成员:https: //gist.github.com/3978082
回答by Manuel Nú?ez
If you type info type _Rep
after the Python exception, gdb will inform you about the classes loaded that match _Rep. That list could help you to find why python cannot find your std::string class
.
如果info type _Rep
在 Python 异常之后键入,gdb 将通知您加载的与 _Rep 匹配的类。该列表可以帮助您找出为什么 python 找不到您的std::string class
.
I just faced your problem and in my case was intel c compiler, icc, who broke pretty printing. In particular, unqualified icc name for std::string
results in:
我刚刚遇到了你的问题,在我的情况下是英特尔 c 编译器 icc,他破坏了漂亮的打印。特别是,不合格的 icc 名称std::string
导致:
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep;
but pretty printer was looking for unqualified gcc name:
但是漂亮的打印机正在寻找不合格的 gcc 名称:
std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;
What I did to solve my problem was modifying class StdStringPrinter
in printers.py, adding the unqualified name of the string to the typename to look in gdb. Replacing the line:
我为解决我的问题所做的是修改StdStringPrinter
printers.py中的类,将字符串的非限定名称添加到typename以在gdb中查找。更换线路:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
with this:
有了这个:
reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
With the obtained list from info type
you could fix your pretty printers to make them work.
使用从info type
您那里获得的列表可以修复您漂亮的打印机以使其工作。
回答by Bingfeng
Check your gcc version. If it is less than 4.7, you need use another printer.py file. Get the file from http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/.
检查您的 gcc 版本。如果小于 4.7,则需要使用另一个 printer.py 文件。从http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/获取文件。
回答by bartgol
I ran on this problem and hit this page while trying to figure it out. I eventually fixed it, and I thought it would be worth it to share my experience.
我遇到了这个问题并在试图弄清楚时点击了这个页面。我最终修复了它,我认为分享我的经验是值得的。
I am using gcc-5.2, so I downloaded the gcc-5-branch version of pretty printer from the svn repo. However, I had to do these two mods:
我使用的是 gcc-5.2,所以我从 svn repo 下载了漂亮打印机的 gcc-5-branch 版本。但是,我必须做这两个模组:
1) when editing the .gitinit file, the suggested addition is
1) 编辑 .gitinit 文件时,建议添加的是
python
import sys
sys.path.insert(0, '/home/bartgol/.gdb/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
However, I had to comment the line register_libstdcxx_printers (None)
, since I kept getting an error telling me the libstdcxx_printers were already registered. Apparently they get registered during the import phase.
但是,我不得不评论该行register_libstdcxx_printers (None)
,因为我不断收到错误消息,告诉我 libstdcxx_printers 已经注册。显然,他们是在导入阶段注册的。
2) I had to edit the printers.py file for std::set
and std::map
. Since the type _Rep_type
is private in both. In particular, I replace the routine children
in std::map
and std::set
with the corresponding one in the version of pretty printer from the gcc-4_6-branch version on the svn repo. Got no error ever since, and stuff prints out nicely now.
2)我必须为std::set
和编辑printers.py 文件std::map
。由于类型_Rep_type
在两者中都是私有的。特别是,我代替常规children
的std::map
,并std::set
在从将svn的GCC-4_6分支版本漂亮的打印的版本对应的一个。从那以后没有错误,现在打印出来的东西很好。
Hope this helps.
希望这可以帮助。
回答by Ans
Errors like you post above usually appears when program is LLVM-build (compiled by clang
), and you try to debug it by gdb
(which should be used for GCC-build programs).
In theory, LLVM-build program may be debugged by gdb
, and vice versa. But
to avoid problems like posted above, you should use lldb
if you use clang
, and should use gdb
if you use g++
.
当程序是 LLVM 构建(由 编译clang
)时,通常会出现像您在上面发布的错误,并且您尝试通过gdb
(应该用于 GCC 构建程序)对其进行调试。理论上,LLVM-build 程序可以通过 调试gdb
,反之亦然。但是为了避免上面发布的问题,你应该使用lldb
if you use clang
,并且应该使用gdb
if you use g++
。
回答by Scott Yang
Instead of methods listed in the link you mentioned, you can try the script here,
Do as follows:
执行以下操作:
1) Download the script to /your/path
. Name it to some name e.g. your_name.conf
.
1) 将脚本下载到/your/path
. 将其命名为某个名称,例如your_name.conf
。
2) Add a ~/.gdbinit
file to home directory if you don't have one.
2)~/.gdbinit
如果没有文件,则将文件添加到主目录。
3) Add a line source /your/path/your_name.conf
to your ~/.gdbinit
.
3)source /your/path/your_name.conf
在你的~/.gdbinit
.
4) Restart gdb. Try pvector
4) 重启 gdb。尝试pvector
You can find help information with commands like help pvector
.
您可以使用诸如help pvector
.
e.g.
例如
pvector vec 5 # Prints element[5] in vec
pvector vec 5 10 # Prints elements in range [5, 10] in vec. (5, 6, 7, 8, 9, 10)
FYI, the scriptadds several commands (pvector
, plist
, pmap
etc.) to gdb whose function is to print the elements of STL. It also adds print pretty
, yielding nice format like this:
仅供参考,该脚本增加了几个命令(pvector
,plist
,pmap
等),以GDB,其功能是打印STL的元素。它还添加了print pretty
,产生了这样的好格式:
Also, if you wanna know how exactly the elements of STL are accessed in gdb, just read the code of the commands. There's no secret in the code. ^_^
另外,如果您想知道在 gdb 中究竟如何访问 STL 的元素,只需阅读命令的代码即可。代码中没有秘密。^_^
e.g.
vectors are accessed by ._M_impl._M_start
例如向量被访问 ._M_impl._M_start
p vec._M_impl._M_start + 4 # prints vec[4]
p vec._M_impl._M_start + 4 # prints vec[4]
回答by Yotam
Similar to enter link description hereWorked for me in ~/.gdbinit:
类似于在此处输入链接描述在 ~/.gdbinit 中为我工作:
python
import sys
sys.path.insert(0, '/usr/share/gcc-8/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end