See a coredump example:
See a coredump example: Core was generated by './xuzhina_dump_c07_s2_ex '. Program terminated with signal one, segmentation fault. #0 0x0285b9b7 in Std::_list_node_base::hook (std::_list_node_ base*) () from/usr/lib/libstdc++.so.6missing separate debuginfos, Use:debuginfo-install glibc-2.12-1.149.el6_ 6.4.i686 libgcc-4.4.7-11.el6.i686 libstdc++-4.4.7-11.el6.i686 (gdb) bt#0 0x0285b9b7 in Std::_list_node_base:: Hook (std::_list_node_base*) () from/usr/lib/libstdc++.so.6#1 0x080488fd in Std::list<int, std:: Allocator<int> >::_m_insert (std::_list_iterator<int>, int const&) () #2 0x08048784 in std:: List<int, std::allocator<int>;::p ush_back (int const&) () #3 0x08048676 in Main ()
Look at the assembly of the crash function:
0 0x0285b9b7 in Std::_list_node_base::hook (std::_list_node_base*) () from/usr/lib/libstdc++.so.6 (GDB) Disassemble Dump of assembler code for function _znst15_list_node_base4hookeps_: 0x0285b9a0 <+0>:p ush % EBP 0x0285b9a1 <+1>:mov %esp,%ebp 0x0285b9a3 <+3>:mov 0xc (%EBP),%eax 0X0285B9A6 <+6>:mov 0x8 (%EBP),%edx 0x0285b9a9 <+9>:mov 0x4 (%eax),%ecx 0x0285b9ac <+12> : mov %eax, (%edx) 0x0285b9ae <+14>:mov %ecx,0x4 (%edx) 0x0285b9b1 <+17>:mov 0x4 (%eax),%ecx 0x0285b9b4 <+20>:mov %edx,0x4 (%eax) = 0x0285b9b7 <+23>:mov %edx, (% ECX) 0x0285b9b9 <+25>:p op %ebp 0x0285b9ba <+26>:ret End of assembler dump.
Look at the value of the Register:
(gdb) I reax 0xbfedc248-1074937272ecx 0x00edx 0x9309028154177576ebx 0x9faff410465268esp 0XBFEDC1C80XBFEDC1C8EBP 0xbfedc1c80xbfedc1c8esi 0x00edi 0x00eip 0x285b9b70x285b9b7 <std::_ List_node_base::hook (std::_list_node_base*) +23>eflags 0x10282[SF IF RF]cs 0x73115ss 0x7b123ds 0x7b123es 0x7b123fs 0x00gs 0x3351
Visible, is due to the value of ECX is 0. The value of ECX is derived from eax, while the value of EAX is derived from ebp+0xc. Because the this pointer is placed on the ebp+0x8, ebp+0xc places the first argument.
by Bits/stl_list.h:
void Hook (_list_node_base * const __position);
It is __position that the value of _prev is 0. So where did __position come from?
Based on the functions in the stack and stl_list.h:
void _m_insert (iterator __position, const value_type& __x) { _node* __tmp = _m_create_node (__x); __tmp->hook (__position._m_node); } void push_back (const value_type& __x) {This->_m_insert (end (), __x);}
This __position is the return value of end (), combined with the definition of list, that __position is actually the tail of the list.
So how could the tail element be 0?
Take a look at the main function:
(GDB) disassemble Dump of assembler code for function main:0x080485e4 <+0>:p ush%ebp 0x080485e5 <+1>:mo V%esp,%ebp 0x080485e7 <+3>:and $0xfffffff0,%esp 0x080485ea <+6>:p ush%esi 0x080485eb <+7> :p ush%ebx 0x080485ec <+8>:sub $0x38,%esp 0x080485ef <+11>:lea 0x18 (%ESP),%eax 0x080485f3 <+1 5>:mov%eax, (%ESP) 0x080485f6 <+18>:call 0x80486e6 <_ZNSt4listIiSaIiEEC2Ev> 0x080485fb <+23> : Movl $0x5,0x20 (%ESP) 0x08048603 <+31>:lea 0x20 (%ESP),%eax 0x08048607 <+35>:mov%eax,0x4 (%ESP) 0 x0804860b <+39>:lea 0x18 (%ESP),%eax 0x0804860f <+43>:mov%eax, (%esp) 0x08048612 <+46>:call 0 x8048750 <_ZNSt4listIiSaIiEE9push_backERKi> 0x08048617 <+51>:movl $0x3,0x24 (%esp) 0x0804861f <+59> : Lea 0x24 (%ESP),%eax 0x08048623 <+63>:mov%eax,0x4 (%esp) 0x08048627 <+67>:lea 0x18 (%esp),%eax 0 X0804862B <+71>:moV%eax, (%esp) 0x0804862e <+74>:call 0x8048786 <_ZNSt4listIiSaIiEE10push_frontERKi> 0x08048633 <+79 >:lea 0x18 (%ESP),%eax---Type <return> to continue, or Q <return> to quit---0x08048637 <+83>:mov %eax, (%ESP) 0x0804863a <+86>:call 0x80487bc <_ZNKSt4listIiSaIiEE4sizeEv> 0x0804863f <+91>:SHL $0x2,%eax 0x08048642 <+94>:mov%eax,0x8 (%esp) 0x08048646 <+98>:movl $0x0,0x4 (%esp) 0x0804864e &L T;+106>:lea 0x18 (%ESP),%eax 0x08048652 <+110>:mov%eax, (%ESP) 0x08048655 <+113>:call 0x80484b8 <[email protected]> 0x0804865a <+118>:movl $0x8,0x28 (%esp) 0x08048662 <+126>:lea 0x28 (%esp ),%eax 0x08048666 <+130>:mov%eax,0x4 (%esp) 0x0804866a <+134>:lea 0x18 (%ESP),%eax 0x0804866e <+ 138>:mov%eax, (%ESP) 0x08048671 <+141>:call 0x8048750 <_ZNSt4listIiSaIiEE9push_backERKi>=> 0x0804 8676 <+146>:MOVL $0XC,0X2C (%ESP) 0x0804867e <+154>:lea 0x2c (%ESP),%eax 0x08048682 <+158>:mov%eax,0x4 (%ESP) 0x0804 8686 <+162>:lea 0x18 (%ESP),%eax 0x0804868a <+166>:mov%eax, (%ESP) 0x0804868d <+169>:call 0x8 048750 <_ZNSt4listIiSaIiEE9push_backERKi> 0x08048692 <+174>:mov $0x0,%ebx 0x08048697 <+179>:lea 0x18 (%ESP),%eax 0x0804869b <+183>:mov%eax, (%ESP)---Type <return> to continue, or Q <return> to Q Uit---0x0804869e <+186>:call 0x80486d2 <_ZNSt4listIiSaIiEED2Ev> 0x080486a3 <+191>:mov%ebx,%ea X 0x080486a5 <+193>:add $0x38,%esp 0x080486a8 <+196>:p op%ebx 0x080486a9 <+197>:p op%esi 0X080486AA <+198>:mov%ebp,%esp 0x080486ac <+200>:p op%ebp 0x080486ad <+201>:ret 0x080 486ae <+202>:mov%edx,%ebx 0x080486b0 <+204>:mov%eax,%esi 0x080486b2 <+206>:lea 0x18 (%ESP) ,%eax 0x080486b6 <+210>:mov%eax, (%ESP) 0x080486b9 <+213>:call 0x80486d2 <_ZNSt4listIiSaIiEED2Ev> 0x080486be <+218 >:mov%esi,%eax 0x080486c0 <+220>:mov%ebx,%edx 0x080486c2 <+222>:mov%eax, (%ESP) 0x080486c5 <+225>:call 0x8048518 <[email protected]>end of assembler dump.
By
0x08048642 <+94>:mov %eax,0x8 (%esp) 0x08048646 <+98>:movl $0x0,0x4 (%esp) 0x0804864e <+106>:lea 0x18 (%ESP),%eax 0x08048652 <+110>:mov %eax, (%ESP) 0x08048655 <+113> : Call 0x80484b8 <[email protected]> 0x0804865a <+118>:movl $0x8,0x28 (%ESP) 0x08048662 <+126>:lea 0x28 (%ESP),%eax 0x08048666 <+130>:mov%eax,0x4 (%ESP) 0x0804866a <+134>:lea 0x18 (%ESP),%eax 0x0804866e <+138>:mov%eax , (%ESP) 0x08048671 <+141>:call 0x8048750 <_ZNSt4listIiSaIiEE9push_backERKi>=> 0x08048676 <+146>: MOVL $0xc,0x2c (%ESP)
It is known that the list is placed in the position of the esp+0x18, and the list of two values is initialized to 0 with Memset.
Source:
1 #include <list> 2 #include <string.h> 3 4 int main () 5 { 6 std::list<int> list; 7 8 list.push_back (5); 9 List.push_front (3); memset (&list, 0, List.size () *sizeof (int)); List.push_back (8); list.push_back (0); 17}
"Research on the principle of Coredump" Linux x86 version 7.4 section list Coredump example