help with pretty printers

Matei David <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <20140721140045.3b722065@ara-vm-ku1404-3>
Hi,

I'm working on a pretty printer for boost::intrusive ("bi") data
structures, and I'm having trouble accessing certain types and methods
in gdb.

Consider the attached cpp file.

I'm using stock Kubuntu 14.04:
Linux 3.13.0-32-generic #57-Ubuntu SMP x86_64
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
boost 1.55.0
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7

I'm compiling with:
g++ -O0 -ggdb3 -fno-inline -std=c++11 -Wall -Wextra -pedantic -o
test-intrusive-list test-intrusive-list.cpp

If I break at line 40 (return), I get:

(gdb) p l1.begin()
Cannot evaluate function -- may be inlined
(gdb) 


My goal here is to write a printer for bi::list. Because
this template class is customized by various traits classes at compile
time, traversing it at runtime is not as simple as accessing various
struct fields. Instead, I need to use some of the methods embedded in
the specific instantiation I deal with.

The definition of bi::list is
in /usr/include/boost/intrusive/list.hpp
I'll briefly decode it here:

- bi::list is a public bi::list_impl
- a bi::list_impl has a root "node" with pointers to a circular
  linked list of "value" elements
- each "value" has an embedded "node" part which is used to traverse
  the list
- given a node n from a list l, access to the next node in that list is
  done through the static method l::node_traits::get_next(n) found in
  the traits class l::node_traits
- different bi::list instantiations may use different fields of "value"
  to maintain list node pointers
- for a bi::list_impl l, the root node is
  l.data_.root_plus_size_.root_, or equivalently, l.get_root_node()
- the first element in l is:
    list_impl<...>::node_traits::get_next(l.get_root_node())
    or, * (l.begin())


As I described above, for some reason I am unable to call l.begin(). I
then tried to access the traits method by hand, but I can't do that
either:

(gdb) ptype/rmt l1
type = class boost::intrusive::list<A,
boost::intrusive::value_traits<boost::intrusive::trivial_value_traits<NT_1<void*>,
(boost::intrusive::link_mode_type)0> >, void, void> : public
boost::intrusive::list_impl<boost::intrusive::trivial_value_traits<NT_1<void*>,
(boost::intrusive::link_mode_type)0>, unsigned long, true> { }

(gdb) ptype/rmt
boost::intrusive::list_impl<boost::intrusive::trivial_value_traits<NT_1<void*>,
(boost::intrusive::link_mode_type)0>, unsigned long, true>::node_traits
There is no field named node_traits

(gdb) p l1.data_.root_plus_size_.root_
$2 = {_val = 0, _prev_1 = 0x7fffffffd4a0, _next_1 = 0x7fffffffd4a0,
_prev_2 = 0x7fffffffd5e0, _next_2 = 0x0}

(gdb) p
boost::intrusive::list_impl<boost::intrusive::trivial_value_traits<NT_1<void*>,
(boost::intrusive::link_mode_type)0>, unsigned long,
true>::node_traits::get_next(l1.data_.root_plus_size_.root_)
No type node_traits" within class or namespace
"boost::intrusive::list_impl<boost::intrusive::trivial_value_traits<NT_1<void*>,
(boost::intrusive::link_mode_type)0>, unsigned long, true>".


Am I missing some debugging symbols here? Are there some other
compile flags I can try?

Is there something else I could try to find and call the get_next()
method?


Thanks,
Matei
test-intrusive-list.cpp (text/x-c++src, 1.2 KB)
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/trivial_value_traits.hpp>
namespace bi = boost::intrusive;

struct A
{
    A(int i = 0) : _val(i) {}

    int _val;
    A* _prev_1;
    A* _next_1;
    A* _prev_2;
    A* _next_2;
};

template<class VoidPointer>
struct NT_1
{
    typedef A node;
    typedef typename bi::pointer_traits<VoidPointer>::template rebind_pointer<node>::type node_ptr;
    typedef typename bi::pointer_traits<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;

    static node_ptr get_next(const node_ptr& n)                  { return n->_next_1; }
    static node_ptr get_next(const const_node_ptr& n)            { return n->_next_1; }
    static void set_next(const node_ptr& n, const node_ptr& next){ n->_next_1 = next; }
    static node_ptr get_previous(const node_ptr& n)              { return n->_prev_1; }
    static node_ptr get_previous(const const_node_ptr& n)        { return n->_prev_1; }
    static void set_previous(const node_ptr& n, const node_ptr& prev) { n->_prev_1 = prev; }
};

typedef bi::trivial_value_traits< NT_1<void*>, bi::normal_link > VT_1;
typedef bi::list< A, bi::value_traits< VT_1 > > List_1;

int main()
{
    List_1 l1;
    A a(42);
    l1.push_front(a);

    return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.