Linux 下如何产生core文件(core dump设置)

转自:https://blog.csdn.net/star_xiong/article/details/43529637

  

  今天在Linux下调试C程序时,出现段错误,习惯性的ls下当前目录,发现没有生成core文件。惊讶了一下,怎么回事?以前都会产生的啊,难不成是程序的问题?后来同事提醒是不是系统没有打开生成core dump的设置。

还真是系统设置问题,我的ubuntu14.04是新装的,之前没有进行过core dump的相关配置,别急!我们来看看怎么对linux系统设置当程序出现段错误时产生core文件:

1、先用#ulimit -a可以查看系统core文件的大小限制(第一行),core文件大小设置为0, 即没有打开core dump设置;

root@XZX:~/cnnic/project/dnsx/dnsX# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 46621
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 46621
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

2、接下来使用#ulimit -c [kbytes]可以设置系统允许生成的core文件大小;
ulimit -c 0 不产生core文件
ulimit -c 100 设置core文件最大为100k
ulimit -c unlimited 不限制core文件大小

执行#ulimit -c unlimited,然后#ulimit -a查看结果如下(第一行):

root@XZX:~/cnnic/project/dnsx/dnsX# ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 46621
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 46621
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

此时,core dump设置打开了,再执行程序出现段错误时,在当前工作目录下产生了core文件,然后我们就可以用gdb调试core文件了。

 例如:

#gdb ./test core.2065

注:Linux下的C程序常常会因为内存访问错误等原因造成segment fault(段错误),此时如果系统core dump功能是打开的,那么将会有内存映像转储到硬盘上来,之后可以用gdb对core文件进行分析,还原系统发生段错误时刻的堆栈情况。这对于我们发现程序bug很有帮助。

很多系统默认的core文件大小都是0,我们可以通过在shell的启动脚本/etc/bashrc或者~/.bashrc等地方来加入 ulimit -c 命令来指定core文件大小,从而确保core文件能够生成。
除此之外,还可以在/proc/sys/kernel/core_pattern里设置core文件的文件名模板,详情请看core的官方man手册。


    需要说明的是:上述方法只是在当前shell中生效,重启之后,就不再有效了。永久生效的办法是如下:

永久生效办法:

       #vi /etc/profile 然后,在profile中添加:

ulimit -c 1073741824

  (但是,若将产生的转储文件大小大于该数字时,将不会产生转储文件)

或者

  ulimit -c unlimited

这样重启机器后生效了。 或者, 使用source命令使之马上生效。

   #source /etc/profile

三、指定内核转储的文件名和目录

        修改完内核转储设置后,当程序core dump后发现确实在本地目录产生了core文件,但是如果程序多次core dump时,core文件会被覆盖,原因是每次core dump后生成的文件名默认都叫core,接下来就分享下如果想在每次core dum时产生的core文件都带上进程号怎么操作,或者你想把内核转储文件保存到其他目录怎么办?

1、core dump文件名自动加上进程ID

    #echo 1 > /proc/sys/kernel/core_uses_pid

最后生成的core dump文件名会加上进程ID.

2、另外可以通过修改kernel的参数,指定内核转储所生成的core文件的路径和文件名。

       可以通过在/etc/sysctl.conf文件中,对sysctl变量kernel.core_pattern的设置。

       #vim /etc/sysctl.conf 然后,在sysctl.conf文件中添加下面两句话:

               kernel.core_pattern = /var/core/core_%e_%p

               kernel.core_uses_pid = 0

       保存后退出。

 注:如果/proc/sys/kernel/core_uses_pid 这个文件的内容被配置成1,即使core_pattern中没有设置%p,最后生成的core dump文件名仍会加上进程ID。

这里%e, %p分别表示:

%c 转储文件的大小上限

%e 所dump的文件名

%g 所dump的进程的实际组ID

%h 主机名

%p 所dump的进程PID

%s 导致本次coredump的信号

%t 转储时刻(由1970年1月1日起计的秒数)

%u 所dump进程的实际用户ID

可以使用以下命令,使修改结果马上生效。

#sysctl –p /etc/sysctl.conf

请在/var目录下先建立core文件夹,然后执行a.out程序,就会在/var/core/下产生以指定格式命名的内核转储文件。查看转储文件的情况:

#ls /var/core

core_a.out_2456

四、Ubuntu16.04 无法产生 core dumped 文件

不产生core文件的原因,最近在用gdb调试时,故意让一个进程core dump,但是却没有产生core文件,解决过程如下:

1. 首先考虑了系统限制问题,shell键入

ulimit -a
查看core文件有没有限制大小,发现没有,是unlimited,所以不是这个原因
(如果大小为0,说明禁止了core文件的产生,可以通过 ulimit -c unlimited 来解除限制)

2. 其次考虑是不是程序实现和权限方面的问题

查阅资料,总结不产生core的相关情况如下:
1.程序设置了用户id(即调用setuid),但当前用户并非该程序文件的所有者
2.程序设置了组id(即调用setgid),但当前用户并非该程序文件的组所有者
3.用户没有当前目录或指定core文件产生目录的写权限
4.core文件太大,磁盘空间不足

但以上并没有解决我的问题

3. 考虑core文件产生位置

core的缺省位置是程序所在目录,可以通过修改/proc/sys/kernel/core_pattern来指定core文件生成位置了名称。
 通过查看core_pattern文件,发现其确实指定了一个路径,于是我前往那个路径,发现竟然是脚本程序,后来查看说明文件,才知道core_pattern中如果首先指定了一个 ‘|’ 管道符,则会将生成的core文件传递给后面所跟的脚本去处理。
 至此,也就确定了问题的原因,| 管道符后面的脚本将我们的core文件给吞了,解决方法自然就是去掉这个脚本,换成自己指定的目录
 但直接去修改core_pattern文件并没有成功,保存时会提示FSync错误,查阅资料得知,这个文件有特殊限制,只能通过命令:
1 sudo bash -c "echo 这里是写入内容 > /proc/sys/kernel/core_pattern "

例如:

1 sudo bash -c "echo /home/xxx/core.%e > /proc/sys/kernel/core_pattern "

来进行写入,即指定程序所在目录为core文件生成目录,core文件名称为"core +可执行文件名字"。

之后再运行程序,core dump后,即在当前程序文件目录下生成了core文件。

 

=============================================================================================

更详细的内容或手动强制某个进程产生core dump的方法见链接:http://blog.csdn.net/wj_j2ee/article/details/7161586

帮助链接:http://www.cppblog.com/API/archive/2012/10/22/193644.html

参考文章:

https://blog.csdn.net/qq_35621436/article/details/120870746?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2.pc_relevant_default

 

posted @ 2019-07-01 16:40  西门吹雪~~~  阅读(20883)  评论(0编辑  收藏  举报