How to pretty-print STL containers in GDB?
Solution 1
It just works on Ubuntu 17.04
Debian seems to have finally integrated things properly now:
main.cpp
#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 main.out -std=c++98 main.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:
(gdb) 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 provided 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/releases/gcc-6.3.0/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244
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?
Custom classes
See how to define a custom toString
method and call it at: Printing C++ class objects with GDB
Inspect specific elements in optimized code
It was hard last time I checked, you get "Cannot evaluate function -- may be in-lined" C++, STL, GDB: Cannot evaluate function maybe inlined
On unoptimized code it works: Inspecting standard container (std::map) contents with gdb
Solution 2
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
Solution 3
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/.
Solution 4
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:
-
when editing the
~/.gdbinit
file, the suggested addition ispython 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.
- I had to edit the printers.py file for
std::set
andstd::map
. Since the type_Rep_type
is private in both. In particular, I replace the routinechildren
instd::map
andstd::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.
Hope this helps.
Solution 5
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
.
2) Add a ~/.gdbinit
file to home directory if you don't have one.
3) Add a line source /your/path/your_name.conf
to your ~/.gdbinit
.
4) Restart gdb. Try pvector
You can find help information with commands like 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 script adds 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:
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. ^_^
e.g.
vectors are accessed by ._M_impl._M_start
p vec._M_impl._M_start + 4 # prints vec[4]
Comments
-
Nick Hutchinson over 2 years
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: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:
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.