How to enable pretty printing for STL in GDB

Printing a C++ STL container in GDB produces information about the internal structure of the container that is hard to understand:

(gdb) print foo_int_vector
$1 = {<std::_Vector_base<int, std::allocator<int> >> = {_M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, _M_start = 0x603010, _M_finish = 0x60301c, 
      _M_end_of_storage = 0x60301c}}, <No data fields>}

By adding pretty printing support, we can get information about the STL container that is easy to understand:

(gdb) print foo_int_vector
$1 = std::vector of length 3, capacity 3 = {34, 999, 345}

To enable pretty printing is easy:

  • Ensure that the GDB version is 7.0 or later. This means it has support for Python scripting.

  • Check out the Python module to perform pretty printing of STL containers:

$ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python stlprettyprinter
  • The GDB that I had in Ubuntu was compiled to run Python 3.4. The Python file printers.py downloaded in the above step gave errors with it. I found an alternate printers.py from here that worked.

  • Open ~/.gdbinit and add these lines:

python
import sys
sys.path.insert(0, '/home/joe/stlprettyprinter')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
  • That is it, this gave me pretty printing of STL containers as shown above! 🙂

References:

Tried with: GDB 7.7 and Ubuntu 14.04

GDB error on cannot find source file

Problem

I was debugging C++ code using the Eclipse debugger. This uses the GDB debugger underneath. I had put a breakpoint inside a class method and was trying to step through that code. I was able to step over a few statements in the method, but on a particular statement that called fgets, a standard C function, Eclipse threw up this error:

Can't find a source file at
"/build/buildd/eglibc-2.19/libio/iofgets.c"

Using GDB directly to perform the above operations gave the same error, so it was the program actually throwing this error. I could understand this error if I wanted to step into fgets. But, all I was doing was stepping over the call and yet it wanted the definition of this function!

Solution

In my haste, I had forgotten that the class method was defined in a header file. Many C++ projects these days include both the declaration and definition of a class in the header file itself. This was one such class.

Since I had to step through and debug this class, I manually pulled out the class method definitions into a C++ source file and separated it from the header file. After compiling these files, I was able to step through the code of the same class method without any mysterious errors.

Tried with: GDB 7.7, Eclipse 3.8.1 and Ubuntu 14.04

The strange case of gdb not finding any symbol

Problem

I compiled C++ code using the g++ compiler. The -g option was specified so that the executable had debugging information. I could run the program using gdb and place breakpoints and look at the source code. However, when I tried to print the value of a variable in gdb, it threw this strange error:

(gdb) print i
No symbol "i" in current context

I tried using Eclipse CDT to compile and debug the same C++ code. Again, I got a similar result. I could run in Debug mode and the program could stop at a breakpoint. However, the Variables window did not show any of the local variables. Hovering the mouse cursor over any local variable did not show its current value!

Solution

The culprit turned out to be a mismatch between the compiler and debugger! I had recently switched to GCC 4.8, a newer version. However, I was still using the old version of GDB. In v4.8, GCC produces debugging information in the DWARF4 format, as explained in its release notes. However, this older version of GDB could only understand DWARF3 or versions older than that. It was failing silently when local variables were requested.

The solution was simple: request GCC to produce debugging information in the older format by specifying -gdwarf-3. Once I did this, GDB could print local variables and they appeared in Eclipse CDT too.

Tried with: GCC 4.8, GDB 7.4 and Ubuntu 12.04 LTS