您的位置:首页 > 其它

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

2015-11-15 09:26 309 查看
        通过前面的学习, 大家应该很了解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]$ ls
main.cpp
[taoge@localhost test]$ g++ main.cpp
[taoge@localhost test]$ ls
a.out  main.cpp
[taoge@localhost test]$ ./a.out
Segmentation fault (core dumped)
[taoge@localhost test]$ ls
a.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/d23352fd770753e375bd0caecf375bd77bded5
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 `./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/d23352fd770753e375bd0caecf375bd77bded5
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 `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x080486f7 in main () at main.cpp:10
10              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]$ ls
a.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/d23352fd770753e375bd0caecf375bd77bded5
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 `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x08048703 in main () at main.cpp:11
11              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, 本文先讨论到这里。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: