How coredump works exploring vector objects and how coredump works in section 7.1 of Linux x86
Let's take a look at the example:
1 #include <vector> 2 3 int main() 4 { 5 std::vector<int> vec; 6 vec.push_back( 0xffeeffab ); 7 vec.push_back( 0xabcdef01 ); 8 vec.push_back( 0x12345678 ); 9 return 0; 10 }
Let's take a look at the compilation:
(gdb) b mainBreakpoint 1 at 0x8048697(gdb) rStarting program: /home/xuzhina/code/s1/xuzhina_dump_c07_s1 Breakpoint 1, 0x08048697 in main ()Missing 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) disassemble Dump of assembler code for function main: 0x08048694 <+0>:push %ebp 0x08048695 <+1>:mov %esp,%ebp=> 0x08048697 <+3>:and $0xfffffff0,%esp 0x0804869a <+6>:push %esi 0x0804869b <+7>:push %ebx 0x0804869c <+8>:sub $0x38,%esp 0x0804869f <+11>:lea 0x18(%esp),%eax 0x080486a3 <+15>:mov %eax,(%esp) 0x080486a6 <+18>:call 0x8048740 <_ZNSt6vectorIiSaIiEEC2Ev> 0x080486ab <+23>:movl $0xffeeffab,0x24(%esp) 0x080486b3 <+31>:lea 0x24(%esp),%eax 0x080486b7 <+35>:mov %eax,0x4(%esp) 0x080486bb <+39>:lea 0x18(%esp),%eax 0x080486bf <+43>:mov %eax,(%esp) 0x080486c2 <+46>:call 0x80487b2 <_ZNSt6vectorIiSaIiEE9push_backERKi> 0x080486c7 <+51>:movl $0xabcdef01,0x28(%esp) 0x080486cf <+59>:lea 0x28(%esp),%eax 0x080486d3 <+63>:mov %eax,0x4(%esp) 0x080486d7 <+67>:lea 0x18(%esp),%eax 0x080486db <+71>:mov %eax,(%esp) 0x080486de <+74>:call 0x80487b2 <_ZNSt6vectorIiSaIiEE9push_backERKi> 0x080486e3 <+79>:movl $0x12345678,0x2c(%esp) 0x080486eb <+87>:lea 0x2c(%esp),%eax 0x080486ef <+91>:mov %eax,0x4(%esp) 0x080486f3 <+95>:lea 0x18(%esp),%eax 0x080486f7 <+99>:mov %eax,(%esp) 0x080486fa <+102>:call 0x80487b2 <_ZNSt6vectorIiSaIiEE9push_backERKi> 0x080486ff <+107>:mov $0x0,%ebx 0x08048704 <+112>:lea 0x18(%esp),%eax 0x08048708 <+116>:mov %eax,(%esp) 0x0804870b <+119>:call 0x8048754 <_ZNSt6vectorIiSaIiEED2Ev> 0x08048710 <+124>:mov %ebx,%eax 0x08048712 <+126>:add $0x38,%esp 0x08048715 <+129>:pop %ebx 0x08048716 <+130>:pop %esi 0x08048717 <+131>:mov %ebp,%esp 0x08048719 <+133>:pop %ebp 0x0804871a <+134>:ret 0x0804871b <+135>:mov %edx,%ebx 0x0804871d <+137>:mov %eax,%esi 0x0804871f <+139>:lea 0x18(%esp),%eax 0x08048723 <+143>:mov %eax,(%esp) 0x08048726 <+146>:call 0x8048754 <_ZNSt6vectorIiSaIiEED2Ev> 0x0804872b <+151>:mov %esi,%eax 0x0804872d <+153>:mov %ebx,%edx 0x0804872f <+155>:mov %eax,(%esp) 0x08048732 <+158>:call 0x80485c8 <_Unwind_Resume@plt>End of assembler dump.
From the instructions in the vicinity of 0x080486a6, 0x080486c2, 0x080486de, 0x080486fa, 0x0804870b, this pointer of vector is placed in esp + 0x18.
At 0x080486a6, 0x080486c2, 0x080486de, 0x080486fa, and 0x0804870b, open a breakpoint to see how the content pointed to by this pointer changes:
0x080486a6 calls the vector constructor:
(gdb) cContinuing.Breakpoint 2, 0x080486a6 in main ()(gdb) x /4x $esp+0x180xbffff248:0xbffff2780x080491090x00210df00x080483a4(gdb) x /4x 0xbffff2780xbffff278:0xbffff2f80x0027ad360x000000010xbffff324(gdb) ni0x080486ab in main ()(gdb) x /4x $esp+0x180xbffff248:0x000000000x000000000x000000000x080483a4
It can be seen from the above that the footprint of a vector on the stack is three units.
Let's take a look at the changes in the vector after the first push_back.
(gdb) cContinuing.Breakpoint 3, 0x080486c2 in main ()(gdb) x /4x $esp+0x180xbffff248:0x000000000x000000000x000000000xffeeffab(gdb) ni0x080486c7 in main ()(gdb) x /4x $esp+0x180xbffff248:0x0804b0080x0804b00c0x0804b00c0xffeeffab(gdb) x /4x 0x0804b0080x804b008:0xffeeffab0x000000000x000000000x00020ff1
We can see that the first member of the vector points to the memory 0x0804b008, and the first value of push_back comes in 0xffeeffab. the second member of the vector points to memory 0x0804b00c, Which is exactly four bytes different from the first member and exactly matches an int member in the vector.
Next, let's take a look at the second push_back.
(gdb) cContinuing.Breakpoint 4, 0x080486de in main ()(gdb) x /4x $esp+0x180xbffff248:0x0804b0080x0804b00c0x0804b00c0xffeeffab(gdb) ni0x080486e3 in main ()(gdb) x /4x $esp+0x180xbffff248:0x0804b0180x0804b0200x0804b0200xffeeffab(gdb) x /4x 0x0804b0180x804b018:0xffeeffab0xabcdef010x000000000x00020fe1
The values of the three members of the vector change. the first member changes from 0x0804b008 to 0x0804b018, but the content pointed to by the first member is the same as 0 xffeeffab, while the adjacent unit is 0xabcdef01, which is the same as the value of the second vector. the second member is 8 bytes different from the first Member, which is exactly two int bytes. It is exactly the same as that of the vector with two members.
Test the third push_back:
(gdb) cContinuing.Breakpoint 5, 0x080486fa in main ()(gdb) x /4x $esp+0x180xbffff248:0x0804b0180x0804b0200x0804b0200xffeeffab(gdb) ni0x080486ff in main ()(gdb) x /4x $esp+0x180xbffff248:0x0804b0280x0804b0340x0804b0380xffeeffab(gdb) x /4x 0x0804b0280x804b028:0xffeeffab0xabcdef010x123456780x00000000
We can still find that the first Member points to the beginning of the vector element, and the second member is the next position of the end of the vector element. The difference between them and the operator of the element size is exactly the number of elements.
If we further examine the vectors of char, short, long, float, double, array, struct, and class objects, and combine them with the definition of vector
(Refer to the header file/usr/include/c ++/4.4.7/bits/stl_vector.h ).