我想看看使用gdb的boost::multi_index(版本1.67.0)所包含的数据。
首先我试过
https://github.com/ruediger/Boost-Pretty-Printer
.
似乎哈希索引如
hashed_unique
不支持。
我注意到如果第一个索引是支持的类型,比如
sequenced
,Boost Pretty Printer工作正常。
但是,我现在无法编辑代码。我需要调试一个核心文件和一个二进制可执行文件。
我尝试用散列索引来理解多个索引的内部结构。
我编写了以下测试代码:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
namespace mi = boost::multi_index;
struct t_hash{};
using elems = mi::multi_index_container<
int,
mi::indexed_by<
mi::hashed_unique<
mi::tag<t_hash>,
mi::identity<int>
>
>
>;
int main() {
elems es { 0x12, 0x34 };
return 0; // set break point here and (gdb) p es
}
https://wandbox.org/permlink/UtMfVRI4rT5AXUOZ
当我打印es时,
(gdb) p es
我得到了以下输出:
$1 = {
<boost::base_from_member<std::allocator<boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<int, std::allocator<int> >, boost::multi_index::detail::hashed_unique_tag> >, 0>> = {
member = {
<__gnu_cxx::new_allocator<boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<int, std::allocator<int> >, boost::multi_index::detail::hashed_unique_tag> >> = {<No data fields>}, <No data fields>}
},
<boost::multi_index::detail::header_holder<boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<int, std::allocator<int> >, boost::multi_index::detail::hashed_unique_tag>*, boost::multi_index::multi_index_container<int, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<t_hash, 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::identity<int>, 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, mpl_::na, mpl_::na>, std::allocator<int> > >> = {
<boost::noncopyable_::noncopyable> = {<No data fields>},
members of boost::multi_index::detail::header_holder<boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<int, std::allocator<int> >, boost::multi_index::detail::hashed_unique_tag>*, boost::multi_index::multi_index_container<int, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<t_hash, 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::identity<int>, 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, mpl_::na, mpl_::na>, std::allocator<int> > >:
member = 0x55555576ee70
},
<boost::multi_index::detail::hashed_index<boost::multi_index::identity<int>, boost::hash<int>, std::equal_to<int>, boost::multi_index::detail::nth_layer<1, int, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<t_hash, 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::identity<int>, 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, mpl_::na, mpl_::na>, std::allocator<int> >, boost::mpl::v_item<t_hash, boost::mpl::vector0<mpl_::na>, 0>, boost::multi_index::detail::hashed_unique_tag>> = {
<boost::multi_index::detail::index_base<int, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<t_hash, 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::identity<int>, 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, mpl_::na, mpl_::na>, std::allocator<int> >> = {<No data fields>},
members of boost::multi_index::detail::hashed_index<boost::multi_index::identity<int>, boost::hash<int>, std::equal_to<int>, boost::multi_index::detail::nth_layer<1, int, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<t_hash, 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::identity<int>, 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, mpl_::na, mpl_::na>, std::allocator<int> >, boost::mpl::v_item<t_hash, boost::mpl::vector0<mpl_::na>, 0>, boost::multi_index::detail::hashed_unique_tag>:
key = {
<boost::multi_index::detail::non_const_identity_base<int>> = {<No data fields>}, <No data fields>},
hash_ = {
<boost::hash_detail::hash_base<int>> = {
<std::unary_function<int, unsigned long>> = {<No data fields>}, <No data fields>}, <No data fields>},
eq_ = {
<std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>},
buckets = {
<boost::multi_index::detail::bucket_array_base<true>> = {
<boost::noncopyable_::noncopyable> = {<No data fields>},
},
members of boost::multi_index::detail::bucket_array<std::allocator<int> >:
size_index_ = 0,
spc = {
<boost::noncopyable_::noncopyable> = {<No data fields>},
members of boost::multi_index::detail::auto_space<boost::multi_index::detail::hashed_index_base_node_impl<std::allocator<char> >, std::allocator<int> >:
al_ = {
<__gnu_cxx::new_allocator<boost::multi_index::detail::hashed_index_base_node_impl<std::allocator<char> > >> = {<No data fields>}, <No data fields>},
n_ = 54,
data_ = 0x55555576ee90
}
},
mlf = 1,
max_load = 53
},
members of boost::multi_index::multi_index_container<int, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<t_hash, 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::identity<int>, 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, mpl_::na, mpl_::na>, std::allocator<int> >:
node_count = 2
}
我发现
node_count = 2
. 似乎元素的数量。我试着挖掘成员变量。例如)
member
,
buckets
等等。但我找不到数据
0x12
和
0x34
,到目前为止。
我怎么才能拿到?
编辑:2018/07/28 11:51 JST
谢谢你的评论,我找到了解决办法。我根据评论总结了两种方法。
基于@sehe方法的运行时共享库加载,
-
编写调试打印函数(
debug_print()
)作为共享库(
dp.so
).
-
运行gdb。
gdb target_executable_file
-
做
set environment LD_PRELOAD ./dp.so
.
-
设置断点。
-
做
r
-
当断点命中时,执行
call debug_print(data)
.
data
是你想看到的目标。
这种方法不需要重新编译目标。但是,当我加载核心文件时,
调试打印()
已经不在记忆里了。所以这种方法不适用于核心文件。
我在找强制装载
副总裁
在核心文件加载后,但到目前为止我找不到路。
用gdb跟踪多个索引的内部结构
这种方法是使用核心文件的。
这种方法基于@joaqÃn M LÃ3 pez MuÃ?oz的评论。
-
用核心文件运行gdb。
gdb target_executable_file core_file
.
-
执行以下命令访问数据。
T
是多个索引的元素类型。
数据
是多索引容器变量。
N
是索引数。
第一个数据
p *(T*)((char*)(*data.member).prior_ - sizeof(T) - 0x10 * (N - 1))
第二数据
p *(T*)((char*)(*(*data.member).prior_).prior_ - sizeof(T) - 0x10 * (N - 1))
……遵循同样的模式。
非常感谢您@sele和@joaqÃn M LÃ3 pez MuÃ?oz!!
编辑:2018/07/28 15:22 JST
我实现了对Boost Pretty打印机的散列索引支持。它基于上述方法。
我发送了请求:
https://github.com/ruediger/Boost-Pretty-Printer/pull/36
编辑:2018/07/28 15:42 JST
我明白了0x10的意思。它是指针大小乘以2。所以在64位环境中,64位=8字节,8*2=16=0x10。
在32位环境中,32位=4字节,4*2=8=0x08。
我还更新了拉取请求。
编辑:2018/08/02 09:30 JST
最后,我发送了两个请求,两个请求都被合并。现在,我们可以简单地使用Boost Pretty Printer,并打印将哈希索引作为第一个索引的多索引容器。
https://github.com/ruediger/Boost-Pretty-Printer/pull/36
https://github.com/ruediger/Boost-Pretty-Printer/pull/37
下面是内部结构和迭代算法:
https://speakerdeck.com/redboltz/boost-multi-index-version-equals-1-dot-56-dot-0-internal-structure-and-iteration-algorithm-for-gdb-boost-prerry-printer