How to pretty-print STL containers in GDB?

Viewed 50279

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.

9 Answers

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

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:

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. ^_^

e.g. vectors are accessed by ._M_impl._M_start

p vec._M_impl._M_start + 4 # prints vec[4]

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++.

Similar to enter link description here Worked for me in ~/.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
Related