linux 下调试coredump文件

1、coredump简介

在linux后台开发过程中可能一不小心出现访问非法内存而产生段错误,面对段错误我们有时候可以通过打印定位,但那样比较慢,我们可以利用linux提供了一种方法,当程序奔溃时内核会保存程序运行的堆栈信息到一个coredump文件,我们可以通过gdb调试这个coredump文件可以知道程序死之前调用了那个函数。

2、开启coredump

我们通过ulimit -c查看系统是否开启了core dump功能,如果输出是0表示没有开,开启coredump文件的命令是ulimit -c unlimited,unlimited表示不限制core dump文件的大小,这样可以保全堆栈信息,开启coredump功能编译程序时不能通过trip去掉程序连接的符号表信息,不然通过gdb调试时连接不要符号表。我们还可以指定产生coredump文件的位置和格式,

命令:echo "/home/core-%e-%p-%t" > /proc/sys/kernel/core_pattern   这样设定coredump文件的保存在/home目录下,文件名格式是core-进程名-进程pid-时间戳。

3、系统接口

coredump设置的接口是setrlimit,主要是设置rlimit结构体

//获取rlimit
int getrlimit(int resource, struct rlimit *rlim);

//设置rlimit
int setrlimit(int resource, const struct rlimit *rlim);
 struct rlimit {
               rlim_t rlim_cur;  /* Soft limit 软件设定值*/
               rlim_t rlim_max;  /* Hard limit (ceiling for rlim_cur)硬件支持最大值 */
           };

struc rlimit不仅可以设置产生coredump文件还可以设置很多系统资源:

RLIMIT_AS: 限制一个进程映射虚拟内存的大小。

RLIMIT_CORE:产生core dump文件。

RLIMIT_FSIZE:一个进程可以打开的文件数量。

...

4、调试过程

#include <sys/time.h>
#include <sys/resource.h>
#include<stdio.h>
#include <string.h>
#include<errno.h>

void fun_test(char *src, char *dst){

        strncpy(dst, src, strlen(src));
}
int main(){
        struct rlimit limit;
        if(0 != getrlimit(RLIMIT_CORE, &limit)){
                printf("%s", strerror(errno));
                return 0;
        }

        limit.rlim_cur = RLIM_INFINITY;  /*表示无穷大,不限制, 也可以指定core dump文大小*/
        limit.rlim_max = RLIM_INFINITY;

        if (0 == setrlimit(RLIMIT_CORE, &limit)){
                printf( "setrlimit core dump success.\n");
        }
        char *pr = NULL;
        char str[16] = {0};

        fun_test(pr, str);
        return 0;

}

编译运行产生了coredump文件core-setrlimit-18503-1543588372

产生coredump文件

调试通过gdb ,调试命令是gdb  进程名 coredump文件,然后通过where命令查看

gdb调试core dump文件

通过gdb调试我们知道程序挂在fun_test函数中的strlen函数,传进去一个野指针。

猜你喜欢

转载自blog.csdn.net/City_of_skey/article/details/84668911