How to pretty-print STL containers in GDB?
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
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
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.