Linux 的 core 文件详解
sinye56 2024-11-27 20:32 1 浏览 0 评论
Linux 的 core 文件
1. 什么是core文件
core 文件是大多数 UNIX 系统实现的一种特性,当进程崩溃时,操作系统会将进程当前的内存映像和一部分相关的调试信息写入 core 文件,方便人们后面对问题进行定位。
2. 哪些信号可能会产生core文件
操作系统里面有很多信号(每个信号都有一个名字,且已SIG开头,用正整数表示,Linux系统一般在头文件中定义),分别代表了不同的含义,在Linux系统中,我们可以通过shell命令 kill -l 来查看系统有哪些信号。操作系统收到信号时,内核会按照以下三种方式之一去对信号进行处理:
忽略此信号。大多数的信号都可以用这种方式去处理,即内核收到此信号时,对进程不做任何处理,直接忽略。但是SIGKILL和SIGSTOP这两个信号不能被忽略,因为它们向超级用户提供了使进程终止或停止的可靠方法。
捕捉信号。即我们向内核注册一个信号处理函数,当内核收到某个信号时,就去调用注册的信号处理函数对信号进行处理。比如我们经常使用的命令kill默认发的是SIGTERM终止信号。注意,不能捕捉SIGKILL和SIGSTOP信号。
执行默认动作。每个系统都有一套自己默认的信号处理函数,即如果我们不显式的去捕捉信号,那内核收到信号时,要么忽略此信号,要么执行默认的操作。可以理解为操作系统有自己默认的信号处理函数。
Linux信号有很多,这里我们列举出默认动作中可能产生core文件的信号(摘自《UNIX环境高级编程》第二版)
信号名字 | 说明 | 默认动作 |
SIGABRT | 异常终止(调用abort函数产生此信号) | 终止+core |
SIGBUS | 硬件故障,比如出现某些内存故障 | 终止+core |
SIGEMT | 硬件故障 | 终止+core |
SIGFPE | 算术异常,比如除以0,浮点溢出等 | 终止+core |
SIGILL | 非法硬件指令 | 终止+core |
SIGIOT | 硬件故障 | 终止+core |
SIGQUIT | 终端退出符,比如Ctrl+C | 终止+core |
SIGSEGV | 无效内存引用 | 终止+core |
SIGSYS | 无效系统调用 | 终止+core |
SIGXCPU | 超过CPU限制(setrlimit) | 终止+core/忽略 |
SIGXFSZ | 超过文件长度限制(setrlimit) | 终止+core/忽略 |
如果我们没有定义上述信号的信号处理函数,那默认情况下,内核收到这些信号,将终止进程,并产生该进程的core文件(该进程的内存映像以及一些调试信息便保存在该core文件中)。
3. 如何开启与关闭core文件
类UNIX操作系统为我们提供了一个可以打开与关闭core文件的开关,因为并非所有场景我们都希望可以生成core文件。类UNIX操作系统为我们提供了一个工具ulimit可以用来设置和查看文件大小的限制,所以我们也可以用这个工具来查看和设置core大小与限制。使用 ulimit -a 可以查看系统上面所有的文件大小的限制,比如下面是我的系统的输出结果:
allan@ubuntu:~$ 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) 7725
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) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7725
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
显示结果分为三部分,比如第一行,第一部分是“core file size”,第二部分是“(blocks, -c)”,第三部分是“0”。这一行的含义是说“core文件的大小限制为0(即关闭core文件/不产生core文件),单位是blocks;使用ulimit -c命令可以改变此值”。这里我们还可以看到系统很多其他文件相关的设置,比如数据段大小无限制,文件大小无限制,最多打开的文件数为1024,栈大小为8192KB等等。
所以很明显,我们可以使用 ulimit -c core_size/unlimited 去设置core文件的大小,注意core_size单位是字节。如果core_size为0,则表示不生成core文件,unlimited表示对core文件大小不做限制。我们可以将该命令现在某个用户的环境变量里面去对不同的用户进行设置,比如写在/home/allan/.bashrc文件里面只对allan用户有效;也可以写在系统的环境变量里面,对所有用户有效,比如/etc/.profile。
4. 如何自定义core文件名和目录
(1) /proc/sys/kernel/core_uses_pid 可以控制产生的core文件的文件名中是否添加pid作为扩展,如果添加则文件内容为1,否则为0。如果添加了pid,生成的core文件一般为core.xxx(xxx为core dump的进程号)。默认为0,即不添加进程pid.
(2) /proc/sys/kernel/core_pattern 可以设置格式化的core文件保存位置或文件名,比如我的系统的默认值为:
|/usr/share/apport/apport %p %s %c %P
我们可以使用以下命令修改此文件:
echo “/corefile/core-%e-%p-%t” > core_pattern ,这样可以将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 添加命令名
5. 如何查看core文件
我们可以使用gdb来查看core文件(core文件必须是完好的,比如如果我们限制的core文件大小比较小,导致core文件被截断,则gdb查看时将出错)。查看语法如下:
gdb [exec file] [core file]
比如: gdb ./test core.3937 。gdb进去以后,可以使用bt或where来查看进程崩溃之前的堆栈信息。
6. 一些注意事项
在Linux下要保证程序崩溃时生成Coredump要注意这些问题:
要保证存放Coredump的目录存在且进程对该目录有写权限。存放Coredump的目录即进程的当前目录,一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动,则脚本可能会修改当前目录,这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看”/proc/<进程pid>/cwd“符号链接的目标来确定进程 真正的当前目录地址。通过系统服务启动的进程也可通过这一方法查看。
若程序调用了seteuid()/setegid()改变 了进程的有效用户或组,则在默认情况下系统不会为这些进程生成Coredump。很多服务程序都会调用seteuid(),如MySQL,不论你用什么用 户运行mysqld_safe启动MySQL,mysqld进行的有效用户始终是msyql用户。如果你当初是以用户A运行了某个程序,但在ps里看到的 这个程序的用户却是B的话,那么这些进程就是调用了seteuid了。为了能够让这些进程生成core dump,需要将/proc/sys/fs /suid_dumpable文件的内容改为1(一般默认是0)。
这个一般都知道,就是要设置足够大的Core文件大小限制 。程序崩溃时生成的Core文件大小即为程序运行时占用的内存大小。但程序崩溃时的行为不可按平常时的行为来估计,比如缓冲区溢出等错误可能导致堆栈被 破坏,因此经常会出现某个变量的值被修改成乱七八糟的,然后程序用这个大小去申请内存就可能导致程序比平常时多占用很多内存。因此无论程序正常运行时占用 的内存多么少,要保证生成Core文件还是将大小限制设为unlimited为好。
相关推荐
- Linux基础知识之修改root用户密码
-
现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...
- Linux如何修改远程访问端口
-
对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...
- 如何批量更改文件的权限
-
如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...
- CentOS「linux」学习笔记10:修改文件和目录权限
-
?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...
- Linux下更改串口的权限
-
问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...
- Linux chown命令:修改文件和目录的所有者和所属组
-
chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...
- chmod修改文件夹及子目录权限的方法
-
chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...
- Android 修改隐藏设置项权限
-
在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...
- 完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!
-
最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...
- linux改变安全性设置-改变所属关系
-
CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...
- Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod
-
#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...
- linux更改用户权限为root权限方法大全
-
背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...
- 怎么用ip命令在linux中添加路由表项?
-
在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...
- Linux配置网络
-
1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...
- Linux系列---网络配置文件
-
1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)