《coredump问题原理探究》Linux x86版7.3节List对象

来源:互联网 发布:网络电视腾讯课堂 编辑:程序博客网 时间:2024/03/29 04:23

先看一下例子:

1 #include <list>  2   3 int main()  4 {  5     std::list<int> lst;  6   7     lst.push_back( 0x12345678 );  8     lst.push_front( 0xabcdef01 );  9     lst.push_back( 0x24242522 ); 10  11     return 0; 12 }

再看一下汇编:

(gdb) disassemble mainDump of assembler code for function main:   0x080485b4 <+0>:push   %ebp   0x080485b5 <+1>:mov    %esp,%ebp   0x080485b7 <+3>:and    $0xfffffff0,%esp   0x080485ba <+6>:push   %esi   0x080485bb <+7>:push   %ebx   0x080485bc <+8>:sub    $0x38,%esp   0x080485bf <+11>:lea    0x1c(%esp),%eax   0x080485c3 <+15>:mov    %eax,(%esp)   0x080485c6 <+18>:call   0x8048674 <_ZNSt4listIiSaIiEEC2Ev>   0x080485cb <+23>:movl   $0x12345678,0x24(%esp)   0x080485d3 <+31>:lea    0x24(%esp),%eax   0x080485d7 <+35>:mov    %eax,0x4(%esp)   0x080485db <+39>:lea    0x1c(%esp),%eax   0x080485df <+43>:mov    %eax,(%esp)   0x080485e2 <+46>:call   0x80486de <_ZNSt4listIiSaIiEE9push_backERKi>   0x080485e7 <+51>:movl   $0xabcdef01,0x28(%esp)   0x080485ef <+59>:lea    0x28(%esp),%eax   0x080485f3 <+63>:mov    %eax,0x4(%esp)   0x080485f7 <+67>:lea    0x1c(%esp),%eax   0x080485fb <+71>:mov    %eax,(%esp)   0x080485fe <+74>:call   0x8048714 <_ZNSt4listIiSaIiEE10push_frontERKi>   0x08048603 <+79>:movl   $0x24242522,0x2c(%esp)   0x0804860b <+87>:lea    0x2c(%esp),%eax   0x0804860f <+91>:mov    %eax,0x4(%esp)---Type <return> to continue, or q <return> to quit---   0x08048613 <+95>:lea    0x1c(%esp),%eax   0x08048617 <+99>:mov    %eax,(%esp)   0x0804861a <+102>:call   0x80486de <_ZNSt4listIiSaIiEE9push_backERKi>   0x0804861f <+107>:mov    $0x0,%ebx   0x08048624 <+112>:lea    0x1c(%esp),%eax   0x08048628 <+116>:mov    %eax,(%esp)   0x0804862b <+119>:call   0x8048660 <_ZNSt4listIiSaIiEED2Ev>   0x08048630 <+124>:mov    %ebx,%eax   0x08048632 <+126>:add    $0x38,%esp   0x08048635 <+129>:pop    %ebx   0x08048636 <+130>:pop    %esi   0x08048637 <+131>:mov    %ebp,%esp   0x08048639 <+133>:pop    %ebp   0x0804863a <+134>:ret       0x0804863b <+135>:mov    %edx,%ebx   0x0804863d <+137>:mov    %eax,%esi   0x0804863f <+139>:lea    0x1c(%esp),%eax   0x08048643 <+143>:mov    %eax,(%esp)   0x08048646 <+146>:call   0x8048660 <_ZNSt4listIiSaIiEED2Ev>   0x0804864b <+151>:mov    %esi,%eax   0x0804864d <+153>:mov    %ebx,%edx   0x0804864f <+155>:mov    %eax,(%esp)   0x08048652 <+158>:call   0x80484e8 <_Unwind_Resume@plt>End of assembler dump.

由0x080485c6附近的汇编来看,this指针放在esp+0x1c

在0x080485c6, 0x080485e2,0x080485fe, 0x0804861a, 0x0804862b打断点

(gdb) b *0x080485c6Breakpoint 1 at 0x80485c6(gdb) b *0x080485e2Breakpoint 2 at 0x80485e2(gdb) b *0x080485feBreakpoint 3 at 0x80485fe(gdb) b *0x0804861aBreakpoint 4 at 0x804861a(gdb) b *0x0804862bBreakpoint 5 at 0x804862b

先看一下list运行构造函数后会怎样.

Breakpoint 1, 0x080485c6 in main ()(gdb) x /8x $esp+0x1c0xbffff24c:0x08048aa90x028ea5500x0804832e0x000000000xbffff25c:0x009faff40x08048a900x080485000x009faff4(gdb) ni0x080485cb in main ()(gdb) x /8x $esp+0x1c0xbffff24c:0xbffff24c0xbffff24c0x0804832e0x000000000xbffff25c:0x009faff40x08048a900x080485000x009faff4

可以看出list对象有两个成员, 且这两个成员的值均指向自身。可见,这两个成员是指针。

再看一下第一个push_back后

Breakpoint 2, 0x080485e2 in main ()(gdb) x /8x $esp+0x1c0xbffff24c:0xbffff24c0xbffff24c0x123456780x000000000xbffff25c:0x009faff40x08048a900x080485000x009faff4(gdb) ni0x080485e7 in main ()(gdb) x /8x $esp+0x1c0xbffff24c:0x0804b0080x0804b0080x123456780x000000000xbffff25c:0x009faff40x08048a900x080485000x009faff4(gdb) x /8x 0x0804b0080x804b008:0xbffff24c0xbffff24c0x123456780x00020ff10x804b018:0x000000000x000000000x000000000x00000000

用结构表示如下:

再看一下push_front

Breakpoint 3, 0x080485fe in main ()(gdb) x /8x $esp+0x1c0xbffff24c:0x0804b0080x0804b0080x123456780xabcdef010xbffff25c:0x009faff40x08048a900x080485000x009faff4(gdb) x /8x 0x0804b0080x804b008:0xbffff24c0xbffff24c0x123456780x00020ff10x804b018:0x000000000x000000000x000000000x00000000(gdb) ni0x08048603 in main ()(gdb) x /8x $esp+0x1c0xbffff24c:0x0804b0180x0804b0080x123456780xabcdef010xbffff25c:0x009faff40x08048a900x080485000x009faff4(gdb) x /8x 0x0804b0180x804b018:0x0804b0080xbffff24c0xabcdef010x00020fe10x804b028:0x000000000x000000000x000000000x00000000(gdb) x /8x 0x0804b0080x804b008:0xbffff24c0x0804b0180x123456780x000000110x804b018:0x0804b0080xbffff24c0xabcdef010x00020fe1

用图形来表示就如下(只表示第一个成员).

如果考察这三个地址的第二个成员,就会变成这样的图形

同样考察第二个push_back,并参照list的代码,会得到这样的结论.

1.     list有两个成员,第一个成员指向链表的头部,第二个成员指向链表的尾部

2.     链表的每一个节点都有三个元素,第一个_M_next,指向下一个节点.第二个_M_prev指向前一个节点.第三个_M_data存储节点的值.

3.     list所指向的链表每一个节点的_M_next, _M_prev指针应该都不为空的,也必须是指向有效地址.


0 0
原创粉丝点击