GDB: print the c++ STL object

For me debugging becomes painful in Unix compared to Windows.

I came across an interesting problem. I had to display the contents of unordered_set of a running process on Ubuntu server. I attached the GDB to running process and tried to display the contents. Here is what I got:

1. Attach GDB to a running process:

Get the pid of running process foo. $ps -aef | grep foo Attach gdb to the pid of process foo $sudo gdb -p pid

2. Display the unordered_set contents

(gdb) print set_contents
$1 = {<std::tr1::__unordered_set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, false>> = {<std::tr1::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, true, true>> = {<std::tr1::__detail::_Rehash_base<std::tr1::__detail::_Prime_rehash_policy, std::tr1::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, true, true> >> = {<No data fields>}, <std::tr1::__detail::_Hash_code_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, false>> = {
        _M_extract = {<std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<No data fields>}, <No data fields>},
        _M_eq = {<std::binary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>> = {<No data fields>}, <No data fields>},
        _M_h1 = {<std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long>> = {<No data fields>}, <No data fields>},
        _M_h2 = {<No data fields>}}, <std::tr1::__detail::_Map_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, true, std::tr1::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, true, true> >> = {<No data fields>},
      _M_node_allocator = {<__gnu_cxx::new_allocator<std::tr1::__detail::_Hash_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, false> >> = {<No data fields>}, <No data fields>}, _M_buckets = 0x1fc6550, _M_bucket_count = 11, _M_element_count = 1, _M_rehash_policy = {
        _M_max_load_factor = 1, _M_growth_factor = 2,
        _M_next_resize = 11}}, <No data fields>}, <No data fields>}

There is no way you can make out what are the contents of STL object with this output.

Then I came across this article: https://sourceware.org/gdb/wiki/STLSupport

Following steps helped me to achieve my goal:

1. Check-out the latest Python libstdc++ printers to a place on your machine. In a local directory, do:
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python

2. Add the following to your ~/.gdbinit. The path needs to match where the python module above was checked-out. So if checked out to: /home/maude/gdb_printers/, the path would be as written in the example:

python
import sys
sys.path.insert(0, '/home/maude/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

After this GDB started displaying the contents of unordered_set as expected:

(gdb) print set_contents 
$1 = std::unordered_set with 1 elements = {"2014-03-15/449782CE-10E6-4233-A143-61CB6314E103" }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s