gdb 提示 coredump 文件 truncated 问题排查

本文深入分析了一种特殊的CoreDump Truncate问题,探讨了问题的排查思路,使用调试工具和阅读内核源代码,揭示了问题的根本原因在于CoreDump进程被SIGKILL信号中断,导致VMA数据写入不完全。

本文选自“字节跳动基础架构实践”系列文章。

“字节跳动基础架构实践”系列文章是由字节跳动基础架构部门各技术团队及专家倾力打造的技术干货内容,和大家分享团队在基础架构发展和演进过程中的实践经验与教训,与各位技术同学一起交流成长。

coredump 我们日常开发中经常会遇到,能够帮助我们辅助定位问题,但如果 coredump 出现 truncate 会给排查问题带来不便。本文以线上问题为例,借助这个Case我们深入了解一下这类问题的排查思路,以及如何使用一些调试工具、阅读内核源代码,更清晰地了解coredump的处理过程。希望能为大家在排查这类问题的时候,提供一个清晰的脉络。

问题背景

在 c/cpp 类的程序开发中进程遇到 coredump,偶尔会遇到 coredump truncate 问题,影响 core 后的问题排查。coredump truncate 大部分是由于 core limits 和剩余磁盘空间引发的。这种比较好排查和解决。今天我们要分析的一种特殊的 case。

借助这个 Case 我们深入了解一下这类问题的排查思路,使用一些调试工具和阅读内核源代码能更清晰的了解 coredump 的处理过程。能够在排查这类问题的时候有个清晰的脉络。

业务同学反馈在容器内的服务出 core 后 gdb 调试报错。业务的服务运行在 K8S+Docker 的环境下,服务在容器内最终由 system 托管。在部分机器上的 coredump 文件在 gdb 的时候出现如下警告,导致排查问题受影响。报错信息如下:

BFD: Warning: /tmp/coredump.1582242674.3907019.dp-b9870a84ea
-867bccccdd-5hb7h is truncated: expected core file size >= 
89036038144, found: 31395205120.

导致的结果是 gdb 无法继续调试。我们登录机器后排查不是磁盘空间和 core ulimit 的问题。需要进一步排查。

名词约定

GDB:UNIX 及 UNIX-like 下的二进制调试工具。

Coredump: 核心转储,是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件。这种信息往往用于调试。

ELF: 可执行与可链接格式(Executable and Linkable Format),用于可执行文件、目标文件、共享库和核心转储的标准文件格式。x86 架构上的类 Unix 操作系统的二进制文件格式标准。

BFD: 二进制文件描述库(Binary File Descriptor library)是 GNU 项目用于解决不同格式的目标文件的可移植性的主要机制。

VMA: 虚拟内存区域(Virtual Memory Area),VMA 是用户进程里的一段 virtual address space 区块,内核使用 VMA 来跟踪进程的内存映射。

排查过程

用户态排查

开始怀疑是自研的 coredump handler 程序有问题。于是还原系统原本的 coredump。

手动触发一次 Coredump。结果问题依然存在。现在排除 coredump handler 的问题。说明问题可能发生在 kernel 层或 gdb 的问题。

需要确定是 gdb 问题还是 kernel 吐 core 的问题。先从 gdb 开始查起,下载 gdb 的源代码找到报错的位置(为了方便阅读,源代码的缩进进行了调整)。

目前看不是 gdb 的问题。coredump 文件写入不完整。coredump 的写入是由内核完成的。需要从内核侧排查。

在排查之前观察这个 coredump 的程序使用的内存使用非常大,几十 G 规模。怀疑是否和其过大有关,于是做一个实验。写一个 50G 内存的程序模拟,并对其 coredump。

#include <unistd.h>
#include <stdlib.h>
#include <string.h>


int main(void){
        for( int i=0; i<1024; i++ ){
                void* test = malloc(1024*1024*50); // 50MB
                memset(test, 0, 1);
        }
        sleep(3600);
}

经过测试正常吐 core。gdb 正常,暂时排除 core 大体积问题。

所以初步判断是 kernel 在吐的 core 文件自身的问题。需要在进一步跟进。

查看内核代码发现一处可疑点:

/*
 * Ensures that file size is big enough to contain the current file
 * postion. This prevents gdb from complaining about a truncated file
 * if the last "write" to the file was dump_skip.
 */
void dump_truncate(struct coredump_params *cprm)
{
    struct file *file = cprm->file;
    loff_t offset;


    if (file->f_op->llseek && file->f_op->l
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值