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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 13:52:53  来源:igfitidea点击:

How to pretty-print STL containers in GDB?

c++linuxdebuggingstlgdb

提问by Nick Hutchinson

I've followed the instructions on the GDB wikito install the python pretty-printers for viewing STL containers. My ~/.gdbinitnow 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 ::Repof 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 ::Repnested 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 _Repafter 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::stringresults 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 StdStringPrinterin printers.py, adding the unqualified name of the string to the typename to look in gdb. Replacing the line:

我为解决我的问题所做的是修改StdStringPrinterprinters.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 typeyou 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::setand std::map. Since the type _Rep_typeis private in both. In particular, I replace the routine childrenin std::mapand std::setwith 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在两者中都是私有的。特别是,我代替常规childrenstd::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 lldbif you use clang, and should use gdbif you use g++.

当程序是 LLVM 构建(由 编译clang)时,通常会出现像您在上面发布的错误,并且您尝试通过gdb(应该用于 GCC 构建程序)对其进行调试。理论上,LLVM-build 程序可以通过 调试gdb,反之亦然。但是为了避免上面发布的问题,你应该使用lldbif you use clang,并且应该使用gdbif 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 ~/.gdbinitfile to home directory if you don't have one.

2)~/.gdbinit如果没有文件,则将文件添加到主目录。

3) Add a line source /your/path/your_name.confto 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, pmapetc.) to gdb whose function is to print the elements of STL. It also adds print pretty, yielding nice format like this:

仅供参考,该脚本增加了几个命令(pvectorplistpmap等),以GDB,其功能是打印STL的元素。它还添加了print pretty,产生了这样的好格式:

enter image description here

在此处输入图片说明

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