public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* help with pretty printers
@ 2014-07-21 18:00 Matei David
  0 siblings, 0 replies; only message in thread
From: Matei David @ 2014-07-21 18:00 UTC (permalink / raw)
  To: gdb

[-- Attachment #1: Type: text/plain, Size: 3136 bytes --]

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

[-- Attachment #2: test-intrusive-list.cpp --]
[-- Type: text/x-c++src, Size: 1266 bytes --]

#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;
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-07-21 18:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-21 18:00 help with pretty printers Matei David

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).