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

看一个coredump的例子:


[xuzhina@localhost 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/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/xuzhina/code/s1_ex/xuzhina_dump_c07_s1_ex...(no debugging symbols found)...done.

warning: core file may not match specified executable file.
[New Thread 27776]
Missing separate debuginfo for 
Try: yum --enablerepo='*-debug*' install /usr/lib/debug/.build-id/34/cbbfa23c72628894342b10c77f636b35126a7f
Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./xuzhina_dump_c07_s1_ex'.
Program terminated with signal 11, Segmentation fault.
#0  0x08048afb in __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > std::merge<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >) ()
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) bt
#0  0x08048afb in __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > std::merge<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >) ()
#1  0x08048871 in main ()


看一下std::_Merge的汇编

(gdb) disassemble 
Dump of assembler code for function _ZSt5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_S6_ET1_T_S8_T0_S9_S7_:
   0x08048a88 <+0>:	push   %ebp
   0x08048a89 <+1>:	mov    %esp,%ebp
   0x08048a8b <+3>:	push   %esi
   0x08048a8c <+4>:	push   %ebx
   0x08048a8d <+5>:	sub    $0x20,%esp
   0x08048a90 <+8>:	mov    0x8(%ebp),%esi
   0x08048a93 <+11>:	jmp    0x8048b13 <_ZSt5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_S6_ET1_T_S8_T0_S9_S7_+139>
   0x08048a95 <+13>:	lea    0x14(%ebp),%eax
   0x08048a98 <+16>:	mov    %eax,(%esp)
   0x08048a9b <+19>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048aa0 <+24>:	mov    (%eax),%ebx
   0x08048aa2 <+26>:	lea    0xc(%ebp),%eax
   0x08048aa5 <+29>:	mov    %eax,(%esp)
   0x08048aa8 <+32>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048aad <+37>:	mov    (%eax),%eax
   0x08048aaf <+39>:	cmp    %eax,%ebx
   0x08048ab1 <+41>:	setl   %al
   0x08048ab4 <+44>:	test   %al,%al
---Type <return> to continue, or q <return> to quit---
   0x08048ab6 <+46>:	je     0x8048ae1 <_ZSt5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_S6_ET1_T_S8_T0_S9_S7_+89>
   0x08048ab8 <+48>:	lea    0x1c(%ebp),%eax
   0x08048abb <+51>:	mov    %eax,(%esp)
   0x08048abe <+54>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048ac3 <+59>:	mov    %eax,%ebx
   0x08048ac5 <+61>:	lea    0x14(%ebp),%eax
   0x08048ac8 <+64>:	mov    %eax,(%esp)
   0x08048acb <+67>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048ad0 <+72>:	mov    (%eax),%eax
   0x08048ad2 <+74>:	mov    %eax,(%ebx)
   0x08048ad4 <+76>:	lea    0x14(%ebp),%eax
   0x08048ad7 <+79>:	mov    %eax,(%esp)
   0x08048ada <+82>:	call   0x8048f5e <_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv>
   0x08048adf <+87>:	jmp    0x8048b08 <_ZSt5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_S6_ET1_T_S8_T0_S9_S7_+128>
   0x08048ae1 <+89>:	lea    0x1c(%ebp),%eax
   0x08048ae4 <+92>:	mov    %eax,(%esp)
   0x08048ae7 <+95>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048aec <+100>:	mov    %eax,%ebx
   0x08048aee <+102>:	lea    0xc(%ebp),%eax
   0x08048af1 <+105>:	mov    %eax,(%esp)
   0x08048af4 <+108>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048af9 <+113>:	mov    (%eax),%eax
