0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

内核转储是怎么设置的?

汽车电子技术 来源:嵌入式与Linux那些事 作者:仲一 2023-02-17 15:57 次阅读

简介

当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做 Core Dump(中文有的翻译成“核心转储”)。

我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。

core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

核心转储如何产生

上面说当程序运行过程中异常终止或崩溃时会发生 core dump,但还没说到什么具体的情景程序会发生异常终止或崩溃。

例如我们使用 kill -9 命令杀死一个进程会发生 core dump 吗?实验证明是不能的,那么什么情况会产生呢?

Linux信号是一种异步事件处理的机制,每种信号都有其对应的默认操作,你可以在 signal(7) 查看 Linux 系统提供的信号以及默认处理。

默认操作主要包括:终止进程(Term)、忽略该信号(Ing)、终止进程并发生核心转储(Core)、暂停进程(Stop)、继续运行被暂停的进程(Cont)。

如果我们信号均是采用默认操作,那么,以下列出的几种信号,它们在发生时会产生 core dump:

Signal Action Comment 说明
SIGABRT Core Abort signal from abort 来自abort的终止信号
SIGBUS Core Bus error (bad memory access) 总线错误(内存访问错误)
SIGFPE Core Floating-point exception 浮点异常
SIGILL Core Illegal Instruction 非法指令
SIGIOT Core IOT trap. A synonym for SIGABRT 物联网陷阱。SIGABRT 的同义词
SIGQUIT Core Quit from keyboard 从键盘退出
SIGSEGV Core Invalid memory reference 无效的内存引用
SIGSYS Core Bad system call (SVr4) 错误的系统调用
SIGTRAP Core Trace/breakpoint trap 跟踪/断点陷阱
SIGUNUSED Core Synonymous with SIGSYS SIGSYS 的同义词
SIGXCPU Core CPU time limit exceeded (4.2BSD) 超出 CPU 时间限制
SIGXFSZ Core File size limit exceeded (4.2BSD) 超出文件大小限制

这就是为什么我们使用 Ctrl+z 来挂起一个进程或者 Ctrl+C 结束一个进程均不会产生 core dump。

因为前者会向进程发出 SIGTSTP 信号,该信号的默认操作为暂停进程(Stop Process);后者会向进程发出SIGINT 信号,该信号默认操作为终止进程(Terminate Process)。

同样,上面提到的 kill -9 命令会发出 SIGKILL 命令,该命令默认为终止进程。而如果我们使用 Ctrl+\\ 来终止一个进程,会向进程发出 SIGQUIT 信号,默认是会产生 core dump 的。

还有其它情景会产生 core dump, 如:程序调用 abort() 函数、访存错误、非法指令等等。

不会生成core dump文件的情况

  • 进程没有写入核心文件的权限。(默认情况下,核心文件称为 core 或 core.pid,其中 pid 是转储核心的进程的 ID,并在当前工作目录中创建。有关命名的详细信息,请参见下文。)如果出现以下情况,则写入核心文件失败:要创建的目录不可写,或者如果存在同名文件且不可写或不是常规文件(例如,它是目录或符号链接)。
  • 一个(可写的、常规的)文件与用于核心转储的同名文件已经存在,但有多个硬链接到该文件。
  • 将创建核心转储文件的文件系统已满;或已用完 inode;或以只读方式安装;或者用户已达到文件系统的配额。
  • 要创建核心转储文件的目录不存在。
  • 进程的 RLIMIT_CORE(核心文件大小)或 RLIMIT_FSIZE(文件大小)资源限制设置为零;请参阅 getrlimit(2) 和 shell 的 ulimit 命令的文档(csh(1) 中的限制)。
  • 进程正在执行的二进制文件没有启用读取权限。(这是一种安全措施,可确保内容不可读的可执行文件不会产生可能可读的核心转储,其中包含可执行文件的映像。)
  • 进程正在执行一个set-user-ID(set-group-ID)程序,该程序被除进程的真实用户(组)ID之外的用户(组)拥有,或者进程正在执行具有文件能力(capabilities)的程序(请参阅 capabilities(7))。(但是,请参阅 prctl(2) PR_SET_DUMPABLE 操作的说明,以及 proc(5) 中 /proc/sys/fs/suid_dumpable 文件的说明)
  • /proc/sys/kernel/core_pattern 为空且 /proc/sys/kernel/core_uses_pid 包含值 0。请注意,如果 /proc/sys/kernel/core_pattern 为空且 /proc/ sys/kernel/core_uses_pid 包含值 1,核心转储文件将具有 .pid 形式的名称,除非使用 ls(1) -a 选项,否则此类文件将被隐藏。
  • (自 Linux 3.7 起)内核配置时没有配置 CONFIG_COREDUMP 选项。

此外,如果使用了 madvise(2) MADV_DONTDUMP 标志,则核心转储可能会排除进程的部分地址空间。

启用内核转储

