用gdb来调试对stl的空vector进行操作而产生的core

来源:互联网 发布:淘宝达人是怎么赚钱的 编辑:程序博客网 时间:2024/06/05 23:45

        通过前面的学习, 大家应该很了解gdb调试core了, 今天我们用gdb来调试对stl的空vector进行操作而产生的core.


        先不说core, 而是来学学vector的front方法, 如下:

[taoge@localhost test]$ cat main.cpp #include <iostream>#include <vector>using namespace std;int main(){        vector<int> v;        v.push_back(1);        v.push_back(2);        cout << v.front() << endl;        v.front() -= 10;        cout << v[0] << endl;        return 0;}[taoge@localhost test]$ g++ main.cpp [taoge@localhost test]$ ./a.out 1-9[taoge@localhost test]$ 
        要注意, v.front()是对vector首元素的引用, 所以可以做左值。  但是, 当vector为空的时候, 就有问题了, 产生了core, 如下:

[taoge@localhost test]$ cat main.cpp -n     1  #include <iostream>     2  #include <vector>     3     4  using namespace std;     5     6  int main()     7  {     8          vector<int> v;     9    10          cout << v.front() << endl;    11          v.front() -= 10;    12    13          cout << v[0] << endl;    14    15          return 0;    16  }    17[taoge@localhost test]$ lsmain.cpp[taoge@localhost test]$ g++ main.cpp [taoge@localhost test]$ lsa.out  main.cpp[taoge@localhost test]$ ./a.out Segmentation fault (core dumped)[taoge@localhost test]$ lsa.out  core.2917  main.cpp[taoge@localhost test]$ [taoge@localhost test]$ [taoge@localhost test]$ [taoge@localhost test]$ gdb a.out core.2917 GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.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/taoge/test/a.out...(no debugging symbols found)...done.[New Thread 2917]Missing separate debuginfo for Try: yum --disablerepo='*' --enablerepo='*-debuginfo' install /usr/lib/debug/.build-id/74/d23352fd770753e375bd0caecf375bd77bded5Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.Loaded symbols for /usr/lib/libstdc++.so.6Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libm.so.6Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.Loaded symbols for /lib/libgcc_s.so.1Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.2Core was generated by `./a.out'.Program terminated with signal 11, Segmentation fault.#0  0x080486f7 in main ()Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.i686 libgcc-4.4.4-13.el6.i686 libstdc++-4.4.4-13.el6.i686(gdb) (gdb) (gdb) (gdb) bt#0  0x080486f7 in main ()(gdb) 
        可以看到, 运行程序的时候, 程序core dump了, 产生了core文件, 但是用gdb只能找到出错的地址, 找不到代码行, 为什么呢? 因为编译的时候没有-g选项, 重新来做一遍, 如下:

[taoge@localhost test]$ cat main.cpp -n     1  #include <iostream>     2  #include <vector>     3     4  using namespace std;     5     6  int main()     7  {     8          vector<int> v;     9    10          cout << v.front() << endl;    11          v.front() -= 10;    12    13          cout << v[0] << endl;    14    15          return 0;    16  }    17[taoge@localhost test]$ g++ main.cpp -g[taoge@localhost test]$ ./a.out Segmentation fault (core dumped)[taoge@localhost test]$ [taoge@localhost test]$ [taoge@localhost test]$ [taoge@localhost test]$ gdb a.out core.2947 GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.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/taoge/test/a.out...done.[New Thread 2947]Missing separate debuginfo for Try: yum --disablerepo='*' --enablerepo='*-debuginfo' install /usr/lib/debug/.build-id/74/d23352fd770753e375bd0caecf375bd77bded5Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.Loaded symbols for /usr/lib/libstdc++.so.6Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libm.so.6Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.Loaded symbols for /lib/libgcc_s.so.1Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.2Core was generated by `./a.out'.Program terminated with signal 11, Segmentation fault.#0  0x080486f7 in main () at main.cpp:1010              cout << v.front() << endl;Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.i686 libgcc-4.4.4-13.el6.i686 libstdc++-4.4.4-13.el6.i686(gdb) (gdb) (gdb) (gdb) bt#0  0x080486f7 in main () at main.cpp:10(gdb) 
        定位到了第10行除了问题。 


         实际上, 单纯的v.front()并不会有错, 错就错在后面用cout用这个东西, 如下再看:

[taoge@localhost test]$ cat main.cpp -n     1  #include <iostream>     2  #include <vector>     3     4  using namespace std;     5     6  int main()     7  {     8          vector<int> v;     9          v.front();    10    11          int a = v.front();    12          cout << v[0] << endl;    13    14          return 0;    15  }    16[taoge@localhost test]$ g++ main.cpp -g[taoge@localhost test]$ lsa.out  main.cpp[taoge@localhost test]$ ./a.out Segmentation fault (core dumped)[taoge@localhost test]$ [taoge@localhost test]$ [taoge@localhost test]$ [taoge@localhost test]$ gdb a.out core.3099 GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.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/taoge/test/a.out...done.[New Thread 3099]Missing separate debuginfo for Try: yum --disablerepo='*' --enablerepo='*-debuginfo' install /usr/lib/debug/.build-id/74/d23352fd770753e375bd0caecf375bd77bded5Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.Loaded symbols for /usr/lib/libstdc++.so.6Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libm.so.6Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.Loaded symbols for /lib/libgcc_s.so.1Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.2Core was generated by `./a.out'.Program terminated with signal 11, Segmentation fault.#0  0x08048703 in main () at main.cpp:1111              int a = v.front();Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.i686 libgcc-4.4.4-13.el6.i686 libstdc++-4.4.4-13.el6.i686(gdb) (gdb) (gdb) (gdb) bt#0  0x08048703 in main () at main.cpp:11(gdb) 
        代码是在第11行core调的, 而不是第9行, 我猜想, 编译器肯定是把第9行优化掉了, 因为它没有什么作用,可以dead code处理。


         本文除了复习gdb调试core, 还有一个重点需要注意奋斗: 在操作stl的时候, 必要时一定需要进行合法判断, 这是程序员自己的责任, 而不是stl的责任。 再比如, 在出栈前, 必须对栈进行非空判断, 否则必定core dump.  据我的经验, 很多人在真正项目中就碰到空stl引起的core dump, 最后大费周折。

         再次大声疾呼, 代码质量不是一句空话啊。OK, 本文先讨论到这里。










0 0