百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Linux Core Dump 解析

toyiye 2024-06-21 11:57 15 浏览 0 评论

通常,在日常的应用系统维护活动中,有这样一种场景:在某一特定的时间段或者流量高峰时刻,我们的应用程序突然无缘无故地挂掉,没有任何征兆(当然,可能更为细致的监控没有检测到),也没有任何应用层面的日志抛出,然而,业务已经开始保障(我艹,怎么又不行了,某些所谓的 XX 开始叫了。。。),顿时,大伙一脸懵逼 。。。经过对所有可疑的文件依据时间段进行“查水表”,终于有所发现。

何为 “Core Dump” 文件 ?

Core Dump 也称之为“核心转储”, 若当前操作系统开启了 core dump ,当程序运行过程中发生异常或接收到某些信号使得程序进程异常退出时, 由操作系统把程序当前的内存状况以及相关的进程状态信息存储在一个 Core 文件中, 即 Core Dump 。通常,Linux 中如果内存越界会收到 SIGSEGV 信号,然后就会进行 Core Dump 相关操作。

在我们大部分人的认知中,潜意识地认为 Core Dump 是针对 Linux 内存快照。其实,从本质上来讲,Core Dump 文件不仅仅包含内存信息,譬如,还有些关键的程序运行状态也会同时 Dump 下来,例如,寄存器信息(包括程序指针、栈指针等)、内存管理信息、相关处理器信息以及操作系统状态及相关信息。Core Dump 对于技术人员,尤其是运维、开发,对其诊断和调试程序是非常有帮助的,毕竟,对于有些程序错误是很难重现的,例如,指针异常,然而,借助于 Core Dump 文件我们可以再一次模拟、重现应用程序抛异常时的情景。

为什么会发生 “Core Dump” ?

Linux 系统中在应用程序运行过程中经常会遇到程序突然崩溃,提示:Segmentation fault,这是因为应用程序收到了 SIGSEGV 信号。这个信号提示当进程发生了无效的存储访问,当接收到这个信号时,缺省动作是:终止w/core。终止w/core的含义是:在进程当前目录生成 Core文件,并将进程的内存映象复制到 Core 文件中,Core 文件的默认名称就是 “Core”。事实上,并不是只有 SIGSEGV 信号产生 CoreDump,还有下面一些信号也产生 CoreDump:SIGABRT(异常终止)、SIGBUS(硬件故障)、SIGEMT(硬件故障)、SIGFPE(算术异常)、SIGILL(非法硬件指令)、SIGIOT(硬件故障),SIGQUIT,SIGSYS(无效系统调用),SIGTRAP(硬件故障)等。

“Core Dump” 文件场景 ?

在基于 Linux 系统,应用程序发生异常时,会产生 Core Dump 文件记录,这些异常或多或少甚至几乎都与“内存”脱不了干系,总结起来主要涉及以下:

1、堆栈溢出问题

通常来讲,例如,分配大量局部变量、多重函数调用、较深的函数递归等等都会有可能导致堆栈溢出现象。

2、多线程访问问题

此处主要包含以下2种场景,共享资源互斥访问异常以及调用不可重入函数等。

3、内存访问越界

此处主要涉及应用程序资源申请超出动态(malloc/new)内存申请范围、数组下标越界、常见的字符串没有结束符,例如,一些函数依赖于字符串结束符,如 strcpy、strcmp、sprintf等等都有可能导致。

4、非法指针的异常访问

如何配置开启 “Core Dump” 文件 ?

通常,在实际的业务场景中,如果没有进行 Core Dump 的相关设置,默认是不开启的。可以通过 ulimit -c 命令行参数查看是否开启。如果输出为 “0”,则表示没有开启,此时,需要执行 ulimit -c unlimited 命令行开启 Core Dump 功能。

[administrator@JavaLangOutOfMemory ~ ]% ulimit -c 
0
[administrator@JavaLangOutOfMemory ~ ]% ulimit -a
core file size          (blocks, -c) 1024
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 127470
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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) 127470
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

如上述命令行结果所示:结果为 0,则表明当前所有程序异常崩溃不会生成 Core Dump 文件。具体的开启命令行操作参数如下所示:

[administrator@JavaLangOutOfMemory ~ ]% ulimit -c 1024  #开启生成 core 文件,文件大小限制在1024KB以内
[administrator@JavaLangOutOfMemory ~ ]% ulimit -c 
1024
[administrator@JavaLangOutOfMemory ~ ]% ulimit -c unlimited  #开启生成 core 文件,文件大小无限制

通常,在大多数环境下,在 Core 生成开启的情况下,Linux 的应用程序在异常崩溃时一定会产生 Core Dump 文件,当 Core Dump 文件超过限定的大小时,文件将不生成。使用 ulimit -c filesize命令,可以限制 Core 文件的大小(filesize 的单位为 kbyte)。若 ulimit -c unlimited,则表示 Core 文件 的大小不受限制。如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的 Core 文件。在调试此 Core 文件的时候,gdb 会提示错误。因此,若在 ulimit -c 1024 情况下异常崩溃没有生成 Core 文件,我们则可以通过 ulimit -c unlimited 命令行参数操作将 Core 的文件规定设置为无限制。

