Core文件生成的两种方法

基本概念

   当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

生成Core文件的两种方法

1.使用shell内建命令ulimit

①在终端中输入命令ulimit -c,输出结果为0,说明默认是core dump的,即当程序异常终止时,也不会生成core dump文件。

②可以使用ulimit -c unlimited开启core dump,unlimited表示不限制core dump文件的大小;如果需要限制文件大小,将unlimited改为你需要的大小,单位为KB。

③用上面命令只会对当前的终端环境有效,如果需要永久生效,可以修改/etc/security/limits.conf文件。

④修改core文件保存路径

●默认生成的core文件保存在可执行文件所在的目录下,文件名为core。

●通过修改/proc/sys/kernel/core_uses_pid文件使生成的core文件加上pid号,echo 1>/proc/sys/kernel/core_uses_pid。

● 还可以通过修改/proc/sys/kernel/core_pattern控制生成的core文件保存的位置以及文件名。

echo "/home/core-%e-%p-%t" > /proc/sys/kernel/core_pattern

或者:
sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t kernel.core_pattern = /corefile/core-%e-%p-%t
可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
以下是参数列表:
%p - insert pid into filename 添加pid(进程id)
%u - insert current uid into filename 添加当前uid(用户id)
%g - insert current gid into filename 添加当前gid(用户组id)
%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 添加导致产生core的命令名

测试是否能生成core文件:

kill -s SIGSEGV $$
查看/home目录下是否生成了core文件

2.使用getrlimit和setrlimit API

需要包含头文件#include <sys/resource.h>

在linux系统中,Resouce limit指在一个进程的执行过程中,它所能得到的资源的限制,比如进程的core file的最大值,虚拟内存的最大值等。

Resouce limit的大小可以直接影响进程的执行状况。其有两个最重要的概念:soft limit 和 hard limit。

struct rlimit {
  rlim_t rlim_cur;  //soft limit
  rlim_t rlim_max;  //hard limit
};

soft limit是指内核所能支持的资源上限。比如对于RLIMIT_NOFILE(一个进程能打开的最大文件数,内核默认是1024),soft limit最大也只能达到1024。对于RLIMIT_CORE(core文件的大小,内核不做限制),soft limit最大能是unlimited。
hard limit在资源中只是作为soft limit的上限。当你设置hard limit后,你以后设置的soft limit只能小于hard limit。要说明的是,hard limit只针对非特权进程,也就是进程的有效用户ID(effective user ID)不是0的进程。具有特权级别的进程(具有属性CAP_SYS_RESOURCE),soft limit则只有内核上限。

#include <stdio.h>
#include <sys/resource.h>
#include<sys/prctl.h>

int main()
{
    struct rlimit corelimit;

    if (prctl(PR_SET_DUMPABLE, 1) < 0)
    {
        printf("Cannot enable core dumping.\n");
    }

    if (getrlimit(RLIMIT_CORE, &corelimit) == -1) {
        return -1;
    }
    printf("Before set rlimit CORE dump current is:%d, max is:%d\n", (int)corelimit.rlim_cur, (int)corelimit.rlim_max);


       /* set core size to unlimited, RLIM_INFINITY:unlimted,1024*1024:1M*/
    corelimit.rlim_cur = RLIM_INFINITY; /*1M*/
    corelimit.rlim_max = RLIM_INFINITY;


    if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1;
    }

    if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1;
    }
    printf("After set rlimit CORE dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);

    /*测试非法内存,产生core文件*/
    int *ptr = NULL;
    *ptr = 10;

    return 0;
}

gcc -g -o main main.c 编译时需要注意带-g,生成可执行文件main,运行可以在当前目录得到core文件。

GDB调试core文件,查看程序挂在位置。当core dump 之后,使用命令 gdb program core 来查看 core 文件,其中 program 为可执行程序名,core 为生成的 core 文件名。

发布了9 篇原创文章 · 获赞 1 · 访问量 6701

猜你喜欢

转载自blog.csdn.net/u014426028/article/details/102730142
今日推荐