Discussion:
help with pretty printers
(too old to reply)
Matei David
2014-07-21 18:00:45 UTC
Permalink
Raw Message
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

Loading...