coredump文件是如何生成的

article/2025/10/23 13:28:13

目录

一、coredump 文件生成过程

二、coredump文件生成原理

1. 信号处理 do_signal()

2. 生成 coredump 文件

三、生产环境应该打开 coredump 功能吗?


人都会犯错,所以在编写程序时难免会出现 BUG。

有些 BUG 是业务逻辑上的错误导致的,一般不会导致程序崩溃,例如:原本要将两个数相加,但不小心把这两个数相减,而导致结果出错。这时我们可以通过在程序中,使用 printf 这类输出函数来进行打点调试。

但有些 BUG 是由于某些致命的操作而导致的,一般会导致程序崩溃,例如:访问未经申请的内存地址。由于程序会异常退出,所以一般不能通过 printf 这类输出函数进行打点调试。

另外,对于必现的 BUG (就是不管什么条件都会发生),一般可以通过 GDB 设置断点进行调试。但对于偶现的 BUG,由于在某些特定的条件下才会发生,所以比较难直接通过 GDB 进行调试。

那么,这时可以通过 Linux 提供的 coredump 文件进行调试。

一、coredump 文件生成过程

在程序发生某些错误而导致进程异常退出时,Linux 内核会根据进程当时的内存信息,生成一个 coredump 文件。而 GDB 可以通过这个 coredump 文件重现当时导致进程异常退出的场景,并且可以通过 GDB 来找到导致进程异常退出的原因。

当进程接收到某些 信号 而导致异常退出时,就会生成 coredump 文件。那么,哪些信号会导致生成 coredump 文件呢?

会导致生成 coredump 文件的信号,如下表所示:

SignalActionComment
SIGQUITCoreQuit from keyboard
SIGILLCoreIllegal Instruction
SIGABRTCoreAbort signal from abort
SIGSEGVCoreInvalid memory reference
SIGTRAPCoreTrace/breakpoint trap

下面我们通过一个例子来说明怎么生成 coredump 文件。

从上面的表格可知,当进程接收到 SIGSEGV 信号时会生成 coredump 文件。SIGSEGV 信号是当进程访问错误(未经申请)内存地址时触发的,所以下面我们编写一个访问错误内存地址的程序:

int main(int argc, char *argv[])
{char *addr = (char *)0; // 设置 addr 变量为内存地址 "0"*addr = '\0';           // 向内存地址 "0" 写入数据return 0;
}

在上面的例子中,由于内存地址 ”0“ 并没有通过调用 malloc 函数申请,所以当向地址 ”0“ 写入数据时将会导致 段错误,进程将会接收到 SIGSEGV 信号。

当进程接收到 SIGSEGV 信号后,内核将会根据进程当时的内存信息生成 coredump 文件,并且把进程杀死。

我们将上面的程序编译并且运行后,会发现程序异常退出,并且生成一个名为 core.xxx 的文件,这个文件就是 coredump 文件。如下图所示:

 

注意:

  1. 编译的时候记得加上 -g 参数表示保留调试信息,否则使用 GDB 调试时会找不到函数名或者变量名。

  2. 如果没有生成 coredump 文件的话,一般是受到资源限制,先使用命令 ulimit -c unlimited 设置资源不受限制。

coredump 文件点后面的数字是进程的 PID

现在我们只需要输入如下命令,即可使用 GDB 配合 coredump 文件来调试程序了:

$ gdb ./coredump ./core.6359

GDB 运行后会停止在发生异常的代码处,并且将发生异常的代码打印出来,如下图:

 

从上面的输出可以看到,GDB 除了会将发生异常的代码打印到终端外,还会将其所在的函数、文件名和所在文件的行数也打印出来,这样我们就很快能定位到哪行代码导致异常的。

二、coredump文件生成原理

前面介绍过,当进程接收到某些 信号 而导致异常退出时,就会生成 coredump 文件。

当进程从 内核态 返回到 用户态 前,内核会查看进程的信号队列中是否有信号没有处理,如果有就调用 do_signal 内核函数处理信号。我们可以通过下图来展示内核是怎么生成 coredump 文件的:

 

进程从内核态返回到用户态的地方有很多,如 从系统调用返回从硬中断处理程序返回 和 从进程调度程序返回 等。上图主要通过 从进程调度程序返回 作为示例,来展示内核是怎么生成 coredump 文件的。