=> 0x08048afb <+115>:	mov    %eax,(%ebx)
   0x08048afd <+117>:	lea    0xc(%ebp),%eax
   0x08048b00 <+120>:	mov    %eax,(%esp)
   0x08048b03 <+123>:	call   0x8048f5e <_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv>
   0x08048b08 <+128>:	lea    0x1c(%ebp),%eax
   0x08048b0b <+131>:	mov    %eax,(%esp)
   0x08048b0e <+134>:	call   0x8048f5e <_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEppEv>
   0x08048b13 <+139>:	lea    0x10(%ebp),%eax
   0x08048b16 <+142>:	mov    %eax,0x4(%esp)
   0x08048b1a <+146>:	lea    0xc(%ebp),%eax
   0x08048b1d <+149>:	mov    %eax,(%esp)
   0x08048b20 <+152>:	call   0x8048f27 <_ZN9__gnu_cxxneIPiSt6vectorIiSaIiEEEEbRKNS_17__normal_iteratorIT_T0_EESA_>
   0x08048b25 <+157>:	test   %al,%al
   0x08048b27 <+159>:	je     0x8048b46 <_ZSt5mergeIN9__gnu_cxx17__normal_itera

由上面汇编可以看出,崩溃指令的ebx刚好是

__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::operator*() const

的返回值,而这个成员函数的this指针由

   0x08048ae1 <+89>:	lea    0x1c(%ebp),%eax
   0x08048ae4 <+92>:	mov    %eax,(%esp)
   0x08048ae7 <+95>:	call   0x8048f54 <_ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv>
   0x08048aec <+100>:	mov    %eax,%ebx

是从第六个参数(ebp+0x1c)获取的.

而这个函数的实现:

(gdb) disassemble 0x8048f54
Dump of assembler code for function _ZNK9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEdeEv:
   0x08048f54 <+0>:	push   %ebp
   0x08048f55 <+1>:	mov    %esp,%ebp
   0x08048f57 <+3>:	mov    0x8(%ebp),%eax
   0x08048f5a <+6>:	mov    (%eax),%eax
   0x08048f5c <+8>:	pop    %ebp
   0x08048f5d <+9>:	ret    
End of assembler dump.


可见,这个函数仅仅是把this指针指向的第一个成员的值返回了.

 

那么,只能看上一层的函数main函数来确定一下这个this指针究竟是怎么回事吧.

(gdb) frame 1
#1  0x08048871 in main ()
(gdb) disassemble 
Dump of assembler code for function main:
   0x08048774 <+0>:	lea    0x4(%esp),%ecx
   0x08048778 <+4>:	and    $0xfffffff0,%esp
   0x0804877b <+7>:	pushl  -0x4(%ecx)
   0x0804877e <+10>:	push   %ebp
   0x0804877f <+11>:	mov    %esp,%ebp
   0x08048781 <+13>:	push   %esi
   0x08048782 <+14>:	push   %ebx
   0x08048783 <+15>:	push   %ecx
   0x08048784 <+16>:	sub    $0x7c,%esp
   0x08048787 <+19>:	lea    -0x44(%ebp),%eax
   0x0804878a <+22>:	mov    %eax,(%esp)
   0x0804878d <+25>:	call   0x8048958 <_ZNSt6vectorIiSaIiEEC2Ev>
   0x08048792 <+30>:	movl   $0x1,-0x38(%ebp)
   0x08048799 <+37>:	lea    -0x38(%ebp),%eax
   0x0804879c <+40>:	mov    %eax,0x4(%esp)
   0x080487a0 <+44>:	lea    -0x44(%ebp),%eax
   0x080487a3 <+47>:	mov    %eax,(%esp)
   0x080487a6 <+50>:	call   0x80489ca <_ZNSt6vectorIiSaIiEE9push_backERKi>
   0x080487ab <+55>:	lea    -0x50(%ebp),%eax
   0x080487ae <+58>:	mov    %eax,(%esp)
   0x080487b1 <+61>:	call   0x8048958 <_ZNSt6vectorIiSaIiEEC2Ev>
   0x080487b6 <+66>:	movl   $0x8,-0x34(%ebp)