使用ulimit命令可以查看当前的内核转储功能是否生效。-c表示内核转储文件的大小限制,0表示内核转储无效。

root@firefly:~# ulimit -c
0

使用以下命令即可开启内核转储功能,unlimited表示不限制core文件的大小。

root@firefly:~# ulimit -c unlimited
root@firefly:~# ulimit -c
unlimited

在服务器上交叉编译一个测试程序,确认内核转储是否生效。

#include 
  
int main(void)
{
 int *a=NULL;
 *a=0x1;
 return 0;
}
aarch64-linux-gnu-gcc -g test.c -o test

将生成的可执行程序拷贝到开发板上。

root@firefly:~/code# ./test 
Segmentation fault (core dumped)
root@firefly:~/code# ls
core  test
root@firefly:~/code# file core 
core: ELF 64-bit LSB core file, ARM aarch64, version 1 (SYSV), SVR4-style, from './test', real uid: 0, effective uid: 0, real gid: 0, effective gid: 0, execfn: './test', platform: 'aarch64'

将core文件拷贝到服务器上,可以使用以下命令解core文件

➜  mnt sudo aarch64-linux-gnu-gdb  test core
.....

GNU gdb (Linaro_GDB-2017.05) 7.12.1.20170417-git
......
warning: Could not load shared library symbols for 2 libraries, e.g. /lib/aarch64-linux-gnu/libc.so.6.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000055815836f4 in main () at test.c:6
6       *a=0x1;
(gdb) l 6
1       #include h>
2
3       int main(void)
4       {
5       int *a=NULL;
6       *a=0x1;
7       return 0;
8       }
(gdb)

可以看到,在GDB启动后,已经打印出test.c的第6行收到了SIGSEGV信号,产生了段错误。使用list命令可以查看附近的源代码。

在专用目录生成内核转储

core文件默认会在当前目录生成,大多数时候,我们希望固定core文件的生成位置。

内核转储保存位置可以通过sysctl变量kernel.core_pattern设置。例如,在/etc/sysctl.conf中做如下设置。

root@firefly:~# vim /etc/sysctl.conf

#在末尾追加以下两行
kernel.core_pattern = /root/core/%t-%e-%p-%c.core
kernel.core_uses_pid = 0

#使配置生效
root@firefly:~# sysctl -p
kernel.core_pattern = /root/core/%t-%e-%p-%c.core
kernel.core_uses_pid = 0

在该状态下执行test测试程序,就会在/root/core/下生成内核转储文件。

root@firefly:~/mnt# ./test
Segmentation fault (core dumped)
root@firefly:~/mnt# ls /root/core/
1664718591-test-2699-18446744073709551615.core

kernel.core_pattern 中可以设置的格式符如下

格式符 说明
%% % 字符本身
%p 被转储进程的进程 ID(PID)
%u 被转储进程的真实用户 ID(real UID)
%g 被转储进程的真实组 ID(real GID)
%s 引发转储的信号编号
%t 转储时刻(从 1970/1/1 0:00 开始的秒数)
%h 主机名(同 uname(2) 返回的 nodename)
%e 可执行文件名
%c 转储文件的大小上限(内核版本 2.6.24 后可用)

压缩转储文件

kernel.core_pattern也支持管道,可以在kernel.core_pattern 后加入管道符自动压缩内核转储文件。

vim /etc/sysctl.conf
kernel.core_pattern = |/usr/local/sbin/core_helper %t %e %p %c
kernel.core_uses_pid = 0
sysctl -p

core_helper内容如下

#!/bin/sh
exec gzip -> /root/core/$1-$2-$3-$4.core.gz

加上可执行权限

chmod 777 /usr/local/sbin/core_helper

这样,发生内核转储时,就会在/root/core下生成压缩的转储文件。

root@firefly:~/mnt# ./test 
Segmentation fault (core dumped)
root@firefly:~/mnt# ls /root/core/
1664720072-test-2723-18446744073709551615.core.gz
root@firefly:~/mnt#

启用整个系统的内核转储功能

在终端通过命令行只是临时修改,重启后无效 ,要想永久修改有三种方式:

  1. 在/etc/rc.local 中增加一行 ulimit -c unlimited
  2. 在/etc/security/limits.conf最后增加如下两行记录:
@root soft core unlimited
@root hard core unlimited

利用内核转储掩码排除共享内存

大型应用程序,通常会跑多个进程。如果所有进程的共享内存全部转存储的话,会对磁盘造成压力,转储过程也会加重系统的负担,甚至会由于转储时间过长导致服务停止时间过长。

由于共享内存的进程中,共享内存的内容是相同的,所以可以只在某个进程中转储共享内存,无需全部转储。

bit 0 转储匿名私有映射。
bit 1 转储匿名共享映射。
bit 2 转储文件支持的私有映射。
bit 3 转储文件支持的共享映射。
bit 4(自 Linux 2.6.24 起)转储 ELF 标头。
bit 5(自 Linux 2.6.28 起)转储私有大页面。
bit 6 (自 Linux 2.6.28) 转储共享大页面。
bit 7(自 Linux 4.4 起)转储私有 DAX 页面。
bit 8(自 Linux 4.4 起)转储共享 DAX 页面。

