Linux关闭核心转储不生效原因简单分析

0x00 发生了什么

最近 杨海象 负责开发的某平台上线,效果不错,但是在使用期间出现了核心转储,占用了大量磁盘空间,如下图,可见,近1T。
在这里插入图片描述平台上线当天杨海象和老王尝试关闭核心转储,执行了命令

ulimit -c 0

核心仍然继续生成。虽然磁盘空间够用,且平台运行正常,但是这个问题找不到原因,且无法解决核心一直产生的问题。头疼,终于,他来了,他带着一杯7分甜的奶茶来找我了。

0x01 什么是核心转储

百度百科解释的还不错,我稍微修改一点:
在UNIX系统中,常将“主内存”(main memory) 称为核心(core),因为在上世纪,计算机还没使用半导体作为内存材料之前,内存的实现便是使用的核心(core)。而核心映像(core image) 就是 内存中的“进程”(process)当前正在执行的内容。当进程发生错误或意外收到指定“信号”(signal) 而终止执行时,系统会将核心映像写入一个文件,以供开发人员跟踪调试错误之用。这就是所谓的核心转储(core dump)。

核心转储简单解释就是当一个程序崩溃时,在该进程当前工作目录的core文件中复制了该进程的存储图像。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。

0x02 核心转储产生的原因及相关知识

1.进程收到特定信号指令而终止1,便会核心转储。
部分信号(核心转储)说明:

符号常量说明缺省动作
SIGABRT非正常终止信号终止w/core
SIGBUS获取内存中不确定的部分终止w/core
SIGEMT硬件故障终止w/core
SIGFPE算术异常终止w/core
SIGILL无效硬件信号的检测终止w/core
SIGIOT硬件故障终止w/core
SIGQUIT交互式终止信号终止w/core
SIGSEGV无效内存引用检测信号终止w/core
SIGSYS无效系统调用终止w/core
SIGTRAP软中断终止w/core
SIGXCPU超过CPU限制(setrlimit)终止w/core
SIGXFSZ超过文件长度限制(setrlimit)终止w/core

2.POSIX标准
可移植操作系统界面(Portable Operating System Interface,POSIX),是IEEE为运行在UNIX系统上的程序而定义的一系列互相关联的API标准的总称。POSIX这个名称基本上是Portable Operating System Interface(可移植操作系统接口)的缩写,而X则表明其对Unix API的传承。
由于以前各应用开发厂商自己玩自己的C语言,互相之间不兼容,于是出现了该标准,统一了C语言语法等,同时规定了所有信号常量及对应值。
(根据记忆写的,如果说错了的话就评论告诉我吧,我把这段删了)

3.信号
懒得写了,可以阅读<signal.h>头文件,它声明了sigset_t类型和sigaction结构。定义了三类信号:
(1)必需的信号;
(2)任务控制信号;
(3)内存保护信号。
略了。。。

0x03 核心转储复现

1.编写demo程序制造核心转储
在这里插入图片描述
2.查看当前ulimit的设置,并开启核心转储
执行命令

ulimit -a

查看配置情况,根据输出信息对ulimit进行设置操作:

ulimit -c unlimited

将核心转储文件的大小设置为无限大,即开启核心转储
在这里插入图片描述
3.编译并执行demo,复现核心转储
在这里插入图片描述
执行demo,核心文件自动转储到当前工作目录
在这里插入图片描述

4.调试core文件,追踪调用栈,分析错误点及错误原因
在这里插入图片描述可以看到错误发生在null_ptr()函数中,在文件第14行,错误原因是信号SIGSEGV。产生信号SIGSEGV的可能原因是数组越界,空指针解引用等。

0x04 修改ulimit配置不生效问题分析

1.情景分析
平台上线,使用时,生成了大量内核转储文件,但平台运行正常,老王和杨海象担心磁盘被占满,所以决定先关闭内核转储。
执行
ulimit -c 0
再查看
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) 63157
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63157
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

可是发现仍有核心文件在转储。持续在生成。直到活动结束,平台未出现崩溃,因此该问题未当天处理完。

2.问题分析
由于核心转储文件生成的时候是用的pid做后缀,不知道崩溃的是哪个进程/线程。但是根据file的提示信息知道具体是哪个进程/线程崩溃:
在这里插入图片描述这里给的图是测试demo,分析了生产环境产生的核心转储,知道了是哪个进程,老王告诉我这个进程是由守护进程拉起的,也存在主动kill的情况。ok,大胆猜测一下核心转储产生的原因可能就是主动kill,一会儿去gdb看看,先分析下为什么设置了
ulimit -c 0
却仍核心转储。
是否是由于崩溃进程不是终端shell拉起(进程),而是作为一个线程执行的。
3.问题复现
编写python起线程验证上述猜想:
在这里插入图片描述demo编写完成后,先确认环境:
(1)关闭核心转储;
在这里插入图片描述

(2)验证是否关闭。
在这里插入图片描述
环境确认无误后,运行demo验证猜想
在这里插入图片描述

转储文件未生成,猜想错误。继续分析和猜想。
首先分析ulimit命令,这个命令事shell内置的命令,所以是否和shell有关?那开始验证:
新开一个shell,cd到同目录,查看ulimit属性,两个终端的ulimit属性配置不同(file size),如下图:
在这里插入图片描述
则先在file size = 0的终端(右)上先运行python demo,发现未生成核心转储;同时在终端(右)demo结束前,让file size = unlimited的终端(左)运行demo,发现核心转储了,说明核心转储的配置属性与当前终端相关。
在这里插入图片描述

0x05 总结

1.问题原因
阿西吧,终于搞清楚了。ulimit命令设置的是当前终端的属性,要想全局修改,则需要修改以下两个文件中的一个2

/proc/sys/kernel/core_pattern
/proc/sys/kernel/core_uses_pid

有个小坑,就是这俩文件需要root权限修改,且vi不能修改该文件,可以使用nano或者echo重定向。

2.解决办法
修改ulimit配置,使所有核心转储保存到 /dev/null

echo "/dev/null/core.%p"  > /proc/sys/kernel/core_pattern

下班,回家,喂狗,睡觉。


  1. 参考自: http://www.mamicode.com/info-detail-1355384.html ↩︎

  2. 参考自: https://blog.csdn.net/phmatthaus/article/details/107182265 ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值