---Type <return> to continue, or q <return> to quit---
   0x080487bd <+73>:	lea    -0x34(%ebp),%eax
   0x080487c0 <+76>:	mov    %eax,0x4(%esp)
   0x080487c4 <+80>:	lea    -0x50(%ebp),%eax
   0x080487c7 <+83>:	mov    %eax,(%esp)
   0x080487ca <+86>:	call   0x80489ca <_ZNSt6vectorIiSaIiEE9push_backERKi>
   0x080487cf <+91>:	lea    -0x5c(%ebp),%eax
   0x080487d2 <+94>:	mov    %eax,(%esp)
   0x080487d5 <+97>:	call   0x8048958 <_ZNSt6vectorIiSaIiEEC2Ev>
   0x080487da <+102>:	lea    -0x2c(%ebp),%eax
   0x080487dd <+105>:	lea    -0x5c(%ebp),%edx
   0x080487e0 <+108>:	mov    %edx,0x4(%esp)
   0x080487e4 <+112>:	mov    %eax,(%esp)
   0x080487e7 <+115>:	call   0x8048a3e <_ZNSt6vectorIiSaIiEE5beginEv>
   0x080487ec <+120>:	sub    $0x4,%esp
   0x080487ef <+123>:	lea    -0x28(%ebp),%eax
   0x080487f2 <+126>:	lea    -0x50(%ebp),%edx
   0x080487f5 <+129>:	mov    %edx,0x4(%esp)
   0x080487f9 <+133>:	mov    %eax,(%esp)
   0x080487fc <+136>:	call   0x8048a62 <_ZNSt6vectorIiSaIiEE3endEv>
   0x08048801 <+141>:	sub    $0x4,%esp
   0x08048804 <+144>:	lea    -0x24(%ebp),%eax
   0x08048807 <+147>:	lea    -0x50(%ebp),%edx
   0x0804880a <+150>:	mov    %edx,0x4(%esp)
---Type <return> to continue, or q <return> to quit---
   0x0804880e <+154>:	mov    %eax,(%esp)
   0x08048811 <+157>:	call   0x8048a3e <_ZNSt6vectorIiSaIiEE5beginEv>
   0x08048816 <+162>:	sub    $0x4,%esp
   0x08048819 <+165>:	lea    -0x20(%ebp),%eax
   0x0804881c <+168>:	lea    -0x44(%ebp),%edx
   0x0804881f <+171>:	mov    %edx,0x4(%esp)
   0x08048823 <+175>:	mov    %eax,(%esp)
   0x08048826 <+178>:	call   0x8048a62 <_ZNSt6vectorIiSaIiEE3endEv>
   0x0804882b <+183>:	sub    $0x4,%esp
   0x0804882e <+186>:	lea    -0x1c(%ebp),%eax
   0x08048831 <+189>:	lea    -0x44(%ebp),%edx
   0x08048834 <+192>:	mov    %edx,0x4(%esp)
   0x08048838 <+196>:	mov    %eax,(%esp)
   0x0804883b <+199>:	call   0x8048a3e <_ZNSt6vectorIiSaIiEE5beginEv>
   0x08048840 <+204>:	sub    $0x4,%esp
   0x08048843 <+207>:	lea    -0x30(%ebp),%eax
   0x08048846 <+210>:	mov    -0x2c(%ebp),%edx
   0x08048849 <+213>:	mov    %edx,0x14(%esp)
   0x0804884d <+217>:	mov    -0x28(%ebp),%edx
   0x08048850 <+220>:	mov    %edx,0x10(%esp)
   0x08048854 <+224>:	mov    -0x24(%ebp),%edx
   0x08048857 <+227>:	mov    %edx,0xc(%esp)
   0x0804885b <+231>:	mov    -0x20(%ebp),%edx
---Type <return> to continue, or q <return> to quit---
   0x0804885e <+234>:	mov    %edx,0x8(%esp)
   0x08048862 <+238>:	mov    -0x1c(%ebp),%edx
   0x08048865 <+241>:	mov    %edx,0x4(%esp)
   0x08048869 <+245>:	mov    %eax,(%esp)
   0x0804886c <+248>:	call   0x8048a88 <_ZSt5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_S6_ET1_T_S8_T0_S9_S7_>
