1.在Linux上当执行文件出现异常时,通常直接结束,或者生成coredump文件,debug时步骤繁琐,今天看到一种方法,在不改变原程序的情况下打印callstrace。主要做法是在程序执行时,为它注册异常信号处理函数。
2.代码
signal_lib.c #include <stdlib.h> #include <stdio.h> #include <stddef.h> #include <signal.h> #include <execinfo.h> #define SIMPLE_WAY #define ADDR_MAX_NUM 100 void sighandler(intsigno) { #ifndef SIMPLE_WAY exit(signo); #else printf ("CALLBACK: SIGNAL:\n", iSignalNo); void *pBuf[ADDR_MAX_NUM] = {0}; int iAddrNum = backtrace(pBuf, ADDR_MAX_NUM); printf("BACKTRACE: NUMBER OF ADDRESSES IS:%d\n\n", iAddrNum); char ** strSymbols = backtrace_symbols(pBuf, iAddrNum); if (strSymbols == NULL) { printf("BACKTRACE: CANNOT GET BACKTRACE SYMBOLS\n"); return; } int ii = 0; for (ii = 0; ii < iAddrNum; ii++) { printf("%03d %s\n", iAddrNum-ii, strSymbols[ii]); } printf("\n"); free(strSymbols); strSymbols = NULL; exit(1); // QUIT PROCESS. IF NOT, MAYBE ENDLESS LOOP. #endif } __attribute__ ((constructor))voidctor(){ intsigs[] = { SIGILL, SIGFPE, SIGABRT, SIGBUS, SIGSEGV, SIGHUP, SIGINT, IGQUIT, SIGTERM }; int i; structsigaction sa; sa.sa_handler = sighandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESETHAND; for(i = 0; i < sizeof(sigs)/sizeof(sigs[0]); ++i) { if(sigaction(sigs[i], &sa, NULL) == -1) { perror("Could not set signal handler"); } } } 编译: gcc -shared -fPIC signal_lib.c -o signal_lib.so 执行: LD_PRELOAD=./signal_lib.so ./daemon