注意:这篇文章上次更新于935天前,文章内容可能已经过时。
面试官问程序崩溃了怎么调试?
我这里简单演示一下。
前期设置
我的环境是 Ubuntu 20.04 ,默认情况下是程序崩溃是不产生 core 文件的。
首先通过 ulimit -a
查看 core 文件的大小。
可以看到,默认情况下 core 文件的大小为 0 ,就是不生成 core 文件。
所以这里首先要通过 ulimit -c 文件大小
命令来设置文件大小。
我这里执行 ulimit -c unlimited
设置为无限大小。
可以再使用 ulimit -a
来查看设置结果。
可以看到 core 文件大小已经设置为无限大。
需要注意的是,这种设置方法只对当前用户生效,并且重新登录也会失效。
接下来要设置默认生成的 core 文件名字的格式。
首先问一下 “男人” 关于 core 文件的信息。
man core
我们可以看到关于文件名字的如下内容。(还好没有特别复杂的单词😏)
大概意思就是说修改 /proc/sys/kernel/core_pattern
文件中的内容可以改变 core 文件的默认命名。
这里我简单示范一下。
echo 'core-%s-%p-%t' > /proc/sys/kernel/core_pattern
core dumped 代码测试
首先写一个会产生段错误的代码,这里用空指针赋值为例。
/*
* filename:test.cpp
*/
#include <iostream>
using namespace std;
void coredump2(int x){
int* p = nullptr;
*p = x; // 这一行出现错误
return;
}
void coredump1(int x){
coredump2(x); //
return;
}
int main(){
int a = 2;
coredump1(a); //
cout << ++a+a++ << endl;
cout << a+++a++ << endl;
cout << ++a+(++a) << endl;
return 0;
}
使用 g++ 编译,这里加上 -g 调试模式选项,-O0 不开启编译器优化, -Wall 开启所有警告信息。
g++ -o app test.cpp -O0 -Wall -g
编译成功后,执行./app
会导致程序崩溃,并产生相应的 core 文件。
接下来可以使用 gdb 调试 core 文件来定位崩溃原因。
需要执行 gdb app core-11-259677-1653376476
此时可以定位到程序崩溃位置为 test.cpp 文件的第 9 行。
使用 bt 命令可以查看程序崩溃时的函数调用栈的情况,方便我们进一步定位问题。
OK !
距离拿到 offer 又进了一步。😂
那么,另一个问题来了,如果主函数中删除掉
coredump1
函数的调用,程序的输出是多少呢?😏感兴趣的同学试验一下,期待路过的大佬留言给我解释一下,我是解释不通了。😥