简介

Linux coredump功能是当Linux下应用程序异常时,Linux内核默认的一种异常信号处理机制,内核会把异常信息与进程内存转储成coredump文件,程序员通过gdb工具可以离线分析应用程序异常时的情况。

使用           

文件生成配置

原版coredump不压缩:

  1. 设置进程的coredump文件大小:ulimit -c unlimited

说明:只对当前进程有效,当前进程的子进程可以继承这一特性。默认为0,不会生成coredump

2. 设置生成coredump文件的路径以及文件名格式:

        echo “/dst_dir/core-%e-%t-%s-%p” > /proc/sys/kernel/core_pattern

        说明:%e 生成coredump文件的进程名

              %t 时间,从1970-01-01 00:00:00开始的秒数

              %s 触发coredump的signal号

              %p 触发coredump的进程pid

压缩版coredump配置:

coredump文件根据进程使用内存的多少决定生成文件的大小,有时候存储空间有限,就希望能在生成的时候自动压缩一下coredump文件

  1. 设置进程的coredump文件大小:ulimit -c unlimited

说明:只对当前进程有效,当前进程的子进程可以继承这一特性。默认为0,不会生成coredump

    2. 编辑压缩脚本coredump_gzip,存放到/path目录

#!/bin/sh

exec gzip -> /ata4/Log/core-$1-$2-$3-$4.gz

  3.设置core_pattern

 echo "| /path/coredump_gzip %e %t %s %p" > /proc/sys/kernel/core_pattern

gdb 解析

  1. 加载coredump文件

gdb 可执行程序 coredump文件

   2.进入gdb控制台后,和正常的gdb操作类似

原理相关

1 哪些异常信号会触发coredump

看内核代码吧:

include/linux/signal.h

#define sig_kernel_coredump(sig)  siginmask(sig, SIG_KERNEL_COREDUMP_MASK)

#define SIG_KERNEL_COREDUMP_MASK (\

        rt_sigmask(SIGQUIT)   |  rt_sigmask(SIGILL)    | \

         rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGABRT)   | \

        rt_sigmask(SIGFPE)    |  rt_sigmask(SIGSEGV)   | \

         rt_sigmask(SIGBUS)    |  rt_sigmask(SIGSYS)    | \

        rt_sigmask(SIGXCPU)   |  rt_sigmask(SIGXFSZ)   | \

         SIGEMT_MASK                                            )

2 当自定义了信号处理函数后,coredump文件还能生成吗

看内核代码吧:

kernel/signal.c   get_signal函数

for (;;) {

…

if (ka->sa.sa_handler != SIG_DFL) {

         /* Run the handler.  */

ksig->ka = *ka;



         if (ka->sa.sa_flags & SA_ONESHOT)

         ka->sa.sa_handler = SIG_DFL;

         break; /* will return non-zero "signr" value */

}

…

fatal:

if (sig_kernel_coredump(signr)) {

…

do_coredump(&ksig->info);

…

}


}

…

return ksig->sig > 0;

由如上代码可知,当自定义了信号处理函数,不等于SIG_DFL时,代码直接就break循环返回了,不会执行到do_coredump。

但是在一些系统任务严重异常的场景中,如在异常处理过程中重复异常,这种异常的表现一般为进程会退出,这时系统会强制设置信号处理为SIG_DFL,这时仍然会产生coredump

3 coredump文件中记录了哪些内容

看内核代码吧:

Coredump文件的生成在fs/coredump.c文件的do_coredump函数中。

  1. coredump文件名确定

在format_corename函数中,解析/proc/sys/kernel/core_pattern传入的字符串,确定生成的coredump文件名。其中如果一个字符串是|,则判断为通过管道的形式把生成的文件传到用户态自定义程序处理,如上面的生成压缩格式的coredump文件。

    2. 文件生成

(1)文件格式选择

do_coredump函数

   …

file_start_write(cprm.file);

core_dumped = binfmt->core_dump(&cprm);

         file_end_write(cprm.file);

   …

一般linux下程序都为elf格式,所以binfmt->core_dump最终执行的是fs/binfmt_elf.c中的elf_core_dump函数

(2)文件头

elf_core_dump函数:

       dump_emit(cprm, elf, sizeof(*elf)))

       …

 (3)notes头

     dump_emit(cprm, phdr4note, sizeof(*phdr4note)))

     这个段用来记录异常信息

 (4)vmaelf_phdr头

     进程的每一段vma,记录一个头

     dump_emit(cprm, &phdr, sizeof(phdr))

 (5)notes头内容填充

     write_note_info(&info, cprm)

 (6)vmaelf_phdr内容填充     

 …

  for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;

                    vma = next_vma(vma, gate_vma))

      …

       page = get_dump_page(addr);

   void *kaddr = kmap(page);

             stop = !dump_emit(cprm, kaddr, PAGE_SIZE);

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