C/C++程序崩溃之——core文件

一、ulimit是什么?
ulimit -a 用来显示当前的各种用户进程限制
Linux对于每个用户,系统限制其最大进程数,为提高性能,可以根据设备资源情况,
设置个Linux用户的最大进程数,一些需要设置为无限制:
数据段长度:ulimit -d unlimited
最大内存大小:ulimit -m unlimited
堆栈大小:ulimit -s unlimited
我们在用这个命令的时候主要是为了产生core文件,就是程序运行发行段错误时的文件。

二、ulimit命令
功能说明:控制shell程序的资源。
语  法:ulimit [-aHS][-c ][-d <数据节区大小>][-f <文件大小>][-m <内存大小>][-n <文件数目>][-p <缓冲区大小>][-s <堆叠大小>][-t ][-u <程序数目>][-v <虚拟内存大小>]
补充说明:ulimit为shell内建指令,可用来控制shell执行程序的资源。
参  数:
   -a  显示目前资源限制的设定。 
   -c  设定core文件的最大值,单位为区块。 
   -d <数据节区大小>  程序数据节区的最大值,单位为KB。 
   -f <文件大小>  shell所能建立的最大文件,单位为区块。 
   -H  设定资源的硬性限制,也就是管理员所设下的限制。 
   -m <内存大小>  指定可使用内存的上限,单位为KB。 
   -n <文件数目>  指定同一时间最多可开启的文件数。 
   -p <缓冲区大小>  指定管道缓冲区的大小,单位512字节。 
   -s <堆叠大小>  指定堆叠的上限,单位为KB。 
   -S  设定资源的弹性限制。 
   -t  指定CPU使用时间的上限,单位为秒。 
   -u <程序数目>  用户最多可开启的程序数目。 
   -v <虚拟内存大小>  指定可使用的虚拟内存上限,单位为KB。

 
三、coredump文件的生成和路径配置
当系统中的一些程序在遇到一些错误以及crash时,系统会自动产生core文件记录crash时刻系统信息,包括内存和寄存器信息,用以程序员日 后debug时可以使用。这些错误包括段错误、非法指令、总线错误或用户自己生成的退出信息等等,一般地,core文件在当前文件夹中存放。
core文件有时可能在你发生错误时,并没有出现在你当前的文件夹中,发生这种情况的原因有两个:一个是当前终端被设置为不能弹出core文件;另一种则是core文件被指定了路径。
1、coredump文件生成和大小控制
对于前者,我们可以使用ulimit命令对core文件的大小进行设定。一般默认情况下,core文件的大小被设置为0,这样系统就不dump出core文件了。这时,使用命令:ulimit -c unlimited进行设置,就可以把core文件的大小设置为无限大,同时也可以使用数字来替代unlimited,对core文件的上限制做更精确的设定。
开启或关闭core文件的生成:
ulimit -c 可以查看是否打开此选项,若为0则为关闭;
ulimit -c 0可手动关闭
ulimit -c 1000 为设置core文件大小最大为1000k
ulimit -c unlimited 设置core文件大小为不限制大小
2、coredump文件路径控制
除了可以设置core文件的大小之外,还可以对core文件的名称进行一些规定。这种设置是对/proc/sys/kernel/core_pattern和/proc/sys/kernel/core_uses_pid这两个文件进行修改。改动这两个文件的方法如下:
echo > /proc/sys/kernel/core_pattern
echo <"0"/"1"> /proc/sys/kernel/core_uses_pid
并且注意,只有超级用户才可以修改这两个表。
core_pattern接受的是core文件名称的pattern,它包含任何字符串,并且用%作为转移符号生成一些标示符,为core文件名称加入特殊含义。已定义的标示符有如下这些:
%%:相当于%
%p:相当于
%u:相当于
%g:相当于
%s:相当于导致dump的信号的数字
%t:相当于dump的时间
%e:相当于执行文件的名称
%h:相当于hostname
除以上这些标志位外,还规定:
1)末尾的单个%可以直接去除;
2)%加上除上述以外的任何字符,%和该字符都会被去除;
3)所有其他字符都作为一般字符加入名称中;
4)core文件的名称最大值为64个字节(包括'\0');
5)core_pattern中默认的pattern为core;
6)为了保持兼容性,通过设置core_uses_pid,可以在core文件的末尾加上%p;
7)pattern中可以包含路径信息。

三、使用tips
很多系统在默认的情况下是关闭生成core文件的,这个命令可以加到你的profile中去。

四、调试示例

#include
#include
#include
#include

int main(int argc, char **argv)
{
    int rnum = 0;
    int *goodptr = malloc(sizeof(int));
    int *badptr = NULL;

    srand(time(NULL));
    while(1) {
        rnum = rand() % 255;
        if(rnum == 13) {
            *badptr = rnum;
        } else {
            *goodptr = rnum;
        }
        printf("random: %d\n", rnum);
        usleep(100);
    }
}

1)ulimit -c unlimited

2)生成core文件

4)gdb   coredump.exe    core文件

denglin@DESKTOP-U4BE2GM:~/Documents/cpp$ gdb coredump.exe core
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
---Type  to continue, or q  to quit---
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from coredump.exe...done.
[New LWP 868]
Core was generated by `./coredump.exe'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055f92a5e3893 in main (argc=1, argv=0x7ffe84c1fb08) at coredump.c:16
16                  *badptr = rnum;
(gdb) p rum
No symbol "rum" in current context.
(gdb) p rnum
$1 = 13
(gdb) print badptr
$2 = (int *) 0x0
(gdb) 

你可能感兴趣的:(coredump,gdb)