以前用C/C++写程序时,运行时经常会出现错误,而且shell上也会出现“段错误(吐核)”的错误输出,虽然好奇输出的到底是什么意思,觉得可能会不会是输出什么运行时错误信息之类的,就用ls看看目录下是否多了什么文件,可是没有出现什么异样的文件,于是也就没有再深究了。后来看Unix环境高级编程,在介绍Unix信号的时候,书上介绍了当进程收到某些信号的时候,会终止并且会core dump,又看到这个名词时也没有太理解,也就这样过去了。
今天学习用gdb调试内核时,学习了一下gdb,发现gdb是一个功能很强大的调试工具,也注意到gdb启动时会有一些选项,其中就有一个
gdb -c core
这个是调试core文件的命令,这时我就确信肯定是存在core文件的,只是我还不知道怎么生成core文件。于是搜索了一下资料,果然有所收获,原来是ulimit这个命令的限制,ulimit会限制用户各种资源的使用量,执行一下ulimit -a会输出资源限制的详细信息,如下所示:
core file size (blocks, -c) 0我们主要看第一行,core file size 被限定为0,这就是为什么没有输出core的原因。找到原因,那么就开始修改,可以执行如下的命令
ulimit -c 1024
这样当我们再用上面的命令显示时,第一行就不再是0了,不过这样修改的话,只会在此次会话中修改了可用资源的数目,如果想永久有效,可以修改/etc/profile文件,root权限下在文件里添加ulimit -c 1024,重新启动后就会永久有效了。不过这里需要注意,虽然我们设置的是1024块,但实际上当你在用户权限下和root权限下执行ulimit -c时,输出的并不是1024,程序会输出512,是你设定值的一半。
下面说一下core文件产生的原因,
1)内存访问越界;
2)多线程环境中使用了不可重入函数;
3)多线程读写的数据未加锁保护;
4)非法指针;
5)堆栈溢出;
以及不产生core文件的几种情况:
1)进程是设置-用户-ID,而且当前用户并非程序文件的所有者;
2)进程是设置-组-ID,而且当前用户并非该程序文件的组所有者;
3)用户没有写当前工作目录的许可权;
4)文件太大。core文件的许可权通常是用户读/写,组读和其他读。
core 文件默认会在当前工作目录产生,文件名一般为core.进程号,但若是程序中调用了chdir,则会在切换后的路径中产生。
用gdb调试core文件的命令是
gdb 应用程序的名称 core文件
输入bt或者where找到错误发生的位置和相应的堆栈信息,就可知道发生错误时的函数调用关系,然后可以使用up或者down查看上一条和下一条具体详细信息。这样便能对问题进行大概定位。