linux下用gdb实现程序宕机时自动打印调用堆栈

linux下程序运行几天莫名其妙宕机了,不能还原现场,找到宕机原因就很无语了。
一个解决办法是使用core文件,但是对于大型服务器文件,动辄几百M的core文件是在有点伤不起,于是想到程序宕机时自动打印调用堆栈。简单实用。
废话不多说,直接上方案:
方案1:使用gdb指令列表文件启动程序并监控之
启动指令 gdb -x gdb_start.ini
以下是gdb_start.ini文件内容:
fileMyApplication
set paginationoff
shell rm./logs/gdb_crash.log
set logging file./logs/gdb_crash.log
set loggingon
handle SIG32nostop noprint
handle SIGPIPEnostop noprint
handle SIGSEGVstop
handle SIGFPEstop
handle SIGILLstop
handle SIGABRTstop
handle SIGSYSstop
r 6660
print "crashtime:"
shell date>> ./logs/gdb_crash.log
print "crashframe:"
info f
print "crashlocals:"
info locals
print "crashcallstack:"
bt
set loggingoff
quit

这样程序宕机时将在gdb_crash.log中记录以下信息,太完美了:
Program receivedsignal SIGFPE, Arithmetic exception.
0x0804874a inmake_crash (nCrashType=1) at crash.c:50
50 z = 1/z;
$1 = "crashtime:"
2014年 08月 13日 星期三15:47:37 CST
$2 = "crashframe:"
Stack level 0,frame at 0xbf9e7900:
eip = 0x804874a inmake_crash (crash.c:50); saved eip 0x8048911
called by frame at0xbf9e7930
source languagec.
Arglist at0xbf9e78f8, args: nCrashType=1
Locals at0xbf9e78f8, Previous frame's sp is 0xbf9e7900
Savedregisters:
ebp at 0xbf9e78f8,edi at 0xbf9e78f4, eip at 0xbf9e78fc
$3 = "crashlocals:"
z = 0
__PRETTY_FUNCTION__ = "make_crash"
$4 = "crashcallstack:"
#0 0x0804874a in make_crash (nCrashType=1) atcrash.c:50
#1 0x08048911 in test_crash () at crash.c:105
#2 0x08048930 in main () at crash.c:119


方案2:程序内设置宕机监控代码
#include[stdio.h]
#include[stdlib.h]
#include[signal.h]
#include[string.h]
#include[unistd.h]

voidcrash_dump(int signo)
{
charbuf[1024];
charcmd[1024];
FILE *fh;

printf("crashdetected: crash_dump(%d)", signo);

snprintf(buf,sizeof(buf), "/proc/%d/cmdline", getpid());
if(!(fh =fopen(buf, "r")))
exit(0);
if(!fgets(buf,sizeof(buf), fh))
exit(0);
fclose(fh);
if(buf[strlen(buf)- 1] == '/n')
buf[strlen(buf) -1] = '/0';
snprintf(cmd,sizeof(cmd), "date > ./crash.log", buf, getpid());
printf(cmd);
system(cmd);
snprintf(cmd,sizeof(cmd), "gdb %s %d -ex=bt >> ./crash.log", buf,getpid());
printf(cmd);
system(cmd);

exit(-1);
}

int main(int argc,char* argv[])
{
//宕机输出调用堆栈
signal(SIGSEGV,&crash_dump);
signal(SIGFPE,&crash_dump);
signal(SIGINT,&crash_dump);
signal(SIGILL,&crash_dump);
signal(SIGABRT,&crash_dump);
//realcode...

return 0;
}

参考链接:
[1]http://www.cppblog.com/sunicdavy/archive/2012/12/29/196809.html
[2]http://blog.csdn.net/cindy9902/article/details/6146816
[3]http://blog.csdn.net/ifengle/article/details/3849783
[4]http://sourceware.org/gdb/wiki/FAQ#How_do_I_disable_the_.22Type_.3Creturn.3E_to_continue.2C_or_q_.3Creturn.3E_to_quit.22_pagination_prompt_in_GDB.3F

猜你喜欢

转载自blog.csdn.net/vipally/article/details/40952821