在编程过程中,我们可能常常遇到程序可以通过编译, 但在运行时出现Segment fault(段错误)。 产生段错误就是访问了错误的内存段。
产生段错误时,并不像编译错误一样会提示到文件的某一行, 而是没有任何信息, 这使得我们的调试变得困难起来,特别是代码量比较大的时候,单步调试很麻烦。这时段错误转储的core文件就派上用场了。
如果想让系统在信号中断造成的错误时产生core文件, 我们需要在shell中按如下设置:
#设置core大小为无限
ulimit -c unlimited
#设置文件大小为无限
ulimit unlimited
以上设置仅本次有效,下次重启需要重新设置。
下面修改/etc/sysctl.conf文件,对产生的core文件进行配置:
在文件末尾添加下面一行
kernel.core_pattern=/tmp/core-%e
并修改kernel.core_uses_pid = 1 为
kernel.core_uses_pid = 0 这样core文件的格式就是
core-可执行文件的名字,这里我把进程号去掉了,觉得进程号在此处没多大用处。文件所在目录为/tmp下,也可以自己修改为可执行文件所在目录,这样比较直观。
然后运行命令:
sysctl -p /etc/sysctl.conf
假设将其值改变为:”/home/duanbei/corefile/core-%e-%p-%t”, 那么所有的core文件将保存在”/home/duanbei/corefile”目录下,文件名格式为“core-程序名-pid-时间戳”
下面我们将通过一个例子来说明core文件的使用。
首先编写一份错误的代码:
#include<iostream>
using namespace std;
void dummy_function()
{
unsigned char* ptr = 0x00; //试图访问地址0x00
*ptr = 0x00;
}
int main()
{
dummy_function();
return 0;
}
编译运行产生coredump:
$ g++ -g -o test test.cpp
$ ./test
段错误 (核心已转储)
发生core dump之后, 可以用gdb查看core文件的内容, 以定位文件中引发core dump的行,其格式如下:
gdb [exec file] [core file]
如:
gdb ./test test.core
在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行.
$ gdb ./test core
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...done.
[New LWP 3621]
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0804858d in dummy_function () at test.cpp:14
14 *ptr = 0x00;
上面显示了core dump的地方。
(gdb) bt //显示函数调用堆栈,显然是main函数调用dummy_function函数
#0 0x0804858d in dummy_function () at test.cpp:14
#1 0x0804859a in main () at test.cpp:19
(gdb) f 1 //打印栈号为1的堆栈,显示main函数是怎么调用dummy_function函数,f的全名为frame
#1 0x0804859a in main () at test.cpp:19
19 dummy_function();
以上就是core dump的一个简单的使用~
(今天面试被问到了=。=之前没用过,没答上来!所以回来学习学习~)