linux c程序崩溃前执行回调函数(包括打印core堆栈信息,也可以做我们想做的其他事情)
2018-08-04 16:51
288 查看
需求
如果程序崩溃的话,我们希望留下程序崩溃在的core信息,记录了程序崩溃的原因,崩溃的函数,甚至可以定位到文件的第几行
思想
实现思想很简单即是:使用信号捕捉。
具体思想:
例如我们捕捉到段错误信号,那么就去执行回调函数执行,记录core信息,而linux c为我们提供了打印core信息的函数即是backtrace()函数,获取函数调用堆栈帧数据
具体实现:
第一部分,建立信号捕捉集合
第二部分:写回调函数
第一部分,建立信号捕捉集合
#其中saveBackTrace为回调函数 signal(SIGSEGV, saveBackTrace); signal(SIGILL, saveBackTrace); signal(SIGFPE, saveBackTrace); signal(SIGABRT, saveBackTrace); signal(SIGTERM, saveBackTrace); signal(SIGKILL, saveBackTrace); signal(SIGXFSZ, saveBackTrace); // block SIGINT to all child process: sigset_t bset, oset; sigemptyset(&bset); sigaddset(&bset, SIGINT); // equivalent to sigprocmask #设置信号为阻塞信号 if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0) { printf("set thread signal mask error!"); return 0; }
第二部分:写回调函数
void saveBackTrace(int signal) { #先执行其他回调函数 if (pErrorExit != NULL) { (*pErrorExit)(); } time_t tSetTime; time( &tSetTime); tm ptm; #以生成core的日期为文件名 localtime_r(&tSetTime, &ptm) ; char fname[256] = {0}; sprintf(fname, "core.%d-%d-%d %d:%d:%d", ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec); FILE* f = fopen(fname, "a"); if (f == NULL) { return; } int fd = fileno(f); fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET)); char buffer[4096] = {0}; int count = readlink("/proc/self/exe", buffer, 4096); if(count > 0) { buffer[count] = '\n'; buffer[count + 1] = 0; fwrite(buffer, 1, count + 1, f); fflush(f); } sprintf(buffer, "Dump Time: %d-%d-%d %d:%d:%d\n", ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec); fwrite(buffer, 1, strlen(buffer), f); fflush(f); #记录捕捉到的信号 strcpy(buffer, "Catch signal: "); switch (signal) { case SIGSEGV: strcat(buffer, "SIGSEGV\n"); break; case SIGILL: strcat(buffer, "SIGILL\n"); break; case SIGFPE: strcat(buffer, "SIGFPE\n"); break; case SIGABRT: strcat(buffer, "SIGABRT\n"); break; case SIGTERM: strcat(buffer, "SIGTERM\n"); break; case SIGKILL: strcat(buffer, "SIGKILL\n"); break; case SIGXFSZ: strcat(buffer, "SIGXFSZ\n"); break; default: sprintf(buffer, "Catch signal: %d\n", signal); break; } fwrite(buffer, 1, strlen(buffer), f); fflush(f); #打印一些全局变量 sprintf(buffer, "Processing cmd: %d\n", g_processingCmd); fwrite(buffer, 1, strlen(buffer), f); fflush(f); sprintf(buffer, "Processing uid: %lld\n", g_processingUID); fwrite(buffer, 1, strlen(buffer), f); fflush(f); #打印堆栈信息 void* DumpArray[256]; int nSize = backtrace(DumpArray, 256); char** symbols = backtrace_symbols(DumpArray, nSize); if (symbols) { if (nSize > 256) { nSi 4000 ze = 256; } if (nSize > 0) { for (int i = 0; i < nSize; i++) { fwrite(symbols[i], 1, strlen(symbols[i]), f); fwrite("\n", 1, 1, f); fflush(f); } } free(symbols); } fcntl(fd, F_SETLK, file_lock(F_UNLCK, SEEK_SET)); fclose(f); exit(1); #endif }阅读更多
相关文章推荐
- linux程序跑挂时堆栈信息日志打印
- Linux有时候执行了 rm -rf 等操作误删了文件绝对是一件可怕的事情,好在有一些解决的办法可以临时救急。这时我们就要用到一款叫做extundelete的工具了。
- Linux下的C++程序崩溃时打印崩溃信息
- Linux调用backtrack函数打印程序崩溃时的调用堆栈
- Linux调用backtrack函数打印程序崩溃时的调用堆栈
- Linux调用backtrack函数打印程序崩溃时的调用堆栈
- Linux调用backtrack函数打印程序崩溃时的调用堆栈
- Linux调用backtrack函数打印程序崩溃时的调用堆栈
- linux 输出执行时的堆栈信息
- linux下打开core功能,以便于通过gdb查看出错堆栈信息
- 在linux下利用程序崩溃后的core文件分析bug
- Linux程序可以编译连接但是执行时找不到*.so 一般都和LD_LIBRARY_PATH有关
- Linux中gdb 查看core堆栈信息
- 用c++语言编写程序实现学生成绩录入,学生信息编辑,以及学生信息(包括成绩,编号)打印
- linux下开启程序崩溃生成core文件开关之ulimit详解
- Linux中gdb 查看core堆栈信息
- 微信小程序 引用其他js里的方法 转载 2017年03月02日 17:07:04 标签:微信小程序 5754 微信小程序 引用其他js里的方法 微信小程序中,在微信官方开发文档我们可以知道 小程序的
- linux查看用户操作或程序执行的一些信息
- Linux中gdb 查看core堆栈信息
- Linux 获取并分析程序崩溃时的调用堆栈