1. 程式人生 > >linux程式跑掛時堆疊資訊日誌列印

linux程式跑掛時堆疊資訊日誌列印

程式碼如下:

void gdb_signal_handler(int signo)
{
	char buff[64] = {0};
	sprintf(buff,"cat /proc/%d/maps", getpid());
	system((const char*) buff);
	
	void *buffer[16];
	char **strings;
	char log[1024 * 2] = {0};
	
	int nptrs = backtrace(buffer, 16);//#define BACKTRACE_SIZE   16
	
	strings = backtrace_symbols(buffer, nptrs);
	if (strings == NULL) 
	{
		perror("backtrace_symbols");
		exit(EXIT_FAILURE);
	}
 
	int len = 0;
	len += sprintf(log + len, "*************************************************************\r\n");
	len += sprintf(log + len, "the abnormal signal No : %d \r\n", signo);
	for (int i = 1; i < nptrs; i++)
	{
		len += sprintf(log + len, "[%02d] %s\r\n", i, strings[i]);
	}
	len += sprintf(log + len, "*************************************************************\r\n");
	
    time_t timep;
    struct tm *p = NULL;
    time(&timep); 
    p = localtime(&timep);

	char FileName[32] = {0};
	sprintf(FileName,"/tmp/gdb.log.%04d_%02d_%02d", (1900+p->tm_year), p->tm_mon+1, p->tm_mday);
	
	FILE * pFile;
	pFile = fopen(FileName,"w");
	if (pFile != NULL)
	{
		fputs (log,pFile);
		fclose(pFile);
	}
 
	free(strings);
 
	signal(signo, SIG_DFL); /* 恢復訊號預設處理 */
	raise(signo);           /* 重新發送訊號 */
}


void GdbInit()
{		
	signal(SIGHUP , gdb_signal_handler); 
	signal(SIGABRT, gdb_signal_handler); 
	signal(SIGSEGV, gdb_signal_handler); 
	signal(SIGPIPE, gdb_signal_handler); 

	return;
}

1)編譯時加上-rdynamic

CFLAGS +=-g -rdynamic

2)在呼叫時,主函式入口初始化GdbInit()就行。

3)用add2line -C -e filename addr解析