coredump文件

1. coredump是什么

Coredump叫做核心转储,它是进程运行时在突然崩溃的那一刻的一个内存快照。操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个core文件里
core文件是二进制文件,可以使用gdbelfdumpobjdump或者windows下的windebug、solaris下的mdb进行打开分析里面的具体内容。

注:core是在半导体作为内存材料前的线圈,当时用线圈当做内存材料,线圈叫做core。用线圈做的内存叫做core memory。故coredump也可称为core memory dump,真是个充满历史味道的词儿。

2. 用在什么地方

在linux下开发时,如果程序突然崩溃了,也没有任何日志。这时可以查看core文件。从core文件中分析原因,通过gdb看出程序挂在哪里,分析前后的变量,找出问题的原因。

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

3.怎么生成core文件

虽然我们知道进程在crash的时候会产生core文件,但是有时候却发现进程虽然coredump了,但是我们却找不到core文件。

原因是,在Linux下是需要进行设置的。

1. 设置文件大小

使用ulimit -c value可以设置core文件的大小。-c的含义是core file size,单位是blocks

  • value=0,则不会产生core文件;
  • value值太小,则core文件也不会产生,因为core文件一般都比较大。
  • ulimit -c unlimited设置无限大,则任意情况下都会产生core文件。

这种修改为临时限制,只存活于当前SHELL会话,仅影响当前SHELL。

2. 获取当前core file名称格式与保存位置

方法1: cat /proc/sys/kernel/core_pattern

eg.

root@OpenWrt:~# cat /proc/sys/kernel/core_pattern
/tmp/%e.%p.%s.%t.core

方法2: /sbin/sysctl kernel.core_pattern

eg.

root@OpenWrt:~# /sbin/sysctl kernel.core_pattern
kernel.core_pattern = /tmp/%e.%p.%s.%t.core

3. 修改core file名称格式与保存位置

echo /mnt/sd/%e.%p.core > /proc/sys/kernel/core_pattern

修改/proc/sys/kernel/core_pattern文件,由于/proc目录本身是动态加载的,每次系统重启都会重新加载,因此这种方法只能作为临时修改

4. 保存修改并全局生效

  1. 修改/etc/profile文件,在文件末尾添加:
ulimit -c unlimited		#设置文件大小
echo /tmp/%e.%p.%s.%t.core > /proc/sys/kernel/core_pattern	#设置文件文件名格式和文件存储位置

为了更详尽的记录core dump当时的系统状态,可通过以下参数来丰富core文件的命名:

  • %%------单个%字符
  • %p------所dump进程的进程ID,pid
  • %u------所dump进程的实际用户ID, uid
  • %g------所dump进程的实际组ID, group
  • %s------导致本次core dump的信号, signal
  • %t------core dump的时间 (由1970年1月1日计起的秒数)
  • %h------主机名, hostname
  • %e------程序文件名, executing program name
  1. 重启系统.
  2. 运行程序。
    当程序coredump时,生成的core文件命名按照上面定义的规则加上了程序名称、coredump时间,进程ID等信息,并放到了指定目录/tmp/下。

3. 使用gdb调试core file简单示例

准备代码

写空指针错误

#include <stdio.h>

void coredump(void)
{
	int *null_ptr = NULL;
	*null_ptr = 10;
}

int main(){
	// 对空指针指向的内存区域写,会发生段错误 -->产生core文件

    printf("hello coredump\n");
    coredump();
    printf("will be never reached\n");
	return 0;
}

编译,运行,生成corefile

image

使用gdb调试core file

gdb 可执行程序(包括路径) 对应的corefile

image

可以直接看到发生错误的地点。

调试无调试信息的程序

image
此时可以看到gdb提示无调试信息,不能像加了-g选项一样,可以直接看到发生段错误的地点。
这个时候需要查看函数的call stackbt or where,看一下是在哪个地方发生的错误 f 0,并进入这个函数,查看其反汇编disassemble代码来定位问题的原因。
image
要想使用反汇编代码定位问题,就需要明确汇编代码与所写代码的对应关系。这个需要积累才能加快调试速度。

4. FAQ

  1. Q: 程序core dump了,但是没有生成core。

    A: 打开ulimited -c unlimited 开关。

  2. Q: 程序core dump了,也产生了core文件, 但core大小为了0。 gdb分析的时候, 会出现is not a core dump: File format not recognized.
    A: 打开ulimited -c unlimited 开关。

  3. Q: 程序core dump了, 也产生了core文件, core大小也不为0, 也设置了ulimited -c unlimited, 但是, gdb分析的时候, 依然出现is not a core dump: File format not recognized
    A: 执行 cat /proc/pid_num/limits查看了一下这个进程的Max core file size值是不是unlimited。 若不是,找到设置文件, 并修改之, 重启服务进程, 然后看看进程的Max core file size值,确认是unlimited即可。

  4. Q:上面的设置都没问题,但是还是会提示is not a core dump: File format not recognized

    A:请确保GDB加载时的格式是正确的。

  5. Q:在/proc/sys/kernel/目录下没有core_pattern文件
    A:这是由于内核编译时,没有使能core dump功能所致。重新配置内核
    image
    编译,烧写即可。

总结:

出现is not a core dump: File format not recognized, 很有可能是core文件不完整导致的,最开始的时候, 大致看看core文件的大小就能大概判断了。 那就真正打开core文件的大小限制吧。

posted @ 2021-09-29 14:22  海林的菜园子  阅读(4711)  评论(0编辑  收藏  举报