用gdb来调试对stl的空vector进行操作而产生的core
2015-11-15 09:26
309 查看
通过前面的学习, 大家应该很了解gdb调试core了, 今天我们用gdb来调试对stl的空vector进行操作而产生的core.
先不说core, 而是来学学vector的front方法, 如下:
实际上, 单纯的v.front()并不会有错, 错就错在后面用cout用这个东西, 如下再看:
本文除了复习gdb调试core, 还有一个重点需要注意
: 在操作stl的时候, 必要时一定需要进行合法判断, 这是程序员自己的责任, 而不是stl的责任。 再比如, 在出栈前, 必须对栈进行非空判断, 否则必定core dump. 据我的经验, 很多人在真正项目中就碰到空stl引起的core dump,
最后大费周折。
再次大声疾呼, 代码质量不是一句空话啊。OK, 本文先讨论到这里。
先不说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, 本文先讨论到这里。
相关文章推荐
- WinPcap笔记(10):从堆文件中读取数据包
- C中的setjmp与longjmp
- 57.Oracle数据库SQL开发之 高级查询——使用CASE函数
- GridView常用总结
- UITableView如何让cell的分割线左边不缩进
- Jquery Ajax请求方法小结(值得收藏)
- 数据结构例程——每对顶点之间的最短路径
- 56.Oracle数据库SQL开发之 高级查询——使用DECODE函数
- win10和Linux双系统怎么在win10下用EasyBcd卸载Linux系统
- 关于不同的程序入口,main(), _tmain(),WinMain(),wmain()?
- Android中用手势的双击事件实现图片单击放大效果
- 使用commandfield删除、修改gridview
- UIView动画和定时器
- TOMCAT ssl 强制访问设置
- Qt初学经验总结
- Android校验类积累
- 再谈Dell-EMC并购:Dell的终极目标是什么?
- Python学习笔记006_异常_else_with
- 再谈Dell-EMC并购:Dell的终极目标是什么?
- stdarg.h详解