《coredump问题原理探究》Linux x86版7.7节 set对象

来源:互联网 发布:淘宝店招设计教程 编辑:程序博客网 时间:2024/04/29 22:52

看一下bits/stl_map和bits/stl_set可以看到map和set的定义如下:


84   template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>, 85             typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 86     class map 87     { 88     public: 89       typedef _Key                                          key_type; 90       typedef _Tp                                           mapped_type; 91       typedef std::pair<const _Key, _Tp>                    value_type; 92       typedef _Compare                                      key_compare; 93       typedef _Alloc                                        allocator_type; 94  95     private: 96       // concept requirements 97       typedef typename _Alloc::value_type                   _Alloc_value_type; 98       __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 99       __glibcxx_class_requires4(_Compare, bool, _Key, _Key,100                 _BinaryFunctionConcept)101       __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)102 103     public:104       class value_compare105       : public std::binary_function<value_type, value_type, bool>106       {107     friend class map<_Key, _Tp, _Compare, _Alloc>;108       protected:109     _Compare comp;110 111     value_compare(_Compare __c)112     : comp(__c) { }113 114       public:115     bool operator()(const value_type& __x, const value_type& __y) const116     { return comp(__x.first, __y.first); }117       };118 119     private:120       /// This turns a red-black tree into a [multi]map. 121       typedef typename _Alloc::template rebind<value_type>::other122         _Pair_alloc_type;123 124       typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,125                key_compare, _Pair_alloc_type> _Rep_type;126 127       /// The actual tree structure.128       _Rep_type _M_t;

85   template<typename _Key, typename _Compare = std::less<_Key>, 86        typename _Alloc = std::allocator<_Key> > 87     class set 88     { 89       // concept requirements 90       typedef typename _Alloc::value_type                   _Alloc_value_type; 91       __glibcxx_class_requires(_Key, _SGIAssignableConcept) 92       __glibcxx_class_requires4(_Compare, bool, _Key, _Key, 93                 _BinaryFunctionConcept) 94       __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) 95  96     public: 97       // typedefs: 98       //@{ 99       /// Public typedefs.100       typedef _Key     key_type;101       typedef _Key     value_type;102       typedef _Compare key_compare;103       typedef _Compare value_compare;104       typedef _Alloc   allocator_type;105       //@}106 107     private:108       typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;109 110       typedef _Rb_tree<key_type, value_type, _Identity<value_type>,111                key_compare, _Key_alloc_type> _Rep_type;112       _Rep_type _M_t;  // Red-black tree representing set.113

由于map,set的本身定义都是声明任何成员变量,所有成员变量都是从_Rb_tree继承过来的,唯一的差别只是_Rb_tree最后参数的定义不一样.

set的特征如下:

1.     set对象有五个成员_M_node_count标明map有多少个元素,三个指针分别指向树中最左的节点,树的根节点,树的最右节点,_M_color表明是红树还是黑树,_M_key_compare指向比较函数

2.     树的根节点的_M_parent指向头节点

3.     每一个节点的值都紧跟着_M_right

 

看一下例子:

  1 #include <set>  2   3 int main()  4 {  5     std::set<int> iSet;  6     iSet.insert( 0x523 );  7     iSet.insert( 0x352 );  8     iSet.insert( 0x808 );  9  10     return 0; 11 }

看一下main函数的汇编:

(gdb) disassemble mainDump of assembler code for function main:   0x08048634 <+0>:lea    0x4(%esp),%ecx   0x08048638 <+4>:and    $0xfffffff0,%esp   0x0804863b <+7>:pushl  -0x4(%ecx)   0x0804863e <+10>:push   %ebp   0x0804863f <+11>:mov    %esp,%ebp   0x08048641 <+13>:push   %esi   0x08048642 <+14>:push   %ebx   0x08048643 <+15>:push   %ecx   0x08048644 <+16>:sub    $0x5c,%esp   0x08048647 <+19>:lea    -0x54(%ebp),%eax   0x0804864a <+22>:mov    %eax,(%esp)   0x0804864d <+25>:call   0x8048712 <_ZNSt3setIiSt4lessIiESaIiEEC2Ev>   0x08048652 <+30>:movl   $0x523,-0x34(%ebp)   0x08048659 <+37>:lea    -0x3c(%ebp),%eax   0x0804865c <+40>:lea    -0x34(%ebp),%edx   0x0804865f <+43>:mov    %edx,0x8(%esp)   0x08048663 <+47>:lea    -0x54(%ebp),%edx   0x08048666 <+50>:mov    %edx,0x4(%esp)   0x0804866a <+54>:mov    %eax,(%esp)   0x0804866d <+57>:call   0x804878c <_ZNSt3setIiSt4lessIiESaIiEE6insertERKi>   0x08048672 <+62>:sub    $0x4,%esp   0x08048675 <+65>:movl   $0x352,-0x28(%ebp)   0x0804867c <+72>:lea    -0x30(%ebp),%eax---Type <return> to continue, or q <return> to quit---   0x0804867f <+75>:lea    -0x28(%ebp),%edx   0x08048682 <+78>:mov    %edx,0x8(%esp)   0x08048686 <+82>:lea    -0x54(%ebp),%edx   0x08048689 <+85>:mov    %edx,0x4(%esp)   0x0804868d <+89>:mov    %eax,(%esp)   0x08048690 <+92>:call   0x804878c <_ZNSt3setIiSt4lessIiESaIiEE6insertERKi>   0x08048695 <+97>:sub    $0x4,%esp   0x08048698 <+100>:movl   $0x808,-0x1c(%ebp)   0x0804869f <+107>:lea    -0x24(%ebp),%eax   0x080486a2 <+110>:lea    -0x1c(%ebp),%edx   0x080486a5 <+113>:mov    %edx,0x8(%esp)   0x080486a9 <+117>:lea    -0x54(%ebp),%edx   0x080486ac <+120>:mov    %edx,0x4(%esp)   0x080486b0 <+124>:mov    %eax,(%esp)   0x080486b3 <+127>:call   0x804878c <_ZNSt3setIiSt4lessIiESaIiEE6insertERKi>   0x080486b8 <+132>:sub    $0x4,%esp   0x080486bb <+135>:mov    $0x0,%ebx   0x080486c0 <+140>:lea    -0x54(%ebp),%eax   0x080486c3 <+143>:mov    %eax,(%esp)   0x080486c6 <+146>:call   0x80486fe <_ZNSt3setIiSt4lessIiESaIiEED2Ev>   0x080486cb <+151>:mov    %ebx,%eax   0x080486cd <+153>:lea    -0xc(%ebp),%esp   0x080486d0 <+156>:add    $0x0,%esp---Type <return> to continue, or q <return> to quit---   0x080486d3 <+159>:pop    %ecx   0x080486d4 <+160>:pop    %ebx   0x080486d5 <+161>:pop    %esi   0x080486d6 <+162>:pop    %ebp   0x080486d7 <+163>:lea    -0x4(%ecx),%esp   0x080486da <+166>:ret       0x080486db <+167>:mov    %edx,%ebx   0x080486dd <+169>:mov    %eax,%esi   0x080486df <+171>:lea    -0x54(%ebp),%eax   0x080486e2 <+174>:mov    %eax,(%esp)   0x080486e5 <+177>:call   0x80486fe <_ZNSt3setIiSt4lessIiESaIiEED2Ev>   0x080486ea <+182>:mov    %esi,%eax   0x080486ec <+184>:mov    %ebx,%edx   0x080486ee <+186>:mov    %eax,(%esp)   0x080486f1 <+189>:call   0x8048564 <_Unwind_Resume@plt>End of assembler dump.

由上面汇编可知,ebp-0x54是set的this指针.

在0x080486b8指令地址打断点,验证一下set的特征是不是对的.

(gdb) x /8wx $ebp-0x540xbffff234:0xbffff2700x000000000x0804b0080x0804b0200xbffff244:0x0804b0380x000000030x0804b0080xbffff201(gdb) x /8wx 0x0804b0080x804b008:0x000000010xbffff2380x0804b0200x0804b0380x804b018:0x000005230x000000190x000000000x0804b008(gdb) x /8x 0x0804b0200x804b020:0x000000000x0804b0080x000000000x000000000x804b030:0x000003520x000000190x000000000x0804b008(gdb) x /8wx 0x0804b0380x804b038:0x000000000x0804b0080x000000000x000000000x804b048:0x000008080x00020fb90x000000000x00000000

可用下图表示:

可知,特征是没有问题


0 0
原创粉丝点击