• 《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每一个节点(头节点除外).



  • 相关阅读:
    51nod 1565模糊搜索(FFT)
    51nod 1851俄罗斯方块(trick)
    可持久化线段树(主席树)模板
    BZOJ2191:Splite
    BZOJ4197:[NOI2015]寿司晚宴
    BZOJ3198:[SDOI2013]SPRING
    BZOJ1500:[NOI2005]维修数列
    BZOJ3527:[ZJOI]力
    BZOJ3160:万径人踪灭
    CODE[VS]1372:DNA
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6867224.html
Copyright © 2020-2023  润新知