? ? ? ? 打印調用棧可以在程序出現死機的時候(如出現 SIGABRT、SIGSEGV等一些信號錯誤)是很有用的信息,有可能就不需要 core file 來協助排查問題了。通過 man backtrace 可以得到一個例子的源碼:
#define SIZE 100
static void backTracePro(void)
{ int j, nptrs; void *buffer[SIZE]; char **strings; nptrs = backtrace(buffer, SIZE);printf("****************************************\n");//這行我自己加的printf("backtrace() returned %d addresses\n", nptrs); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++){printf("%s\n", strings[j]); }free(strings);
}
然后可以把這個函數放在信號回調函數里,所以先需要設置一下信號處理函數,函數:int sigaction (int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact),
static bool initSignalCallBack()
{struct sigaction sigact;memset(&sigact, 0, sizeof(sigact));sigact.sa_handler = signalHandler;sigemptyset(&(sigact.sa_mask));int ret = sigaction(SIGABRT, &sigact, NULL);if(0 == ret){ret |= sigaction(SIGSEGV, &sigact, NULL);}else{strerror(errno);return false;}if(ret){strerror(errno);}return ret == 0;
}
所以可以把?backTracePro() 放到信號回調函數?signalHandler() 里,看看執行結果:
接下來用 c++filt 解析一下符號就可以看到調用到哪個函數了。?