《coredump问题原理探究》Linux x86版7.9节list相关的iterator对象

这一节,看一下list的iterator对象在内存的布局

1 #include <list>
  2
  3 void init( std::list<int>& lst )
  4 {
  5     for ( int i = 0; i < 0x10; i++ )
  6     {
  7         lst.push_back( i );
  8     }
  9 }
 10
 11 int getSum( std::list<int>& lst )
 12 {
 13     std::list<int>::iterator iter;
 14     int result = 0;
 15
 16     for ( iter = lst.begin(); iter != lst.end(); iter++ )
 17     {
 18         result += *iter;
 19     }
 20
 21     return result;
 22 }
 23
 24 int main()
 25 {
 26     std::list<int> lst;
 27     init( lst );
 28
 29     return getSum( lst );
 30 }

看getSum函数的汇编:

(gdb) disassemble getSum
Dump of assembler code for function _Z6getSumRSt4listIiSaIiEE:
   0x080486cd <+0>:	push   %ebp
   0x080486ce <+1>:	mov    %esp,%ebp
   0x080486d0 <+3>:	sub    $0x38,%esp
   0x080486d3 <+6>:	lea    -0x18(%ebp),%eax
   0x080486d6 <+9>:	mov    %eax,(%esp)
   0x080486d9 <+12>:	call   0x8048816 <_ZNSt14_List_iteratorIiEC2Ev>
   0x080486de <+17>:	movl   $0x0,-0xc(%ebp)
   0x080486e5 <+24>:	lea    -0x1c(%ebp),%eax
   0x080486e8 <+27>:	mov    0x8(%ebp),%edx
   0x080486eb <+30>:	mov    %edx,0x4(%esp)
   0x080486ef <+34>:	mov    %eax,(%esp)
   0x080486f2 <+37>:	call   0x8048824 <_ZNSt4listIiSaIiEE5beginEv>
   0x080486f7 <+42>:	sub    $0x4,%esp
   0x080486fa <+45>:	mov    -0x1c(%ebp),%eax
   0x080486fd <+48>:	mov    %eax,-0x18(%ebp)
   0x08048700 <+51>:	jmp    0x804872f <_Z6getSumRSt4listIiSaIiEE+98>
   0x08048702 <+53>:	lea    -0x18(%ebp),%eax
   0x08048705 <+56>:	mov    %eax,(%esp)
   0x08048708 <+59>:	call   0x80488ba <_ZNKSt14_List_iteratorIiEdeEv>
   0x0804870d <+64>:	mov    (%eax),%eax
   0x0804870f <+66>:	add    %eax,-0xc(%ebp)
   0x08048712 <+69>:	lea    -0x10(%ebp),%eax
   0x08048715 <+72>:	movl   $0x0,0x8(%esp)
   0x0804871d <+80>:	lea    -0x18(%ebp),%edx
   0x08048720 <+83>:	mov    %edx,0x4(%esp)
   0x08048724 <+87>:	mov    %eax,(%esp)
   0x08048727 <+90>:	call   0x8048882 <_ZNSt14_List_iteratorIiEppEi>
   0x0804872c <+95>:	sub    $0x4,%esp
   0x0804872f <+98>:	lea    -0x14(%ebp),%eax
   0x08048732 <+101>:	mov    0x8(%ebp),%edx
   0x08048735 <+104>:	mov    %edx,0x4(%esp)
   0x08048739 <+108>:	mov    %eax,(%esp)
   0x0804873c <+111>:	call   0x804884a <_ZNSt4listIiSaIiEE3endEv>
   0x08048741 <+116>:	sub    $0x4,%esp
   0x08048744 <+119>:	lea    -0x14(%ebp),%eax
   0x08048747 <+122>:	mov    %eax,0x4(%esp)
   0x0804874b <+126>:	lea    -0x18(%ebp),%eax
   0x0804874e <+129>:	mov    %eax,(%esp)
   0x08048751 <+132>:	call   0x804886e <_ZNKSt14_List_iteratorIiEneERKS0_>
   0x08048756 <+137>:	test   %al,%al
   0x08048758 <+139>:	jne    0x8048702 <_Z6getSumRSt4listIiSaIiEE+53>
   0x0804875a <+141>:	mov    -0xc(%ebp),%eax
   0x0804875d <+144>:	leave
   0x0804875e <+145>:	ret
End of assembler dump.

可以看到list的this指针在ebp+0x8,iter的this指针在ebp-0x18.

在0x0804874b指令地址打断点.

看一下list的内容:

(gdb) x $ebp+0x8
0xbffff5a0:	0xbffff5b8
(gdb) x /8x 0xbffff5b8
0xbffff5b8:	0x0804b008	0x0804b0f8	0x08048c60	0x080485e0
0xbffff5c8:	0x002edff4	0x00000000	0x08048c60	0x00000000
(gdb) x /4x 0x0804b008
0x804b008:	0x0804b018	0xbffff5b8	0x00000000	0x00000011
(gdb) x /4x 0x0804b018
0x804b018:	0x0804b028	0x0804b008	0x00000001	0x00000011
(gdb) x /4x 0x0804b028
0x804b028:	0x0804b038	0x0804b018	0x00000002	0x00000011
(gdb) x /4x 0x0804b038
0x804b038:	0x0804b048	0x0804b028	0x00000003	0x00000011
(gdb) x /4x 0x0804b048
0x804b048:	0x0804b058	0x0804b038	0x00000004	0x00000011
(gdb) x /4x 0x0804b058
0x804b058:	0x0804b068	0x0804b048	0x00000005	0x00000011
(gdb) x /4x 0x0804b0f8
0x804b0f8:	0xbffff5b8	0x0804b0e8	0x0000000f	0x00020f01
(gdb) x /4x 0x0804b0e8
0x804b0e8:	0x0804b0f8	0x0804b0d8	0x0000000e	0x00000011
(gdb) x /4x 0x0804b0d8
0x804b0d8:	0x0804b0e8	0x0804b0c8	0x0000000d	0x00000011

