利用backtrace可以在程序crash退出之前,打印出crash时的堆栈信息,有助于我们分析crash问题。下面,教大家如何在linux下利用backtrace打印crash堆栈信息。
1. 引入头文件
# include <signal.h>
2. 初始化backtrace
struct sigaction newAct; newAct.sa_handler = NaviBackTrace; sigemptyset( &newAct.sa_mask ); sigaction(SIGABRT, &newAct, NULL); sigaction(SIGSEGV, &newAct, NULL); sigaction(SIGBUS, &newAct, NULL); sigaction(SIGFPE, &newAct, NULL); sigaction(SIGILL, &newAct, NULL); sigaction(SIGTRAP, &newAct, NULL);
其中NaviVackTrace
为程序发生crash,退出之前的回调函数,在此函数中可以做一些事情,例如打印crash堆栈,通知其它程序该程序crash等。
3. NaviBackTrace函数
static void NaviBackTrace(int signalNum) { printf("NaviBackTrace signalNum[%d]", signalNum); usleep(1000 * 1000); if (signalNum == SIGABRT) { printf("Start print stack information(SIGABRT)."); } else if (signalNum == SIGSEGV) { printf("Start print stack information(SIGSEGV)."); } else if (signalNum == SIGBUS) { printf("Start print stack information(SIGBUS)."); } else if (signalNum == SIGFPE) { printf("Start print stack information(SIGFPE)."); } else if (signalNum == SIGILL) { printf("Start print stack information(SIGILL)."); } else if (signalNum == SIGTRAP) { printf("Start print stack information(SIGTRAP)."); } void * array[100]; int nSize = backtrace(array, 100); char ** symbols = backtrace_symbols(array, nSize); printf("process id(%d), thread id(%u)", getpid(), (unsigned int)pthread_self()); for (int i = 1; i < nSize; i++) { printf("%s", symbols[i]); } printf("End print stack information."); free(symbols); signal(SIGABRT, SIG_DFL); signal(SIGSEGV, SIG_DFL); signal(SIGBUS, SIG_DFL); signal(SIGFPE, SIG_DFL); signal(SIGILL, SIG_DFL); signal(SIGTRAP, SIG_DFL); }