在Unix系统下,应用程序崩溃,一般会产生core文件,如何根据core文件查找问题的所在,并做相应的分析和调试,是非常重要的。
什么是Core Dump?Core的意思是内存, Dump的意思是扔出来, 堆出来.开 发和使用Unix程序时, 有时程序莫名其妙的down了,却没有任何的提示(有时候会提示core dumped). 这时候可以查看一下有没有形如core.进程号的文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的, 它可以做为调试程序的参考.
core dump又叫核心转储, 当程序运行过程中发生异常,程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.
为什么没有core文件生成呢?
有时候程序down了, 但是core文件却没有生成.core文件的生成跟你当前系统的环境设置有关系, 可以用下面的语句设置一下,然后再运行程序便成生成core文件.
ulimit -c unlimited
core文件生成的位置一般于运行程序的路径相同,文件名一般为core.进程号
当获得了core文件以后,就可以利用命令gdb进行查找,参数一是应用程序的名称,参数二是core文件
如: gdb [...]xmsd [...]/xmsd_PID1065_SIG11.core
ulimit -c unlimited
gdb test_svrd /data/corefile/test_svr_1334308671.20527
然后输入bt或者where找到错误发生的位置和相应的堆栈信息。就可知道发生错误时的函数调用关系,然后可以使用up或者down查看上一条和下一条具体详细信息。这样便能对问题进行大概定位,然后看源代码,进行分析。
eg:
(gdb) where
#0 0x0804ff8c inmemory_error (self=0x818ca10, ptr=0x82e5a94, msg=0x813efb2"memory_free") at/aston/h_debit/XMS/bin/XMS_1_15_11/src/xms/lib/memory.c:140
#1 0x080504cd inmemory_free (ptr=0x82e5a94) at/aston/h_debit/XMS/bin/XMS_1_15_11/src/xms/lib/memory.c:275
#2 0x080505ac inxml_free (ptr=0x82e5a94) at/aston/h_debit/XMS/bin/XMS_1_15_11/src/xms/lib/memory.c:316
#3 0xb7edb589 inxmlFreeNode () from/home/zhenbo/workstation/DEVSUITE-HEAD/debug/lib/libxml2.so
#4 0x082b2228 in ??()
#5 0x08097031 ininterfacehandler_set (self=0x82bd74c, correlator=-4, conf=0x0,cb=0x82b0aac) at/aston/h_debit/XMS/bin/XMS_1_15_11/src/interfaces/interfacehandler.c:150
#6 0x0805e897 inconfigurable_set (self=0x82bd74c, correlator=-4, conf=0x0,cb=0x82b0aac) at/aston/h_debit/XMS/bin/XMS_1_15_11/src/xms/xms/configurable.c:85
#7 0x0805e73c inconfigurable_flush (self=0x82bd74c, correlator=-4, cb=0x82b0aac) at/aston/h_debit/XMS/bin/XMS_1_15_11/src/xms/xms/configurable.c:67 #80x08100ddc in system_complete (self=0x82b0aac, correlator=-5,code=0
如果之前不能准确定位错误的位置,则从以上信息可以知道,可从函数interfacehandler_set入手进行分析,其中的参数和行号都已经给出了。
多线程如果dump,多为段错误,一般都涉及内存非法读写。可以这样处理,使用下面的命令打开系统开关,让其可以在死掉的时候生成core文件。
ulimit -cunlimited
这样的话死掉的时候就可以在当前目录看到core.pid(pid为进程号)的文件。接着使用gdb:
gdb ./bin./core.pid
进去后,使用bt查看死掉时栈的情况,在使用frame命令。
还有就是里面某个线程停住,也没死,这种情况一般就是死锁或者涉及消息接受的超时问题(听人说的,没有遇到过)。遇到这种情况,可以使用:
gcorepid (调试进程的pid号)
手动生成core文件,在使用pstack(linux下好像不好使)查看堆栈的情况。如果都看不出来,就仔细查看代码,看看是不是在if,return,break,continue这种语句操作是忘记解锁,还有嵌套锁的问题,都需要分析清楚了。