1. 程式人生 > >linux下用gdb實現程式宕機時自動列印呼叫堆疊

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