LINUX系统通过信号捕捉进程调用栈
1 标题在说什么
开启core转储功能后,程序运行中发生严重错误(如SIGILL, SIGSEGV)后,生成core 文件,可用于分析发生问题时的调用栈。产品在实际运行时,既不希望-g编译影响性能,也没有足够的资源用于保存core,通过信号机制自行实现调用栈的打印,对问题分析可以带来积极作用。
编写会导致SIGSEGV的代码:
#include <stdio.h> static void func2() { char *p = NULL; printf("%s\n", __func__); *p = '\0'; /* core dump here ! */ } static void func1() { printf("%s\n", __func__); func2(); } static void func() { printf("%s\n", __func__); func1(); } int main(int argc, char *argv[argc]) { func(); return 0; }
运行调试
~$ gcc -o -g backtrace backtrace.c ~$ ulimit -c unlimited ~$ ./backtrace func func1 func2 Segmentation fault (core dumped) ~$ gdb backtrace core GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1 ... Type "apropos word" to search for commands related to "word"... Reading symbols from backtrace...done. [New LWP 5568] Core was generated by `./backtrace'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x0000000000400524 in func2 () at backtrace.c:7 7 *p = '\0'; /* core dump here ! */ (gdb) bt #0 0x0000000000400524 in func2 () at backtrace.c:7 #1 0x0000000000400541 in func1 () at backtrace.c:13 #2 0x000000000040055b in func () at backtrace.c:19 #3 0x0000000000400576 in main (argc=1, argv=0x7ffd21ea50a8) at backtrace.c:24
2 技术概述
基于信号处理机制,使用SRC_C{sigaction, sigfillset, sigdelset}定制信号处理回调,并通过SRC_C{sigaltstack}提供信号处理函数特有的栈,打印user context.
3 测试代码
// ignored