问题由来
今天某个同学问我,说自己写了一个很长的代码,使用 -O0 编译的时候没有问题,使用 -O2 编译,就会产生 Segmentation fault,然后程序就结束了,百思不得其解。
这个问题很简单:
1、使用 -O0 的编译的时候,系统是不会优化代码的。
2、使用 -O2 的编译的时候,系统是会优化代码的。
3、这个问题产生的原因大概率是以下几个可能:非法指针、数组访问越界、类构造函数等。
那么如何如何定位问题呢?其实 Linux 下有强大的 gdb,加上代码 Segmentation fault 后产生的 core 文件,我们就可以非常容易定位问题。不需要逐一阅读代码。
运行环境
Win10 + WSL2 + Ubuntu 18.04
在 Ubuntu 中设置 ulimit
$ sudo vim /etc/profile
在文件中添加一下
ulimit -c unlimited
在命令行中验证设置。
可以看到 ulimit 已经发生作用。
测试代码
编辑代码
测试代码如下。
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int *p=NULL;
*p=10;
cout<<*p<<"\n";
return 0;
}
上面代码,我们知道 *p=10; 这句话将导致 Segmentation fault。
编译
$ g++ -g test.cpp -o test
运行产生 core 文件
zhouyi@O7070-8B00:~$ ./test
Segmentation fault (core dumped)
zhouyi@O7070-8B00:~$ ls -l
total 256
-rw------- 1 zhouyi zhouyi 491520 Sep 8 16:00 core
-rwxr-xr-x 1 zhouyi zhouyi 28776 Sep 8 15:47 test
-rw-r--r-- 1 zhouyi zhouyi 124 Sep 8 15:47 test.cpp
我们可以看到在当前目录下已经产生出对应的 coredump 文件。
使用 gdb 调试
对应的命令行为
$ gdb ./test core
运行的结果如下图。
好了,已经告诉你哪里除了问题,如上图红色框所示。
也可以在 gdb 中增加 bt 命令,来看调用的堆栈情况。如下图所示。
Enjoy it.