[boost-users] [multi_index] print object data member in gdb

Hi, I've been compiling & using multi_index without problem for a while; but when I use gdb to print multi_index_container objects, I couldn't find a way to easily traverse through its internal data structure. Here' s my multi_index_container object declaration: class MyClass { .... //define a multi_index_container with a list-like index and an ordered index struct SEQ {}; // Sequence struct TID {}; // TypeID typedef boost::multi_index::multi_index_container< HtvValueBasePtr, // element type boost::multi_index::indexed_by< boost::multi_index::sequenced< // list-like index boost::multi_index::tag<SEQ> >, // sequenced<> boost::multi_index::ordered_unique< // map-lik index boost::multi_index::tag<TID>, boost::multi_index::const_mem_fun< // key extractor HtvValueBase, // class name const HtvTypeBase::TypeID, // return type &HtvValueBase::getTypeId // const mem fun name > // const_mem_fun<> > // ordered_unique<> > // indexed_by<> > TLVListMapType; typedef TLVListMapType::index<SEQ>::type TLV_by_SEQ; typedef TLVListMapType::index<TID>::type TLV_by_TID; TLVListMapType mTLVs; //< indexed on both physical layout & TypeID. .... }; // class MyClass The program is running fine without problem; and I wanna use gdb to check its runtime status by printing out the object. Here's the gdb output when I print the object (I've manully indexed the gdb output & add '//' comment after closing-bracket '{' s.t. it's easier for the eyes): (gdb) p pMyClassObj->mTLVs $5 = { <boost::base_from_member<std::allocator<boost::multi_index::detail::sequenced_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<boost::shared_ptr<hipeer::HtvValueBase>
,0>> = { member = {
<__gnu_cxx::new_allocator<boost::multi_index::detail::sequenced_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<boost::shared_ptr<hipeer::HtvValueBase>
= { <No data fields> }, <No data fields> } },
<boost::multi_index::detail::header_holder<boost::multi_index::detail::sequenced_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<boost::shared_ptr<hipeer::HtvValueBase>
,boost::multi_index::multi_index_container<boost::shared_ptr<hipeer::HtvValueBase>, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<hipeer::HipPacket::SEQ, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::multi_index::ordered_unique<boost::multi_index::tag<hipeer::HipPacket::TID, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<boost::shared_ptr<hipeer::HtvValueBase> > > >> = {
<boost::base_from_member<boost::multi_index::detail::sequenced_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<boost::shared_ptr<hipeer::HtvValueBase>
*,0>> = { member = 0x85cf7a8 }, <boost::noncopyable_::noncopyable> = { <No data fields> }, <No data fields> }, // header_holder
<boost::multi_index::detail::sequenced_index<boost::multi_index::detail::nth_layer<1, boost::shared_ptr<hipeer::HtvValueBase>, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<hipeer::HipPacket::SEQ, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::multi_index::ordered_unique<boost::multi_index::tag<hipeer::HipPacket::TID, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<boost::shared_ptr<hipeer::HtvValueBase> >
,boost::mpl::v_item<hipeer::HipPacket::SEQ, boost::mpl::vector0<mpl_::na>, 0> >> = {
<boost::multi_index::detail::ordered_index<boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>,std::less<const hipeer::HtvTypeBase::TypeID>,boost::multi_index::detail::nth_layer<2, boost::shared_ptr<hipeer::HtvValueBase>, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<hipeer::HipPacket::SEQ, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::multi_index::ordered_unique<boost::multi_index::tag<hipeer::HipPacket::TID, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<boost::shared_ptr<hipeer::HtvValueBase> >
,boost::mpl::v_item<hipeer::HipPacket::TID, boost::mpl::vector0<mpl_::na>, 0>,boost::multi_index::detail::ordered_unique_tag>> = {
<boost::multi_index::detail::index_base<boost::shared_ptr<hipeer::HtvValueBase>,boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<hipeer::HipPacket::SEQ, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::multi_index::ordered_unique<boost::multi_index::tag<hipeer::HipPacket::TID, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, mpl_::na>, mpl_---Type <return> to continue, or q <return> to quit--- ::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>,std::allocator<boost::shared_ptr<hipeer::HtvValueBase> > >> = { <No data fields> }, // index_base <boost::multi_index::detail::safe_container<boost::multi_index::detail::ordered_index<boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, std::less<const hipeer::HtvTypeBase::TypeID>, boost::multi_index::detail::nth_layer<2, boost::shared_ptr<hipeer::HtvValueBase>, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<hipeer::HipPacket::SEQ, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::multi_index::ordered_unique<boost::multi_index::tag<hipeer::HipPacket::TID, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<boost::shared_ptr<hipeer::HtvValueBase> > >, boost::mpl::v_item<hipeer::HipPacket::TID, boost::mpl::vector0<mpl_::na>, 0>, boost::multi_index::detail::ordered_unique_tag> >> = { <boost::multi_index::detail::safe_container_base> = { <boost::noncopyable_::noncopyable> = { <No data fields> }, header = { cont = 0x0, next = 0x0, unchecked_ = false }, mutex = { m_ = { __m_reserved = 0, __m_count = 0, __m_owner = 0x0, __m_kind = 0, __m_lock = { __status = 0, __spinlock = 0 } } } }, <No data fields> }, // safe_container (for ordered_index?) key = { <No data fields> }, comp = { <> = { <No data fields> }, <No data fields> } }, // ordered_index <boost::multi_index::detail::safe_container<boost::multi_index::detail::sequenced_index<boost::multi_index::detail::nth_layer<1, boost::shared_ptr<hipeer::HtvValueBase>, boost::multi_index::indexed_by<boost::multi_index::sequenced<boost::multi_index::tag<hipeer::HipPacket::SEQ, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::multi_index::ordered_unique<boost::multi_index::tag<hipeer::HipPacket::TID, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::const_mem_fun<hipeer::HtvValueBase, const hipeer::HtvTypeBase::TypeID, &hipeer::HtvValueBase::getTypeId>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<boost::shared_ptr<hipeer::HtvValueBase> > >, boost::mpl::v_item<hipeer::HipPacket::SEQ, boost::mpl::vector0<mpl_::na>, 0>
= { <boost::multi_index::detail::safe_container_base> = { <boost::noncopyable_::noncopyable> = { <No data fields> }, header = { cont = 0x0, next = 0x0, unchecked_ = false }, mutex = { m_ = { __m_reserved = 0, __m_count = 0, __m_owner = 0x0, __m_kind = 0, __m_lock = { __status = 0, __spinlock = 0 } } } }, <No data fields> }, // safe_container (for sequenced_index?) <No data fields> }, // sequenced_index
node_count = 3 } // $5... (gdb) p pMyClassObj->mTLVs.header $12 = {cont = 0x0, next = 0x0, unchecked_ = false} (gdb) p pMyClassObj->mTLVs.member $13 = {<__gnu_cxx::new_allocator<boost::multi_index::detail::sequenced_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<boost::shared_ptr<hipeer::HtvValueBase>
= {<No data fields>}, <No data fields>} (gdb) p rqInbPkt.px->mTLVs.node_count $14 = 3
According to the 'node_count', there're 3 objects stored in the multi_index_container of '*pMyClassObj'. But I couldn't find a way to traverse all 3 objects in gdb: I see there're two 'member' data fields inside MyClass container, the first one doesn't contain any data, while the second one (at address 0x85cf7a8 inside the header_holder class???) seems to be the right place to start traversing... but I don't know if there's any convenient way to traverse it at the symbolic level via container's data members. Any hint? Thanks, --- Jeffrey

Hi Jeffrey ----- Mensaje original ----- De: Jeffrey Chang <jeffrey8chang@gmail.com> Fecha: Martes, Mayo 1, 2007 7:03 pm Asunto: [Boost-users] [boost-users] [multi_index] print object data member in gdb Para: boost-users@lists.boost.org CC: jeffrey8chang@gmail.com
Hi,
I've been compiling & using multi_index without problem for a while; but when I use gdb to print multi_index_container objects, I couldn't find a way to easily traverse through its internal data structure.
Here' s my multi_index_container object declaration: [...] The program is running fine without problem; and I wanna use gdb to check its runtime status by printing out the object. Here's the gdb output when I print the object (I've manully indexed the gdb output & add '//' commentafter closing-bracket '{' s.t. it's easier for the eyes):
(gdb) p pMyClassObj->mTLVs $5 = [...] According to the 'node_count', there're 3 objects stored in the multi_index_container of '*pMyClassObj'. But I couldn't find a way to traverse all 3 objects in gdb: I see there're two 'member' data fieldsinside MyClass container, the first one doesn't contain any data, while the second one (at address 0x85cf7a8 inside the header_holder class???) seems to be the right place to start traversing... but I don't know if there's any convenient way to traverse it at the symbolic level via container's data members. Any hint?
As you correctly guess, the member at header_holder_class is where you have to look at in order to reach for the elements. This member is of type (in your particular case) boost::base_from_member< boost::multi_index::detail::sequenced_index_node< boost::multi_index::detail::ordered_index_node< boost::multi_index::detail::index_node_base< HtvValueBasePtr > > >*, 0
The base_from_member base class in turn contains a member of type pointer to boost::multi_index::detail::sequenced_index_node< boost::multi_index::detail::ordered_index_node< boost::multi_index::detail::index_node_base< HtvValueBasePtr > >
which is a pointer to the "header" of the container, from where you can jump to the elements. This class contains the element values proper (inside index_node_base<...>) as well as linking stuff for each of the indices the multi-index container is comprised of. sequenced_index_node<...> multiply inherits from ordered_index_node<...> and from a class sequenced_index_node_trampoline<...>, which in turn inherits from sequenced_index_node_impl, which has members called prior_ and next_. Since the header is conceptually the end node of the container, just follow the prior_ pointers to traverse all the elements. You could also do the traversal following the pointers in ordered_index_node<...>, but this is a little more complicated since the data structure implemented by this is an rb tree. Hope this helps, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
"JOAQUIN LOPEZ MU?Z"
-
Jeffrey Chang