三尺非寒 发表于 2024-6-19 15:19:02

具体分析Linux中的core dump异常(附 Demo排查)

1. 基本知识

Core dump 是指在程序异常终止时,操纵系统将程序的内存映像保存到磁盘上的一种机制。
在 Linux 系统中,core dump 提供了一种调试程序错误的重要方式,它记录了程序在崩溃时的内存状态,可以帮助开发职员定位问题
常见的 core dump 错误通常是程序在运行过程中发生了严重的错误或异常,导致操纵系统强制终止了程序并生成了 core dump 文件。以下是一些常见的导致 core dump 的错误:


[*]段错误(Segmentation fault):
程序访问了无效的内存地址,比如试图访问未分配的内存或者已经释放的内存
[*]空指针引用(Null pointer dereference):
程序试图利用空指针(null pointer)访问内存中的数据时,会导致空指针引用错误
[*]内存访问越界(Out of bounds memory access):
程序试图访问数组或者其他数据布局超出其界限范围的内存,就会发生内存访问越界错误
[*]利用已释放的内存(Use after free):
程序试图在已经释放的内存地址上进行读取或写入操纵时,就会发生利用已释放的内存错误
[*]栈溢出(Stack overflow):
程序递归调用层数过深或者在栈上分配了过多的内存时,会导致栈溢堕落误
[*]除以零(Division by zero)
[*]无效的指令或操纵码(Invalid instruction or opcode):
执行了不存在或无效的机器指令或操纵码,会导致无效指令错误
[*]硬件故障或操纵系统错误:如内存破坏、内核崩溃等环境
2. 进阶知识

一、怎么生成 core dump?
利用 ulimit 命令来控制生成 core dump 的条件,比如通过 ulimit -c unlimited 命令来设置允许生成任意巨细的 core dump
先查看系統默认:ulimit -c 命令用于表现当前用户的 core dump 文件的巨细限定。输出结果的含义如下:


[*]数字(以 KB 为单位),表示当前用户允许生成的 core dump 文件的最大巨细限定
[*]unlimited,表示当前用户允许生成任意巨细的 core dump 文件
[*]0,表示当前用户不允许生成 core dump 文件
截图如下:
https://img-blog.csdnimg.cn/direct/f2fd47ce260a40dbac94fd2fcc63bd44.jpeg
核心转储文件的巨细通常受到操纵系统或系统管理员设置的限定,可以利用 ulimit 命令来调整生成 core dump 文件的最大巨细
二、core文件含义以及相关参数?


[*]程序崩溃时生成的二进制文件,其中包含了程序崩溃时的内存映像,以及当前的寄存器状态等信息
[*]一样平常存储在当前工作目次下,文件名通常为 core 或者 core.<pid>,其中 <pid> 是崩溃程序的进程 ID
相关的设置参数如下:
修改 /proc/sys/kernel/core_pattern 文件来设置 core dump 文件的生成路径和文件名格式
通过 ulimit -c 命令来设置 core 文件的最大巨细限定
三、怎样分析core dump文件?
利用 GNU Debugger (GDB) 等调试工具来分析 core dump 文件。通过加载 core 文件和对应的可执行文件,可以获取崩溃时的堆栈跟踪、变量值等信息,帮助定位程序错误
利用 gdb <executable> <corefile> 命令来加载可执行文件和 core 文件,并进入 GDB 调试环境
3. Demo

要排查 core dump,通常需要分析 core 文件以及程序的源代码。以下是排查 core dump 的一样平常步调:

[*]获取 core 文件:
程序发生 core dump 时,会在当前工作目次下生成一个 core 文件(除非已经设置了不同的路径)。首先要做的是获取这个 core 文件
[*]分析 core 文件:
利用 GDB 命令查看堆栈跟踪、变量值等信息,从而确定程序崩溃的位置和缘故原由
[*]定位问题:
根据分析结果,确定程序崩溃的具体缘故原由()内存访问错误、空指针引用、数据布局破坏等)
分析代码,找出导致错误的代码段。
[*]修复问题:
根据定位到的问题,修改程序代码以修复错误(涉及到修复内存管理错误、增加错误查抄和处置惩罚逻辑等)
[*]测试和验证:
各种测试技术,如单元测试、集成测试等,以确保程序的稳固性和可靠性
下面是一个简朴的示例,演示怎样排查一个导致 core dump 的 C 程序:
#include <stdio.h>

void cause_crash() {
    char *ptr = NULL;
    *ptr = 'A';// 尝试在空指针上进行写操作,导致段错误
}

int main() {
    cause_crash();
    return 0;
}

[*] 编译该程序:gcc -o demo demo.c
[*] 执行程序,会触发 core dump:./demo
[*] 利用 GDB 分析 core 文件:gdb ./demo core
[*] 在 GDB 中可以利用命令 bt 查看堆栈跟踪:
(gdb) bt
#00x00005555555546e8 in cause_crash () at demo.c:6
#10x0000555555554701 in main () at demo.c:11
通太过析堆栈跟踪,可以发现问题出如今 cause_crash 函数的第 6 行,即空指针引用导致了段错误。在这个示例中,问题相对简朴,修复方法可能是在写操纵前添加对指针的空指针查抄
4. 彩蛋

无法生成一个core-dump文件,有好些缘故原由
https://img-blog.csdnimg.cn/direct/4e3f84b5e6c249d1aecbad8afca77573.png
一开始以为是被限定的文件巨细或者不让他输出导致
查看core file size的巨细
https://img-blog.csdnimg.cn/direct/561f54f20fe549d983abd02bfa7fa112.png
此处更改为无穷制看看
https://img-blog.csdnimg.cn/direct/8bd61186579346b095cc5405aedbd0bc.png
后续发现此类问题尚有一种缘故原由:(挂载点的内存无可用,导致不停写入不进)
保举阅读:【Linux】具体分析/dev/loop的基本知识 | 空间满了的办理方法

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 具体分析Linux中的core dump异常(附 Demo排查)