Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

print static variable from member function of template class in gdb

I have a simple template class:

namespace test
{

template< class Key, class Value, class Container = std::map< Key, Value > >
class DB
{
public:

    static DB& instance()
    {
        static DB _instance;

        return _instance;
    }
private:
    DB(){};
    DB( DB const& ){};
    void operator=( DB const& ){};

    Container _db_internal;
};
}

When I debug in gdb I want to see the _db_internal container, but don't know how to access it.

I tried writing in gdb:

p 'test::DB<std::string, someclass*, std::tr1::unordered_map< std::string, someclass* > >::instance()::_instance'._db_internal

and it gives me: No symbol ... in current context

also tried without single quotes but no luck.

How to print that container in gdb? I'm using gdb version: 7.6.1

Thanks

As suggested using gdb autocomplete I was able to get this:

p 'test::DB<std::string, std::string, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > >::instance()::_instance'

but that gives me 0 which is not good

then if I tried:

p 'test::DB<std::string, std::string, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > >::instance()::_instance._db_internal' 

I also got an error saying:

No symbol "test::DB<std::string, std::string, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > >::instance()::_instance._db_internal" in current context.
like image 274
Jan Avatar asked Sep 27 '16 11:09

Jan


1 Answers

but that gives me 0 which is not good

That seems to be a bug in GDB, still present in GDB built from git as of a few days ago. This works:

(gdb) start
Temporary breakpoint 1 at 0x400865: file foo.cc, line 27.
Starting program: /tmp/a.out 
Temporary breakpoint 1, main () at foo.cc:27
27    auto& db = test::DB<int, int>::instance();
(gdb) n
28    return 0;
(gdb) p 'test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >::instance()::_instance'
$1 = 0

That reproduced your behavior. Let's find out where the _instance resides:

(gdb) info var _instance
All variables matching regular expression "_instance":

Non-debugging symbols:
0x0000000000602088  guard variable for test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >::instance()::_instance
0x00000000006020a0  test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >::instance()::_instance

... and interpret the address 0x00000000006020a0 as a pointer to desired type:

(gdb) p ('test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >' *)0x00000000006020a0
$2 = (test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > > *) 0x6020a0 <test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >::instance()::_instance>

Finally we can dereference it:

(gdb) p *$
$3 = {_db_internal = {_M_t = {_M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<int const, int> > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, int> > >> = {<No data fields>}, <No data fields>}, 
        _M_key_compare = {<std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>}, _M_header = {_M_color = std::_S_red, _M_parent = 0x0, 
          _M_left = 0x6020a8 <test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >::instance()::_instance+8>, 
          _M_right = 0x6020a8 <test::DB<int, int, std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >::instance()::_instance+8>}, _M_node_count = 0}}}}

P.S. I used <int,int> as the instance, since I had to complete your snippet to a program I can compile and run. (You should have provided a complete program, but didn't).

like image 113
Employed Russian Avatar answered Oct 23 '22 05:10

Employed Russian