看一下iter的内容变化:

Breakpoint 1, 0x0804874b in getSum(std::list<int, std::allocator<int> >&) ()
(gdb) x /4x $ebp-0x18
0xbffff580:	0x0804b018	0xbffff5b8	0x0804b008	0x00000000
(gdb) c
Continuing.

Breakpoint 1, 0x0804874b in getSum(std::list<int, std::allocator<int> >&) ()
(gdb) x /4x $ebp-0x18
0xbffff580:	0x0804b028	0xbffff5b8	0x0804b018	0x00000001
(gdb) c
Continuing.

Breakpoint 1, 0x0804874b in getSum(std::list<int, std::allocator<int> >&) ()
(gdb) x /4x $ebp-0x18
0xbffff580:	0x0804b038	0xbffff5b8	0x0804b028	0x00000003
(gdb) c
Continuing.

Breakpoint 1, 0x0804874b in getSum(std::list<int, std::allocator<int> >&) ()
(gdb) x /4x $ebp-0x18
0xbffff580:	0x0804b048	0xbffff5b8	0x0804b038	0x00000006

可以得到list的iterator也只有一个成员_M_node,指向list每个节点(头节点除外).

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 02:53:30

《coredump问题原理探究》Linux x86版7.9节list相关的iterator对象的相关文章

《coredump问题原理探究》Linux x86版7.8节vector相关的iterator对象

在前面看过了一个vectorcoredump的例子,接触了vector的iterator,可以知道vector的iterator只有一个成员_M_current指向vector某一个元素. 先看一个例子: 1 #include <vector> 2 3 void init( std::vector<int>& vec ) 4 { 5 for ( int i = 0; i < 0x10; i++ ) 6 { 7 vec.push_back( i ); 8 } 9 } 1

《coredump问题原理探究》Windows版 笔记

<coredump问题原理探究>Windows版 笔记 Debug 一.环境搭建 1.Win7捕获程序dump 2.Windbg符号表设置(Symbols Search Path) 二.WinDbg命令 三.函数栈帧 1.栈内存布局 2.栈溢出 3.栈的规律 4.定位栈溢出问题的经验方法 四.函数逆向 五.C内存布局 1.基本类型 2.数组类型 3.结构体 六.C++内存布局 1.类的内存布局 2.this指针 3.虚函数表及虚表指针 4.单继承 5.多继承(无公共基类) 七.STL容器内存布

《coredump问题原理探究》Linux x86版6.3节有成员变量的类coredump例子

在探究完类成员变量分布后,来定位一个coredump例子来实践一把: (gdb) bt #0 0x0804863c in xuzhina_dump_c06_s2_ex::print() () #1 0x08048713 in main () 看一下xuzhina_dump_c06_s2_ex::print的汇编: (gdb) disassemble 0x0804863c Dump of assembler code for function _ZN22xuzhina_dump_c06_s2_ex

《coredump问题原理探究》Linux x86版7.2节vector coredump例子

看一个coredump的例子: [[email protected] s1_ex]$ gdb xuzhina_dump_c07_s1_ex core.27776 GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses

《coredump问题原理探究》Linux x86版6.2节C++风格数据结构内存布局之有成员变量的类

上面一节已经探究出this指针的辨别,由this指针就可以看到类的内容.在这里,就由this指针来看一下类的成员变量是如何排列. 先看一个例子 1 #include <stdio.h> 2 class xuzhina_dump_c06_s2 3 { 4 private: 5 short m_c; 6 char m_d; 7 int m_e; 8 9 public: 10 xuzhina_dump_c06_s2( int a, int b ) 11 { 12 m_c = (short)(a +

《coredump问题原理探究》Linux x86版7.5节 Map对象

先看一个例子: 1 #include <map> 2 3 int main() 4 { 5 std::map<int,int> iMap; 6 7 iMap[5] = 6; 8 iMap[8] = 20; 9 iMap[2] = 80; 10 11 return 0; 12 } 看一下汇编: (gdb) disassemble main Dump of assembler code for function main: 0x080486e4 <+0>: push %eb

《coredump问题原理探究》Linux x86版6.8节多继承coredump例子

下面看一个coredump的例子: (gdb) bt #0 0x08048662 in xuzhina_dump_c06_s5_ex_child::inheritFrom(char*, int) () #1 0x08048609 in main () 先看一下xuzhina_dump_c06_s5_ex_child::inheritFrom的汇编: (gdb) disassemble 0x08048662 Dump of assembler code for function _ZN28xuzh

《coredump问题原理探究》Linux x86版6.1节C++风格数据结构内存布局之无成员变量的类

在探究完C风格数据结构内存布局之后,接着探究C++风格数据结构内存布局. 虽然最简单的类是没有任何成员变量和成员函数,但由于没什么意义,不值得探究.在这里,就先探究一下没有任何成员变量和虚函数,只有成员函数的类. 先看一下例子: 1 #include <stdio.h> 2 class xuzhina_dump_c06_s1 3 { 4 public: 5 void hello() 6 { 7 printf( "hello\n" ); 8 } 9 void print()

《coredump问题原理探究》Linux x86版7.4节List coredump例子

看一个coredump例子: 看一个coredump例子: Core was generated by `./xuzhina_dump_c07_s2_ex'. Program terminated with signal 11, Segmentation fault. #0 0x0285b9b7 in std::_List_node_base::hook(std::_List_node_base*) () from /usr/lib/libstdc++.so.6 Missing separate