Yanyg - Software Engineer

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