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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章