通过coredump_filter的内容可以查看设置情况

cat /proc//coredump_filter

如果要跳过所有共享内存区域,应将掩码值设置为1.

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    2964

    浏览量

    73803
  • 操作系统
    +关注

    关注

    37

    文章

    6675

    浏览量

    123127
  • 程序
    +关注

    关注

    116

    文章

    3754

    浏览量

    80738
收藏 人收藏

    评论

    相关推荐

    崩溃

    10 64bit即使我不使用我的系统,我总是有崩溃它有很多原因,如:irql不小于或等于驱动程序irql不小于或等于内存管理非分页区域中的页面文件意外的内核陷阱kmod异常没有handeled系统
    发表于 11-30 11:14

    怎么在B2902A上通过SCPI设置自动触发和屏幕

    GRAP TRIG:ALL:IMM(@ 1:2)此时图像显示,它应该是新触发的数据集,但它只显示最后收集的数据。我也试图从电源获得屏幕。我使用了HCOP:SDUM:FORM JPG和HCOP
    发表于 03-19 14:41

    怎么从Virtex 6的FPGA中取出BRAM

    大家好请任何人告诉我。是否有任何方法可以从Virtex 6的FPGA中取出BRAM。提前致谢问候Vir_1602以上来自于谷歌翻译以下为原文Hi all would anyone please
    发表于 03-20 15:37

    如何程序4bit程序

    你好先生,我有Spartan 3E套件我正在学习它我知道如何程序4bit程序什么是Microbiz以及何时使用..谢谢拉梅什以上来自于谷歌翻译以下为原文Hellosir, I am having
    发表于 05-13 08:19

    MPLABX有字节字节的HEX选项吗?

    我使用MPLABX和XC8编译器来声明一个16位整数数组。好的,它是一个8位处理器。奇怪的是,低字节似乎需要在一个奇怪的地址。好,好的。也许吧。但是当我看着HEX的时候,似乎字节被颠倒了,然后被
    发表于 07-19 08:42

    位文件后合成设计更改

    合成设计时,所有FDCE端口都正确连接。但是在将代码到目标之后,我得到的输出是错误的。但是,如果我第二次,我没有得到输出,但只有数据捕获模块的零。那次我检查了合成设计。现在,F
    发表于 04-16 07:46

    用于VHDL代码的saif文件

    我一直在使用xilinx vivado来测试一些代码。这些代码通常用于无矢量功率估计。但是,当我尝试从模拟设置saif文件时,我收到以下错误:#log_saif [get_objects
    发表于 04-20 10:14

    在FPGA上生成位文件和时无法看到输出是为什么?

    文件和时,我无法看到输出。这里我使用的是1.25Gbps的SFP光收发模块。是否有任何条件/约束要考虑使SFP启用?FPGA = Kintex 7系列xc7k160tfbg484-2SFP
    发表于 05-21 10:58

    有什么方法可以追溯地将加密标志应用于现有加密设备上的核心分区?

    应用程序分区(一个工厂和两个 OTA 分区) ,以及 FATFS 分区、核心分区和一些 NVS 分区等......对于我们现在运行此设置的(数千台)野外设备,我们希望能够将核心
    发表于 03-02 08:01

    如何QN9021的bin数据?

    我们有一款产品使用 Q9021 和 BLE SDK 1.0.0。我们得到了一些退货单位,我想检查一下bin文件的代码是否正确。如何QN9021的bin数据?
    发表于 05-25 07:32

    紫金桥实时数据库_实时数据功能深度剖析

    在紫金桥软件的实时数据库版本中,提供了一组与关系数据库通讯的工具——数据工具,数据工具包括数据
    发表于 10-13 16:26 8次下载
    紫金桥实时数据库_实时数据<b class='flag-5'>转</b><b class='flag-5'>储</b>功能深度剖析

    Ubuntu 16.04系统中调试Apollo项目核心文件的方法

    核心对于程序员调试程序非常有益,因为有些程序错误是很难重现的,例如指针异常,而核心文件可以重现程序出错时的情景。
    的头像 发表于 03-23 09:30 6938次阅读

    linux内核参数设置_linux内核的功能有哪些

    本文主要阐述了linux内核参数设置及linux内核的功能。
    发表于 09-17 14:40 1353次阅读
    linux<b class='flag-5'>内核</b>参数<b class='flag-5'>设置</b>_linux<b class='flag-5'>内核</b>的功能有哪些

    内核设置

    当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做 Core Dump(中文有的翻译成“核心”)。
    的头像 发表于 12-19 13:42 665次阅读

    ADPADS颜色设置保存版

    ADPADS颜色设置保存版
    发表于 05-29 10:43 0次下载