linux 清空正在高速写的文件,不修改指针,Linux关闭核心转储不生效原因简单分析...

0x00 发生了什么

最近 杨海象 负责开发的某平台上线,效果不错,但是在使用期间出现了核心转储,占用了大量磁盘空间,如下图,可见,近1T。

9964649a14b7cf5fb72e12ba9be7cdf1.png平台上线当天杨海象和老王尝试关闭核心转储,执行了命令

ulimit -c 0

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

0x01 什么是核心转储

百度百科解释的还不错,我稍微修改一点:

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

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

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

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.信号

懒得写了,可以阅读头文件,它声明了sigset_t类型和sigaction结构。定义了三类信号:

(1)必需的信号;

(2)任务控制信号;

(3)内存保护信号。

略了。。。

0x03 核心转储复现

1.编写demo程序制造核心转储

8ae354a7193b1153022e9112a22c1d23.png

2.查看当前ulimit的设置,并开启核心转储

执行命令

ulimit -a

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

ulimit -c unlimited

将核心转储文件的大小设置为无限大,即开启核心转储

593c9d5e61412af6638c12b72c814004.png

3.编译并执行demo,复现核心转储

3df82b6efe09f435379f3de8b0bfd89f.png

执行demo,核心文件自动转储到当前工作目录

feb47aff39b2ee10f18b803144e99f35.png

4.调试core文件,追踪调用栈,分析错误点及错误原因

5b2aa1b4593c693edc53641d1f5b26a5.png可以看到错误发生在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的提示信息知道具体是哪个进程/线程崩溃:

d9be9fbab6170f45c87e9fc7e5e87874.png这里给的图是测试demo,分析了生产环境产生的核心转储,知道了是哪个进程,老王告诉我这个进程是由守护进程拉起的,也存在主动kill的情况。ok,大胆猜测一下核心转储产生的原因可能就是主动kill,一会儿去gdb看看,先分析下为什么设置了

ulimit -c 0

却仍核心转储。

是否是由于崩溃进程不是终端shell拉起(进程),而是作为一个线程执行的。

3.问题复现

编写python起线程验证上述猜想:

2ee011c3db5c42fe6e52d6f0152e2ecd.pngdemo编写完成后,先确认环境:

(1)关闭核心转储;

620a5881395ddd3def6e582f58e7f427.png

(2)验证是否关闭。

07f8790d723580f81b5270e6da90c388.png

环境确认无误后,运行demo验证猜想

0fb5b65e36e3ab9fbc6c87919a22f229.png

转储文件未生成,猜想错误。继续分析和猜想。

首先分析ulimit命令,这个命令事shell内置的命令,所以是否和shell有关?那开始验证:

新开一个shell,cd到同目录,查看ulimit属性,两个终端的ulimit属性配置不同(file size),如下图:

cdb7201fbd1477fe7ee07a00a0206a09.png

则先在file size = 0的终端(右)上先运行python demo,发现未生成核心转储;同时在终端(右)demo结束前,让file size = unlimited的终端(左)运行demo,发现核心转储了,说明核心转储的配置属性与当前终端相关。

02e175b224715f909762f4dbc7bdb7a3.png

0x05 总结

1.问题原因

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

/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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值