[英]Segmentation fault in segmentation fault handler
我遇到了在分段错误处理程序中引发分段错误的问题。 虽然我已经修复了实际问题,但我仍然感到困惑,为什么以下程序不会进入无限循环:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void C()
{
int *p = NULL;
*p = 3;
}
void B()
{
C();
}
void segfault_sigaction(int signal, siginfo_t *si, void *arg)
{
printf("Came in sigaction.\n");
//if(si)
//printf("Caught segfault at address %p\n", si->si_addr);
B();
}
int main(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = segfault_sigaction;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
segfault_sigaction(0, NULL, NULL);
return 0;
}
以上代码的输出如下:
Came in sigaction.
Came in sigaction.
Segmentation fault (core dumped)
在这篇类似文章的评论中: 分段错误处理程序中的分段错误一些人评论说它应该进入无限循环,但它不是当前的行为。 谁能向我解释发生了什么?
您在信号处理程序中发出信号。 POSIX标准说 :
[安全功能表]
上表中未包含的所有功能都被认为对信号不安全。 在存在信号的情况下,由IEEE Std 1003.1-2001卷定义的所有功能在信号捕获功能调用或中断时应按照定义运行,但有一个例外: 当信号中断不安全功能和信号时 - catch函数调用一个不安全的函数 ,行为是未定义的。
void C()
是一个不安全的函数,因为它不在安全函数列表中,因此让它引发信号会导致未定义的行为。 (我认为它也意味着从信号处理函数中提升信号也会导致UB,尽管措辞不清楚)。
作为未定义的行为,您不能依赖于无限循环或任何其他此类行为。
其他要点:
printf
是未定义的行为,因为这也不是表中的安全函数之一。 SIGSEGV
的信号处理程序返回也是UB。 退出信号处理程序的唯一可移植方法是使用诸如exit
的调用中止该过程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.