=> 0x08048871 <+253>:	sub    $0x4,%esp
   0x08048874 <+256>:	mov    $0x0,%ebx
   0x08048879 <+261>:	lea    -0x5c(%ebp),%eax
   0x0804887c <+264>:	mov    %eax,(%esp)
   0x0804887f <+267>:	call   0x804896c <_ZNSt6vectorIiSaIiEED2Ev>
   0x08048884 <+272>:	jmp    0x80488b0 <main+316>
   0x08048886 <+274>:	mov    %edx,%ebx
   0x08048888 <+276>:	mov    %eax,%esi
   0x0804888a <+278>:	lea    -0x5c(%ebp),%eax
   0x0804888d <+281>:	mov    %eax,(%esp)
   0x08048890 <+284>:	call   0x804896c <_ZNSt6vectorIiSaIiEED2Ev>
   0x08048895 <+289>:	mov    %esi,%eax
   0x08048897 <+291>:	mov    %ebx,%edx
   0x08048899 <+293>:	jmp    0x804889b <main+295>
   0x0804889b <+295>:	mov    %edx,%ebx
   0x0804889d <+297>:	mov    %eax,%esi
   0x0804889f <+299>:	lea    -0x50(%ebp),%eax
---Type <return> to continue, or q <return> to quit---

   0x08048846 <+210>:	mov    -0x2c(%ebp),%edx
   0x08048849 <+213>:	mov    %edx,0x14(%esp)
   0x0804884d <+217>:	mov    -0x28(%ebp),%edx
   0x08048850 <+220>:	mov    %edx,0x10(%esp)
   0x08048854 <+224>:	mov    -0x24(%ebp),%edx
   0x08048857 <+227>:	mov    %edx,0xc(%esp)
   0x0804885b <+231>:	mov    -0x20(%ebp),%edx
---Type <return> to continue, or q <return> to quit---
   0x0804885e <+234>:	mov    %edx,0x8(%esp)
   0x08048862 <+238>:	mov    -0x1c(%ebp),%edx
   0x08048865 <+241>:	mov    %edx,0x4(%esp)
   0x08048869 <+245>:	mov    %eax,(%esp)
   0x0804886c <+248>:	call   0x8048a88 <_ZSt5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_S6_ET1_T_S8_T0_S9_S7_>
=> 0x08048871 <+253>:	sub    $0x4,%esp


可以看到第六个参数,应该是由ebp-0x2c的值.

而ebp-0x2c如何得来?看一下这段汇编:

0x080487cf <+91>:	lea    -0x5c(%ebp),%eax
   0x080487d2 <+94>:	mov    %eax,(%esp)
   0x080487d5 <+97>:	call   0x8048958 <_ZNSt6vectorIiSaIiEEC2Ev>
   0x080487da <+102>:	lea    -0x2c(%ebp),%eax
   0x080487dd <+105>:	lea    -0x5c(%ebp),%edx
   0x080487e0 <+108>:	mov    %edx,0x4(%esp)
   0x080487e4 <+112>:	mov    %eax,(%esp)
   0x080487e7 <+115>:	call   0x8048a3e <_ZNSt6vectorIiSaIiEE5beginEv>

用c++filt命令可以看到. _ZNSt6vectorIiSaIiEEC2Ev和_ZNSt6vectorIiSaIiEE5beginEv是

[xuzhina@localhost s1_ex]$ c++filt _ZNSt6vectorIiSaIiEEC2Ev
std::vector<int, std::allocator<int> >::vector()
[xuzhina@localhost s1_ex]$ c++filt _ZNSt6vectorIiSaIiEE5beginEv
std::vector<int, std::allocator<int> >::begin()


可知ebp-0x2c的值是由ebp-0x5c得来的。

看一下ebp-0x5c里存放着的是什么.

(gdb) x /4x $ebp-0x5c
0xbfb2b24c:	0x00000000	0x00000000	0x00000000	0x0865e018

可以看到ebp-0x54指向的vector对象, _M_start, _M_finish, _M_end_of_storage

三个指针都为0.说明vector只是调用完了构造函数,却没有进行别的操作来申请空间.

看一下源代码

  1 #include <vector>
  2 #include <algorithm>
  3 #include <iostream>
  4 
  5 int main()
  6 {
  7     std::vector<int> a;
  8     a.push_back(1);
  9 
 10     std::vector<int> b;
 11     b.push_back(8);
 12 
 13     std::vector<int> c;
 14     std::merge( a.begin(), a.end(), b.begin(), b.end(), c.begin() );
 15 
 16     return 0;
 17 }
                                   

可知,只有c这个vector对象只是构造了,没有申请任何空间,就进行了merge操作.在merge之前,可以调用一下成员函数reserve.


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。