Print the elements of a C++ vector in GDB?
26 April, 2013 - 3 min read
With GCC 4.1.2, to print the whole of a std::vector<int> called myVector, do the following:
print *(myVector._M_impl._M_start)@myVector.size()
To print only the first N elements, do:
print *(myVector._M_impl._M_start)@N
Explanation
This is probably heavily dependent on your compiler version, but for GCC 4.1.2, the pointer to the internal array is:
myVector._M_impl._M_start
And the GDB command to print N elements of an array starting at pointer P is:
print P@N
Or, in a short form (for a standard .gdbinit):
p P@N
(gdb) what vIPIFMOC
type = std::vector<SManagedObj,std::allocator<SManagedObj> >
(gdb) p vIPIFMOC
$2 = {
<std::_Vector_base<SManagedObj,std::allocator<SManagedObj> >> = {
_M_impl = {
<std::allocator<SManagedObj>> = {
<__gnu_cxx::new_allocator<SManagedObj>> = {<No data fields>}, <No data fields>},
members of std::_Vector_base<SManagedObj,std::allocator<SManagedObj> >::_Vector_impl:
_M_start = 0x556802cb70,
_M_finish = 0x556802cc30,
_M_end_of_storage = 0x556802cc30
}
}, <No data fields>}
(gdb) p *(vIPIFMOC._M_impl._M_start)@1
Options-2:
In the gdb:
source {full_path}stl-views.gdb
now you'll have new commands, such as pvector, plist, pmap
and more (replace {full_path} with the full path to the file.
You can also put the command source stl-views.gdb
in ~/.gdbinit
- and then you'll have it automatically every time you launch gdb.
Option-3:
For performance reasons, SGI's STL implmentation is all inline; a naming convention is generally followed (i.e. double underscore as a prefix for local variables), but tends to create long, cryptic variable names. Unfortunately, raw gdb is not a graceful way to debug STL-heavy code, the reasons being -
- First, the 'T' in "STL" stands for "template"; while you as a programmer have full information about what is the argument to the template, gdb does not necessarily have access to this knowledge. As a result, gdb will tend to think that every (templated) pointer is a (void*), and will have no access to its internals should it point to a class.
- The traversal of some containers (hashes, trees) is complicated; obtaining the "first()" and "next()" elements of a container is a tricky task.
- Some data, such as the size of lists, is not stored explicitly - and there is simply no way to find it out in gdb.
gdb_stl_utils.gdb is a small utility that may help solving these problems.
To use it, download and compile StlStdContainers.cc (a simple g++ StlStdContainers.cc -o StlStdContainers.o will do); then, load gdb_stl_utils into gdb by using the command "source gdb_stl_utils" (in gdb) or including in .gdbinit. You will then have access to the following gdb function:
p_stl_vector, p_stl_vector_size
p_stl_list, p_stl_list_size
p_stl_tree, p_stl_tree_size (for maps and sets)
p_stl_hash, p_stl_hash_size (for hash_maps and sets)
The names are self-explanatory: the functions print the contents and the sizes of STL containers given to them.
Good luck and happy debugging!
Note: From above attachments, remove .doc extensions and use.