具体解释coredump
一,什么是coredump
我们常常听到大家说到程序core掉了,须要定位解决,这里说的大部分是指相应程序因为各种异常或者bug导致在执行过程中异常退出或者中止,而且在满足一定条件下(这里为什么说须要满足一定的条件呢?以下会分析)会产生一个叫做core的文件。
通常情况下,core文件会包括了程序执行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,我们能够理解为是程序工作当前状态存储生成第一个文件,很多的程序出错的时候都会产生一个core文件,通过工具分析这个文件,我们能够定位到程序异常退出的时候相应的堆栈调用等信息,找出问题所在并进行及时解决。
二,coredump文件的存储位置
core文件默认的存储位置与相应的可运行程序在同一文件夹下,文件名称是core,大家能够通过以下的命令看到core文件的存在位置:
cat /proc/sys/kernel/core_pattern
缺省值是core
注意:这里是指在进程当前工作文件夹的下创建。通常与程序在同样的路径下。但假设程序中调用了chdir函数,则有可能改变了当前工作文件夹。这时core文件创建在chdir指定的路径下。有好多程序崩溃了,我们却找不到core文件放在什么位置。和chdir函数就有关系。当然程序崩溃了不一定都产生 core文件。
例如以下程序代码:则会把生成的core文件存储在/data/coredump/wd,而不是大家觉得的跟可运行文件在同一文件夹。
通过以下的命令能够更改coredump文件的存储位置,若你希望把core文件生成到/data/coredump/core文件夹下:
echo “/data/coredump/core”> /proc/sys/kernel/core_pattern
注意,这里当前用户必须具有对/proc/sys/kernel/core_pattern的写权限。
缺省情况下,内核在coredump时所产生的core文件放在与该程序同样的文件夹中,而且文件名称固定为core。非常显然,假设有多个程序产生core文件,或者同一个程序多次崩溃,就会反复覆盖同一个core文件,因此我们有必要对不同程序生成的core文件进行分别命名。
我们通过改动kernel的參数,能够指定内核所生成的coredump文件的文件名称。比如,使用以下的命令使kernel生成名字为core.filename.pid格式的core dump文件:
echo “/data/coredump/core.%e.%p” >/proc/sys/kernel/core_pattern
这样配置后,产生的core文件里将带有崩溃的程序名、以及它的进程ID。上面的%e和%p会被替换成程序文件名称以及进程ID。
假设在上述文件名称中包括文件夹分隔符“/”,那么所生成的core文件将会被放到指定的文件夹中。 须要说明的是,在内核中另一个与coredump相关的设置,就是/proc/sys/kernel/core_uses_pid。假设这个文件的内容被配置成1,那么即使core_pattern中没有设置%p,最后生成的core dump文件名称仍会加上进程ID。
三,怎样推断一个文件是coredump文件?
在类unix系统下,coredump文件本身基本的格式也是ELF格式,因此,我们能够通过readelf命令进行推断。
能够看到ELF文件头的Type字段的类型是:CORE (Core file)
能够通过简单的file命令进行高速推断:
四,产生coredum的一些条件总结
1, 产生coredump的条件,首先须要确认当前会话的ulimit –c,若为0,则不会产生相应的coredump,须要进行改动和设置。
ulimit -c unlimited (能够产生coredump且不受限制大小)
若想甚至相应的字符大小,则能够指定:
ulimit –c [size]
能够看出,这里的size的单位是blocks,一般1block=512bytes
如:
ulimit –c 4 (注意,这里的size假设太小,则可能不会产生相应的core文件,笔者设置过ulimit –c 1的时候,系统并不生成core文件,并尝试了1,2,3均无法产生core,至少须要4才生成core文件)
但当前设置的ulimit仅仅对当前会话有效,若想系统均有效,则须要进行例如以下设置:
Ø 在/etc/profile中增加下面一行,这将同意生成coredump文件
ulimit-c unlimited
Ø 在rc.local中增加下面一行,这将使程序崩溃时生成的coredump文件位于/data/coredump/文件夹下:
echo /data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern
注意rc.local在不同的环境,存储的文件夹可能不同,susu下可能在/etc/rc.d/rc.local
很多其它ulimit的命令使用,能够參考:http://baike.baidu.com/view/4832100.htm
这些须要有root权限, 在ubuntu下每次又一次打开中断都须要又一次输入上面的ulimit命令, 来设置core大小为无限.
2, 当前用户,即运行相应程序的用户具有对写入core文件夹的写权限以及有足够的空间。
3, 几种不会产生core文件的情况说明:
The core file will not be generated if
(a) the process was set-user-ID and the current user is not the owner of the program file, or
(b) the process was set-group-ID and the current user is not the group owner of the file,
(c) the user does not have permission to write in the current working directory,
(d) the file already exists and the user does not have permission to write to it, or
(e) the file is too big (recall the RLIMIT_CORE limit in Section 7.11). The permissions of the core file (assuming that the file doesn't already exist) are usually user-read and user-write, although Mac OS X sets only user-read.
五,coredump产生的几种可能情况
造成程序coredump的原因有非常多,这里总结一些比較经常使用的经验吧:
1,内存訪问越界
a) 因为使用错误的下标,导致数组訪问越界。
b) 搜索字符串时,依靠字符串结束符来推断字符串是否结束,可是字符串没有正常的使用结束符。
c) 使用strcpy, strcat, sprintf, strcmp,strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。
2,多线程程序使用了线程不安全的函数。
应该使用以下这些可重入的函数,它们非常easy被用错:
asctime_r(3c) gethostbyname_r(3n) getservbyname_r(3n)ctermid_r(3s) gethostent_r(3n) getservbyport_r(3n) ctime_r(3c) getlogin_r(3c)getservent_r(3n) fgetgrent_r(3c) getnetbyaddr_r(3n) getspent_r(3c)fgetpwent_r(3c) getnetbyname_r(3n) getspnam_r(3c) fgetspent_r(3c)getnetent_r(3n)
gmtime_r(3c) gamma_r(3m) getnetgrent_r(3n) lgamma_r(3m) getauclassent_r(3)getprotobyname_r(3n) localtime_r(3c) getauclassnam_r(3) etprotobynumber_r(3n)nis_sperror_r(3n) getauevent_r(3) getprotoent_r(3n) rand_r(3c) getauevnam_r(3)getpwent_r(3c) readdir_r(3c)
getauevnum_r(3) getpwnam_r(3c) strtok_r(3c) getgrent_r(3c)getpwuid_r(3c) tmpnam_r(3s) getgrgid_r(3c) getrpcbyname_r(3n) ttyname_r(3c)getgrnam_r(3c) getrpcbynumber_r(3n) gethostbyaddr_r(3n) getrpcent_r(3n)
3,多线程读写的数据未加锁保护。
对于会被多个线程同一时候訪问的全局数据,应该注意加锁保护,否则非常easy造成coredump
4,非法指针
a) 使用空指针
b) 任意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这样的结构或类型的数组,否则不要将它转换为这样的结构或类型的指针,而应该将这段内存复制到一个这样的结构或类型中,再訪问这个结构或类型。这是由于假设这段内存的開始地址不是依照这样的结构或类型对齐的,那么訪问它时就非常easy由于bus error而core dump。
5,堆栈溢出
不要使用大的局部变量(由于局部变量都分配在栈上),这样easy造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
六,利用gdb进行coredump的定位
事实上分析coredump的工具有非常多,如今大部分类unix系统都提供了分析coredump文件的工具,只是,我们经经常使用到的工具是gdb。
这里我们以程序为样例来说明怎样进行定位。
1, 段错误 – segmentfault
Ø 我们写一段代码往受到系统保护的地址写内容。
Ø 按例如以下方式进行编译和运行,注意这里须要-g选项编译。
能够看到,当输入12的时候,系统提示段错误而且core dumped
Ø 我们进入相应的core文件生成文件夹,优先确认是否core文件格式并启用gdb进行调试。
从红色方框截图能够看到,程序中止是由于信号11,且从bt(backtrace)命令(或者where)能够看到函数的调用栈,即程序运行到coremain.cpp的第5行,且里面调用scanf 函数,而该函数事实上内部会调用_IO_vfscanf_internal()函数。
接下来我们继续用gdb,进行调试相应的程序。
记住几个经常使用的gdb命令:
l(list) ,显示源码,而且能够看到相应的行号;
b(break)x, x是行号,表示在相应的行号位置设置断点;
p(print)x, x是变量名,表示打印变量x的值
r(run), 表示继续运行到断点的位置
n(next),表示运行下一步
c(continue),表示继续运行
q(quit),表示退出gdb
启动gdb,注意该程序编译须要-g选项进行。
注: SIGSEGV 11 Core Invalid memoryreference
七,附注:
1, gdb的查看源代码
显示源码
GDB 能够打印出所调试程序的源码,当然,在程序编译时一定要加上-g的參数,把源程序信息编译到运行文件里。不然就看不到源程序了。当程序停下来以后,GDB会报告程序停在了那个文件的第几行上。你能够用list命令来打印程序的源码。还是来看一看查看源码的GDB命令吧。
list<linenum>
显示程序第linenum行的周围的源程序。
list<function>
显示函数名为function的函数的源程序。
list
显示当前行后面的源程序。
list -
显示当前行前面的源程序。
通常是打印当前行的上5行和下5行,假设显示函数是是上2行下8行,默认是10行,当然,你也能够定制显示的范围,使用以下命令能够设置一次显示源程序的行数。
setlistsize <count>
设置一次显示源码的行数。
showlistsize
查看当前listsize的设置。
list命令还有以下的使用方法:
list<first>, <last>
显示从first行到last行之间的源码。
list ,<last>
显示从当前行到last行之间的源码。
list +
往后显示源码。
一般来说在list后面能够跟下面这些參数:
<linenum> 行号。
<+offset> 当前行号的正偏移量。
<-offset> 当前行号的负偏移量。
<filename:linenum> 哪个文件的哪一行。
<function> 函数名。
<filename:function>哪个文件里的哪个函数。
<*address> 程序执行时的语句在内存中的地址。
2, 一些经常使用signal的含义
SIGABRT:调用abort函数时产生此信号。进程异常终止。
SIGBUS:指示一个实现定义的硬件故障。
SIGEMT:指示一个实现定义的硬件故障。EMT这一名字来自PDP-11的emulator trap 指令。
SIGFPE:此信号表示一个算术运算异常,比如除以0,浮点溢出等。
SIGILL:此信号指示进程已运行一条非法硬件指令。4.3BSD由abort函数产生此信号。SIGABRT如今被用于此。
SIGIOT:这指示一个实现定义的硬件故障。IOT这个名字来自于PDP-11对于输入/输出TRAP(input/outputTRAP)指令的缩写。系统V的早期版本号,由abort函数产生此信号。SIGABRT如今被用于此。
SIGQUIT:当用户在终端上按退出键(一般採用Ctrl-/)时,产生此信号,并送至前台进
程组中的全部进程。此信号不仅终止前台进程组(如SIGINT所做的那样),同一时候产生一个core文件。
SIGSEGV:指示进程进行了一次无效的存储訪问。名字SEGV表示“段违例(segmentationviolation)”。
SIGSYS:指示一个无效的系统调用。因为某种未知原因,进程运行了一条系统调用指令,但其指示系统调用类型的參数却是无效的。
SIGTRAP:指示一个实现定义的硬件故障。此信号名来自于PDP-11的TRAP指令。
SIGXCPUSVR4和4.3+BSD支持资源限制的概念。假设进程超过了其软C P U时间限制,则产生此信号。
SIGXFSZ:假设进程超过了其软文件长度限制,则SVR4和4.3+BSD产生此信号。
3, Core_pattern的格式
能够在core_pattern模板中使用变量还非常多,见以下的列表:
%% 单个%字符
%p 所dump进程的进程ID
%u 所dump进程的实际用户ID
%g 所dump进程的实际组ID
%s 导致本次core dump的信号
%t core dump的时间 (由1970年1月1日计起的秒数)
%h 主机名
%e 程序文件名称
具体解释coredump的更多相关文章
- 嵌入式系统coredump设计
阴沟翻船,马失前蹄,说明凡事皆有可能.自然,程序设计的再好,也会有crash的时候.开发期还还说,正式交付的系统crash自然更是难以承受的.无论何时,死一次就够了,得有方法查个水落石出. 几年前哥去 ...
- ZIP压缩算法详细分析及解压实例解释
最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...
- 说说BPM数据表和日志表中几个状态字段的详细解释
有个客户说需要根据这些字段的值作为判断条件做一些定制化需求,所以需要知道这些字段的名词解释,以及里面存储的值具体代表什么意思 我只好为你们整理奉上这些了! Open Work Sheet 0 Sav ...
- 【完全开源】知乎日报UWP版:项目结构说明、关键源代码解释
目录 说明 项目结构 关键代码 演示视频 说明 上一篇博客将源码放出来了,但是并没有做过多的介绍,所以如果自己硬看可能需要花费很长的时间,尤其这些代码并不是自己写的.项目不算复杂但是也不算简单,这篇文 ...
- nodejs、npm、grunt——名词解释
最近着手开发一个新项目,打算从工程化的角度整理一套自己的前端开发.发布体系. grunt这些工具,之前别人用我也用,并没有认真想过它们的前世今生,正好趁着这个机会,我来理一理目前业界比较流行这些工具的 ...
- HTTP各状态码解释
状态码 含义 100 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必 ...
- JavaScript中‘this’关键词的优雅解释
本文转载自:众成翻译 译者:MinweiShen 链接:http://www.zcfy.cc/article/901 原文:https://rainsoft.io/gentle-explanation ...
- XML简介与CDATA解释
简介XML 是一种受到广泛支持的 Internet 标准,用于以一种特殊的方式编码结构化数据.实际上,以 XML 编码的数据可以通过任何编程语言解码,人们甚至可以使用标准的文本编辑器来阅读或编写 XM ...
- free-简单明了解释清楚怎么看内存使用
free命令可以用来查看系统内存使用情况.我一般习惯-m参数以MB的方式查看 [root@localhost ~]# free -m total used free shared buffers ca ...
随机推荐
- 学会了 C 语言真的可以开发出很多东西吗?
马里奥碰到花朵就变身. 什么是马里奥?一个装着 16 × 32 个小色块的长方形,其中一些色块填着颜色,另一些没有.什么是花?一个 16 × 16 的正方形.什么是「变身」?把马里奥这个方块里面代表衣 ...
- Ztree异步树加载
JSP代码片段 <%@ page language="java" contentType="text/html; charset=utf-8" pageE ...
- SQL Server 通配符为目标字符的查找
create table t(x int identity(1,1) primary key,v nvarchar(32));go insert into t(v) values('this is % ...
- perspective结合transform的3D效果
http://css-tricks.com/almanac/properties/p/perspective/ 链接中讲了 perspective的两种用法及比较: 1.perspective:100 ...
- Mybatis的ResultMap的使用(转)
本篇文章通过一个实际工作中遇到的例子开始吧: 工程使用Spring+Mybatis+Mysql开发.具体的业务逻辑很重,对象之间一层一层的嵌套.和数据库表对应的是大量的model类,而和前端交互的是V ...
- Highlighting an element as it is hovered over (like inspect element in FireBug) - jQuery Forum
Highlighting an element as it is hovered over (like inspect element in FireBug) - jQuery Forum Highl ...
- Codeforce 424C Magic Formulas 找规律
题目链接:http://codeforces.com/contest/424/problem/C 题意:求Q值 思路:找规律 显然能够得到一个矩阵 把这个矩阵画出来就能发现一个横向的规律和一个主对角线 ...
- 《网络编程》Unix 域套接字
概述 Unix 域套接字是一种client和server在单主机上的 IPC 方法.Unix 域套接字不运行协议处理,不须要加入或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套 ...
- xcode initWithCoder\awakeFromNib\layoutSubviews
控件通过xib,storyboard创建,初始化设置一定会调用initWithCoder awakeFromNib 加载完毕的时候肯定会调用 layoutSubviews 布局子控件 位置和尺寸 利用 ...
- 2015 5.16 C# 继承和多态
类的层次结构有两种基本的构造方式 自顶向下 自底向上 基类的保护成员是指允许派生类的方法代码访问,而不是指通过派生类的对象访问 如果基类中的字段通过公有且可读写的属性进行了封装,那么建议将字段定义 ...