coredump

写在前面

今天在分析TBOX的过程中,发现了一个CoredumpService的服务,具体代码涉及保密,就不放出来了,fw的我之前并不知道coredump是什么东西,所以来学习记录一下。

什么是coredump

coredump顾名思义就是核心转储。我们的应用程序在运行过程中,如果发生了异常crash,光靠程序自身的log是很难定位到根因的,所以操作系统提供了一套coredump机制。这套机制可以在crash发生的时候,把进程现场的vma信息存储到coredump文件中去。利用这个文件,就可以恢复异常现场的信息,分析人员可以从中获取到变量值、栈信息、内存数据、程序crash时的运行位置等

coredump是如何生成的

当应用程序发生crash时,会陷入到内核进行异常处理,此时内核会产生一个信号(signal)发送给对应的进程。当进程从内核态到用户态切换时,该进程会处理这个信号。此类信号(比如SEGV)的默认处理行为就会生成一个coredump文件。当然,手动给某个应用程序发送这类信号,也是可以生成对应的coredump文件的,例如kill -9 pidof xxx

哪些信号可以产生coredump文件

可以看到3、4、6、8、11都能产生的信号, 默认都会产生coredump行为。如果修改了进程对这类信号的处理,则不会产生coredump了。

保存的coredump文件在什么地方

/proc/sys/kernel/core_pattern 指定coredump文件存储的位置,缺省值是core,表示将coredump文件存储到当前目录。这个pattern是可以定制的,模式如下:

1
2
3
4
5
%p  进程的PID
%u 进程的UID
%s 造成coredump的signal号
%t coredump生成的时间,从1970-01-01 00:00:00开始的秒数
%e 出Core进程对应的可执行文件名

例如:echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern,表示coredump路径为/corefile,文件名的格式为”core-可执行文件名-pid-时间”。

/proc/sys/kernel/core_uses_pid 取值是0或者1,表示是否在coredump文件名字后面加上进程号

coredump文件会把进程地址空间的哪些内容保存下来

/proc/$pid/coredump_filter 设置那些内存会被dump出来,需要在程序启动之后进行设置。

1
2
3
4
5
6
7
bit 0  Dump anonymous private mappings.
bit 1 Dump anonymous shared mappings.
bit 2 Dump file-backed private mappings.
bit 3 Dump file-backed shared mappings.
bit 4 (since Linux 2.6.24) Dump ELF headers.
bit 5 (since Linux 2.6.28) Dump private huge pages.
bit 6 (since Linux 2.6.28) Dump shared huge pages.

coredump_filter的默认值是0x33,也即发生coredump时会将所有anonymous内存、ELF头页面、hugetlb private memory内容保存。

如何控制coredump文件的大小

ulimit -c决定save的coredump文件大小限制,如果保存的文件小于设定的限制,则不会创建coredump文件。如果不想限制大小,需要设置ulimit -c unlimited。但是输入后只对执行这个命令的进程,及其后面fork出来的进程有效,已经运行的进程无效。例如,init进程在执行ulimit -c unlimited之前,运行了一个进程a,则进程a crash的时候不会产生coredump。

太烧脑了,下次再学。。。。。


coredump
https://g1at.github.io/2023/08/21/coredump/
作者
g0at
发布于
2023年8月21日
许可协议