如何在GDB中打印STL容器?

时间:2020-12-26 21:44:01

I've followed the instructions on the GDB wiki to 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.: 
$3 = 

Can anyone shed some light on this? I'm running Ubuntu 12.04, which comes with GDB 7.4.

有人能解释一下吗?我正在运行Ubuntu 12.04,它自带GDB 7.4。

7 个解决方案

#1


7  

You can try with below GDB macro (append it to your ~/.gdbinit file) to print STL containter types data and even their data members: https://gist.github.com/3978082

您可以尝试使用下面的GDB宏(将它附加到~/中。打印STL容器类型数据,甚至他们的数据成员:https://gist.github.com/3978082。

#2


4  

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,则需要使用另一台打印机。py文件。从http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc+ -v3/python/获取文件。

#3


2  

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.

如果在Python异常之后键入info类型_Rep, gdb将通知您匹配_Rep的类。这个列表可以帮助您找到为什么python不能找到您的std::string类。

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,它破坏了漂亮的印刷。特别地,std::string的不限定icc名称导致:

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。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类型获得的列表,您可以修复漂亮的打印机,使其工作。

#4


1  

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 , std::allocator >。注意,这不是std::basic_string ,>

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嵌套类型。

#5


1  

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.

我得编辑一下打印机。std::set和std::map的py文件。因为两者中的_Rep_type类型都是私有的。特别地,我将std中的常规儿童替换为:map和std::在svn repo上从gcc-4_6-branch版本的漂亮打印机的版本中设置相应的。从那以后就没有出错了,现在东西打印得很好。

Hope this helps.

希望这个有帮助。

#6


1  

It just works on Ubuntu 17.04

它只适用于Ubuntu 17.04

Debian seems to have finally integrated things properly now:

Debian现在似乎终于正确地整合了事物:

#include <map>
#include <utility>
#include <vector>

int main() {
    std::vector<int> v;
    v.push_back(0);
    v.push_back(1);
    v.push_back(2);
    std::map<int,int> m;
    m.insert(std::make_pair(0, 0));
    m.insert(std::make_pair(1, -1));
    m.insert(std::make_pair(2, -2));
}

Compile:

编译:

g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp

Outcome:

结果:

(gdb) p v
$1 = std::vector of length 3, capacity 4 = {0, 1, 2}
(gdb) p m
$2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2}

We can see that the pretty printer is installed with:

我们可以看到漂亮的打印机安装了:

info pretty-printer

Which contains the lines:

它包含:

global pretty-printers:
  objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
  libstdc++-v6
    std::map
    std::vector

The printers are provieded by the file:

打印机被文件所记录:

/usr/share/gcc-7/python/libstdcxx/v6/printers.py

which comes with the main C++ library package libstdc++6 and is located under libstdc++-v3/python/libstdcxx in the GCC source code: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

它附带了主要的C++库包libstdc+ 6,位于libstdc+ -v3/python/libstdcxx的GCC源代码中

TODO: how GDB finds that file is the final mistery, it is not in my Python path: python -c "import sys; print('\n'.join(sys.path))" so it must be hardcoded somewhere?

TODO: GDB如何发现该文件是最终的错误,它不在我的Python路径中:Python -c“import sys;打印('\n'.join(sys.path)))“所以它必须硬编码在某个地方?

#7


0  

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-build(由clang编译)时,就会出现上面所提到的错误,并尝试通过gdb(应该用于GCC-build程序)对其进行调试。理论上,llvm构建程序可能会被gdb调试,反之亦然。但是为了避免上面提到的问题,如果使用clang,应该使用lldb,如果使用g++,应该使用gdb。

#1


7  

You can try with below GDB macro (append it to your ~/.gdbinit file) to print STL containter types data and even their data members: https://gist.github.com/3978082

您可以尝试使用下面的GDB宏(将它附加到~/中。打印STL容器类型数据,甚至他们的数据成员:https://gist.github.com/3978082。

#2


4  

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,则需要使用另一台打印机。py文件。从http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc+ -v3/python/获取文件。

#3


2  

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.

如果在Python异常之后键入info类型_Rep, gdb将通知您匹配_Rep的类。这个列表可以帮助您找到为什么python不能找到您的std::string类。

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,它破坏了漂亮的印刷。特别地,std::string的不限定icc名称导致:

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。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类型获得的列表,您可以修复漂亮的打印机,使其工作。

#4


1  

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 , std::allocator >。注意,这不是std::basic_string ,>

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嵌套类型。

#5


1  

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.

我得编辑一下打印机。std::set和std::map的py文件。因为两者中的_Rep_type类型都是私有的。特别地,我将std中的常规儿童替换为:map和std::在svn repo上从gcc-4_6-branch版本的漂亮打印机的版本中设置相应的。从那以后就没有出错了,现在东西打印得很好。

Hope this helps.

希望这个有帮助。

#6


1  

It just works on Ubuntu 17.04

它只适用于Ubuntu 17.04

Debian seems to have finally integrated things properly now:

Debian现在似乎终于正确地整合了事物:

#include <map>
#include <utility>
#include <vector>

int main() {
    std::vector<int> v;
    v.push_back(0);
    v.push_back(1);
    v.push_back(2);
    std::map<int,int> m;
    m.insert(std::make_pair(0, 0));
    m.insert(std::make_pair(1, -1));
    m.insert(std::make_pair(2, -2));
}

Compile:

编译:

g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp

Outcome:

结果:

(gdb) p v
$1 = std::vector of length 3, capacity 4 = {0, 1, 2}
(gdb) p m
$2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2}

We can see that the pretty printer is installed with:

我们可以看到漂亮的打印机安装了:

info pretty-printer

Which contains the lines:

它包含:

global pretty-printers:
  objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
  libstdc++-v6
    std::map
    std::vector

The printers are provieded by the file:

打印机被文件所记录:

/usr/share/gcc-7/python/libstdcxx/v6/printers.py

which comes with the main C++ library package libstdc++6 and is located under libstdc++-v3/python/libstdcxx in the GCC source code: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

它附带了主要的C++库包libstdc+ 6,位于libstdc+ -v3/python/libstdcxx的GCC源代码中

TODO: how GDB finds that file is the final mistery, it is not in my Python path: python -c "import sys; print('\n'.join(sys.path))" so it must be hardcoded somewhere?

TODO: GDB如何发现该文件是最终的错误,它不在我的Python路径中:Python -c“import sys;打印('\n'.join(sys.path)))“所以它必须硬编码在某个地方?

#7


0  

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-build(由clang编译)时,就会出现上面所提到的错误,并尝试通过gdb(应该用于GCC-build程序)对其进行调试。理论上,llvm构建程序可能会被gdb调试,反之亦然。但是为了避免上面提到的问题,如果使用clang,应该使用lldb,如果使用g++,应该使用gdb。