下面我们来分析一下 coredump 文件生成过程的步骤:

1. 信号处理 do_signal()

当进程从内核态返回到用户态前,内核会查看进程的信号队列中是否有信号没有被处理,如果有就调用 do_signal 内核函数处理信号。我们来看看 do_signal 函数的实现:

static void fastcall do_signal(struct pt_regs *regs)
{siginfo_t info;int signr;struct k_sigaction ka;sigset_t *oldset;...signr = get_signal_to_deliver(&info, &ka, regs, NULL);...
}

上面代码去掉了很多与生成 coredump 文件无关的逻辑,最终我们可以看到,do_signal 函数主要调用 get_signal_to_deliver 内核函数来进行进一步的处理。

get_signal_to_deliver 内核函数的主要工作是从进程的信号队列中获取一个信号,然后根据信号的类型来进行不同的操作。我们主要关注生成 coredump 文件相关的逻辑,如下代码:

int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,struct pt_regs *regs, void *cookie)
{sigset_t *mask = &current->blocked;int signr = 0;...for (;;) {...// 1. 从进程信号队列中获取一个信号signr = dequeue_signal(current, mask, info); ...// 2. 判断是否会生成 coredump 文件的信号if (sig_kernel_coredump(signr)) {// 3. 调用 do_coredump() 函数生成 coredump 文件do_coredump((long)signr, signr, regs);}...}...
}

上面代码去掉了与生成 coredump 文件无关的逻辑,最后我们可以看到 get_signal_to_deliver 函数主要完成三个工作:

  • 调用 dequeue_signal 函数从进程的信号队列中获取一个信号。

  • 调用 sig_kernel_coredump 函数判断信号是否会生成 coredump 文件。

  • 如果信号会生成 coredump 文件,那么就调用 do_coredump 函数生成 coredump 文件。

2. 生成 coredump 文件

如果要处理的信号会触发生成 coredump 文件,那么内核就会调用 do_coredump 函数来生成 coredump 文件。do_coredump 函数的实现如下:

int do_coredump(long signr, int exit_code, struct pt_regs *regs)
{char corename[CORENAME_MAX_SIZE + 1];struct mm_struct *mm = current->mm;struct linux_binfmt *binfmt;struct inode *inode;struct file *file;int retval = 0;int fsuid = current->fsuid;int flag = 0;int ispipe = 0;binfmt = current->binfmt; // 当前进程所使用的可执行文件格式(如ELF格式)...// 1. 判断当前进程可生成的 coredump 文件大小是否受到资源限制if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)goto fail_unlock;...// 2. 生成 coredump 文件名ispipe = format_corename(corename, core_pattern, signr);...// 3. 创建 coredump 文件file = filp_open(corename, O_CREAT|2|O_NOFOLLOW|O_LARGEFILE|flag, 0600);...// 4. 把进程的内存信息写入到 coredump 文件中retval = binfmt->core_dump(signr, regs, file);fail_unlock:...return retval;
}

经过代码精简后,最终可以看到 do_coredump 函数完成四个工作:

  • 判断当前进程可生成的 coredump 文件大小是否受到资源限制。

  • 如果不受限制,那么调用 format_corename 函数生成 coredump 文件的文件名。

  • 接着调用 filp_open 函数创建 coredump 文件。

  • 最后根据当前进程所使用的可执行文件格式来选择相应的填充方法来填充 coredump 文件的内容,对于 ELF文件格式 使用的是 elf_core_dump 方法。

elf_core_dump 方法的主要工作是:把进程的内存信息和内容写入到 coredump 文件中,并且以 ELF文件格式 作为 coredump 文件的存储格式。有兴趣的可以自行阅读 elf_core_dump 方法的代码,这里就不作进一步的解说了。

三、生产环境应该打开 coredump 功能吗?

最后,我们来讨论一下在生产环境应不应该打开 coredump 功能。

笔者遇过在生产环境打开 coredump 功能而导致的事故,故事如下:

我们上线了一个有 BUG 的 WEB 服务,这个程序是以 master-worker 模式运行的。master 进程的主要工作是监控 worker 进程的运行情况,如果 worker 进程挂掉,master 进程会创建新的 worker 进程来继续工作。

由于 worker 进程的代码存在漏洞,会导致 worker 进程访问非法的内存地址而产生 SIGSEGV 信号(段错误),而 SIGSEGV 信号会触发生成 coredump 文件。

由于每次 worker 进程异常退出后,master 进程都会创建新的 worker 进程来补充,所以最终导致 worker 进程不断的异常退出和被创建。这样就不断的生成 coredump 文件,最终导致磁盘被打满。

所以,经过上面的事故,我建议大家不要在生成环境打开 coredump 功能。那么,如果程序有问题怎么排查呢?

我的建议是摘掉线上的某一台机器,打开 coredump 功能,然后模拟发生异常的情况来进行排查。如果人工比较难模拟,那么可以通过使用 tcpcopy 这些工具来把线上的流量导入到调试机器进行调试。生成 coredump 文件后,可以使用 GDB 来进行调试。


http://chatgpt.dhexx.cn/article/HfSHuVZY.shtml

相关文章

Coredump 详解

引言 当程序运行的过程中异常终止或崩溃&#xff0c;操作系统会将程序当时的内存状态记录下来&#xff0c;保存在一个文件中&#xff08;core文件&#xff09;&#xff0c;这种行为就叫做 Core Dump 或者叫做 ‘核心转储’&#xff0c;利用 coredump 可以帮助我们快速定位程序…

CoreDump追踪

当程序运行的过程中异常终止或崩溃&#xff0c;操作系统会将程序当时的内存状态记录下来&#xff0c;保存在一个文件中&#xff0c;这种行为就叫做Core Dump&#xff08;中文有的翻译成“核心转储”)。我们可以认为 core dump是“内存快照”&#xff0c;但实际上&#xff0c;除…

coredump详解

原文地址&#xff1a;https://blog.51cto.com/u_15471709/4868198 一&#xff0c;什么是coredump 我们经常听到大家说到程序core掉了&#xff0c;需要定位解决&#xff0c;这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止&#xff0c;并且在满…

linux之fping命令

fping检测主机是否存在,fping命令 fping类似于ping&#xff0c;但比ping强大。与ping要等待某一主机连接超时或发回反馈信息不同&#xff0c;fping给一个主机发送完数据包后&#xff0c;马上给下一个主机发送数据包&#xff0c;实现多主机同时ping&#xff0c;fping还可以在命令…

linux fping参数,linux下,fping命令与ping命令解析

ping Linux系统的ping命令是常用的网络命令&#xff0c;它通常用来测试与目标主机的连通性。 1.命令格式&#xff1a; ping [参数] [主机名或IP地址] 2.命令功能&#xff1a; ping命令用于&#xff1a;确定网络和各外部主机的状态&#xff1b;跟踪和隔离硬件和软件问题&#xf…

php fping,【Linux 命令】fping ping 包间隔时间详解

服务器间检查会用到fping的命令,期间遇到了一个问题,需要将ping包间的间隔时间设置为100毫秒,查看fping -h看下,找到了-i和-p两个参数: 看到这两个参数,我当时的表情是这样的: 看不懂,那就测吧: 先来-i: 间隔1s,没有生效.! 再试试-p OK,这个生效了,但-i 和-p的区别是…

fping使用

【-4】-ipv4仅PING IPv4地址 【-6】-ipv6仅PING IPv6地址 【-b】 指定数据&#xff0c;以字节发送&#xff08;默认值&#xff1a;56&#xff09; 【-c】指定发送的数量 【-f】读取一个文件里面的ip 【-g】扫描一个c段 【--ttl】设置ttl值 当这是为ttl1时&#xff0c;未检测到1…

linux yum fping,ping fping

通过ping来监测对端网络状态 ping fpinf在windows和linux上的参数是不同的&#xff0c;返回的结果也是不同的 在网络连通性监测方面用的比较多&#xff0c;在py go中调用命令&#xff0c;对返回的结果使用正则来在文本中挑出所需要的数据信息 windows中的ping参数 fping fping只…

【kali-2021.1】FPING—参数中文版(上)

目录 FPINGFPING是什么命令格式Fping用法选项介绍中文版示例1.不带选项2.设置数据包大小&#xff08;1&#xff09;默认情况下&#xff08;2&#xff09;在使用-b参数情况下 3.指定发送ping次数4.通过IP或DNS返回主机名5.通过文件获取目标6.一次ping多个目标7.设置TTL值8.指定网…

入侵检测——fping(扫描篇)

目录 环境介绍参数数据包参照组数据包&#xff08;使用ping命令&#xff09;windows下使用cmd发出的ping包kali在终端中发出的ping包 fping发出的数据包单个主机扫描&#xff08;无回应&#xff09;单个主机扫描&#xff08;有回应&#xff09;网段扫描 规则 环境介绍 NAT模式…

Linux C/C++ fping命令(检查主机是否存在)

ping基本上是验证网络连接的最简单工具。我们可以验证专用或公共网络中任意两个设备之间的连接。但是今天我们要讲的是fping&#xff0c;因为fping是一个类似ping的程序&#xff0c;它使用Internet控制消息协议&#xff08;ICMP&#xff09;回显请求来确定目标主机是否正在响应…

DeepLabV1网络简析

原论文名称&#xff1a;Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs 论文下载地址&#xff1a;https://arxiv.org/abs/1412.7062 参考源码&#xff1a;https://github.com/TheLegendAli/DeepLab-Context 讲解视频&#xff1a; https:…

DeepLab v3+原理和实现

这节课讲DeepLabv3模型&#xff0c;及前身DeepLabv3模型&#xff0c;两篇论文来自Google的同一个团队。 参考资料 DeepLabv3&#xff0c;被引1000 DeepLabv3&#xff0c;被引1000 Pytorch DeepLabv3实现&#xff0c;Star 1.5k 我们讲1.模型原理2.代码实现 from PIL import Im…

deeplabcut使用

cuda11.2和cudnn8.1安装 win 最新的 Win11/WIN10 安装CUDA11.2和cuDNNlinux ubuntu 16.04 安装 cuda11.2 和cudnn8.2.1 dlc安装 创建虚拟环境 安装deeplabcut2.2.3 tensorflow2.11.0 wxPython4.0.4 pip install deeplabcut2.2.3 deeplabcut里面包含了tensorflow的不用再安…

MATLAB与深度学习(一)— Deep Learning Toolbox

MATLAB与深度学习&#xff08;一&#xff09;— Deep Learning Toolbox 最近&#xff0c;我在学习基于matlab的深度学习的内容&#xff0c;并整理出如下学习笔记。本文借鉴和引用了网上许多前辈的经验和代码&#xff0c;如有冒犯&#xff0c;请及时与我联系。 1. MATLAB与深度…

Deeplab V1 和 V2讲解

Deeplab V1 Background&#xff1a; CNN的一个特性是invariance&#xff08;不变性&#xff09;&#xff0c;这个特性使得它在high-level的计算机视觉任务比如classification中&#xff0c;取得很好的效果。但是在semantic segmentation任务中&#xff0c;这个特性反而是个障…

deeplab v3+ 源码详解

训练模型&#xff1a; 下载好voc数据集&#xff0c;并传入所需的参数即可进行训练。 参数配置&#xff1a; """ 训练&#xff1a; --model deeplabv3plus_mobilenet --gpu_id 0 --year 2012_aug --crop_val --lr 0.01 --crop_size 513 --batch_size 4 --…

Deeplabcut教程(二)使用

因为很久没用这个了所以就一直没更使用教程&#xff0c;写的安装教程收到好几条私信要使用教程&#xff0c;这几天在帮一个朋友跑这个&#xff0c;于是就有了这个使用教程 安装教程&#xff1a;Deeplabcut教程&#xff08;一&#xff09;安装&#xff08;GPU&CPU版本&…

概述DeepLab系列(deeplab v1, deeplab v2, deeplab v3, deeplab v3+)

前言&#xff1a;图像分割是指像素级别的图像识别&#xff0c;即标注出图像中每个像素所属的对象类别。 语义分割更注重类别之间的区分&#xff0c;而实例分割更注重个体之间的区别。 DeepLab是由Google团队提出的一系列图像分割算法。 DeepLab v1 &#xff08;2014年&#xf…

DeepLab系列理解

原文Blog&#xff1a;https://zhuanlan.zhihu.com/p/61208558 1、deeplab v1 针对标准的深度卷积神经网络的两个主要问题&#xff1a;1.Striding操作使得输出尺寸减小&#xff1b; 2.Pooling对输入小变化的不变性&#xff0c;v1 使用空洞卷积(atrous)条件随机场(CRFs)来解决这…