信号处理函数
linux c提供了两个信号处理函数SIG_IGN、SIG_DFL。
- SIG_IGN:忽略信号
- SIG_DFL:信号默认处理函数
- 自定义处理函数:通过signal或sigaction注册自定义信号处理函数
注:信号SIGKILL、SIGSTOP不可捕获、不可忽略。
打印堆栈
#include <stdio.h>
#include <signal.h>
#include <execinfo.h>
void sigsegv_handler(int signum) {
void *array[10];
size_t size;
char **strings;
size_t i;
// 获取堆栈信息
size = backtrace(array, 10);
strings = backtrace_symbols(array, size);
printf("Received SIGSEGV signal. Printing stack trace:\n");
for (i = 0; i < size; i++) {
printf("%s\n", strings[i]);
}
free(strings);
// 执行默认的SIG_DFL处理函数
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV); // 触发SIGSEGV信号,执行默认处理函数
}
int main() {
// 设置SIGSEGV信号的处理函数为sigsegv_handler
struct sigaction sa;
sa.sa_handler = sigsegv_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGSEGV, &sa, NULL);
// 产生SIGSEGV信号
int *ptr = NULL;
*ptr = 10;
return 0;
}
在上述代码中,我们定义了一个sigsegv_handler函数作为SIGSEGV信号的处理函数。在该处理函数中,我们使用backtrace函数获取当前的堆栈信息,并使用backtrace_symbols函数将堆栈信息转换为可读的字符串数组。然后,我们打印堆栈信息,并释放字符串数组的内存。
接下来,我们使用signal函数将SIGSEGV信号的处理函数设置为sigsegv_handler,并使用raise函数手动触发SIGSEGV信号,以执行默认的SIG_DFL处理函数。
在main函数中,我们设置了SIGSEGV信号的处理函数为sigsegv_handler,然后故意产生了一个SIGSEGV信号,通过访问一个空指针来触发。
当运行上述代码时,如果程序收到SIGSEGV信号,它将首先打印堆栈信息,然后执行默认的SIG_DFL处理函数,通常是终止程序的执行。