针对 ulimit 命令,此处进行简要的解析。作为 Linux 操作系统中关键的命令行工具之一,其主要用来限制系统用户对 Shell 资源的访问。涉及以下各种类型的限制:所创建的内核文件的大小、进程数据块的大小、Shell 进程创建文件的大小、内存锁住的大小、常驻内存集的大小、打开文件描述符的数量、分配堆栈的大小、CPU 时间片、单个用户的最大线程数、Shell 进程所能使用的最大虚拟内存。除此之外,其也能够支持硬资源和软资源的限制。针对 ulimit 命令相关语法选项如下所示:

-a:显示目前资源限制的设定;
-c <core文件上限>:设定core文件的最大值,单位为区块;
-d <数据节区大小>:程序数据节区的最大值,单位为KB;
-f <文件大小>:shell所能建立的最大文件,单位为区块;
-H:设定资源的硬性限制,也就是管理员所设下的限制;
-m <内存大小>:指定可使用内存的上限,单位为KB;
-n <文件数目>:指定同一时间最多可开启的文件数;
-p <缓冲区大小>:指定管道缓冲区的大小,单位512字节;
-s <堆叠大小>:指定堆叠的上限,单位为KB;
-S:设定资源的弹性限制;
-t <CPU时间>:指定CPU使用时间的上限,单位为秒;
-u <程序数目>:用户最多可开启的程序数目;
-v <虚拟内存大小>:指定可使用的虚拟内存上限,单位为KB。

通常,基于默认配置环境下,系统生成的 Core 文件是不带其它任何扩展名称,即往往会被命名为 core。同时,新的 core 文件生成将覆盖原来旧的 core文件 。因此,基于特定的场景,我们需要对 Core 文件的名称和生成路径进行相关的配置,以满足我们实际的问题排障需要,具体操作可参考如下所示:

[administrator@JavaLangOutOfMemory ~ ]% echo "1" > /proc/sys/kernel/core_uses_pid

基于 /proc/sys /kernel/core_uses_pid 可以控制 Core 文件的文件名中是否添加 pid 作为扩展。若文件内容为1,表示添加pid作为扩展名,生成的 Core文件格式为core.pid;为 0 则表示生成的 Core 文件统一命名为 core。

[administrator@JavaLangOutOfMemory ~ ]% echo "/corefile/core-%e-%p-%t" > core_pattern

基于 /proc/sys/kernel/core_pattern可以控制 Core 文件保存位置和文件名格式。上述命令行操作可以将 Core 文件统一生成到 /corefile 目录下,产生的文件名为:core-命令名-pid-时间戳。其他类似的参数可参考如下:

%p - insert pid into filename 添加pid 
%u - insert current uid into filename 添加当前uid 
%g - insert current gid into filename 添加当前gid 
%s - insert signal that caused the coredump into the filename 添加导致产生core的信号 
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间 
%h - insert hostname where the coredump happened into filename 添加主机名 
%e - insert coredumping executable name into filename 添加命令名 

如何确定是 “Core Dump” 文件?

在类 Linux 系统下,Core Dump 文件本身主要的格式也是 ELF ,因此,我们可以通过 readelf 命令进行判断,具体如下所示:

[administrator@JavaLangOutOfMemory ~ ]% readelf -h core

基于上述命令,获取 “Type”关键字属性值,若为 “CORE (Core file)” ,则表示此文件为 Core Dump 文件。当然,我们也可以通过简单的 file 命令进行快速判断,具体如下所示:

[administrator@JavaLangOutOfMemory ~ ]% file core.10000

上面我们讲了 Core 文件的生成,接下来,我们再简要解析下 Core 文件的使用与分析。通常情况下,所生成的 Core 文件是需要借助 gdb 工具来进行调试以及查看。具体可参考如下所示:

[administrator@JavaLangOutOfMemory ~ ]% gdb test core.coredump.2034.3291660340
GNU gdb Red Hat Linux (6.5-8.fc6rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".


Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Error while mapping shared library sections:
libmylib.so: Success.
[administrator@JavaLangOutOfMemory ~ ]% gdb -core=core.10000

然后,我们键入 “bt” 命令参数,此时,将会显示所更详尽的调用信息,基于此内容分析,我们便能够快速、准确定位出问题所在。通常,若有时候 Core Dump 只生成一个空文件,我们也可以借助 “file” 命令进行辅助查看。

综上所述,Core Dump 文件对于分析类 Unix 操作系统环境下程序异常的作用是不言而喻的,具有十分重要的参考意义。基于其所具备的“问题复现”、“信息追踪”等特征,借助它,使得我们在疑难杂症面前,能够从容面对。

- EOF -

如果您喜欢本文,欢迎点赞收藏留言,或者点击右下角,把文章分享给你的朋友们~~~

Luga Lee

“路,在自己脚下~”

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码