简体   繁体   English

分段故障处理程序中的分段错误

[英]Segmentation fault in segmentation fault handler

I have encountered in a problem where segmentation fault is being raised within segmentation fault handler. 我遇到了在分段错误处理程序中引发分段错误的问题。 Although I have already fixed the actual issue, but still I am confused that why below program is not going in infinite loop: 虽然我已经修复了实际问题,但我仍然感到困惑,为什么以下程序不会进入无限循环:

#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;
}

Output of the above code is as below: 以上代码的输出如下:

Came in sigaction.
Came in sigaction.
Segmentation fault (core dumped)

In the comments of this similar post: Segmentation fault within segmentation fault handler some folks have commented that it should go in infinite loop but it's not the current behavior. 在这篇类似文章的评论中: 分段错误处理程序中的分段错误一些人评论说它应该进入无限循环,但它不是当前的行为。 Can someone explain to me what's happening ?? 谁能向我解释发生了什么?

You are raising a signal while in a signal handler. 您在信号处理程序中发出信号。 The POSIX standard says : POSIX标准说

[table of safe functions] [安全功能表]

All functions not in the above table are considered to be unsafe with respect to signals. 上表中未包含的所有功能都被认为对信号不安全。 In the presence of signals, all functions defined by this volume of IEEE Std 1003.1-2001 shall behave as defined when called from or interrupted by a signal-catching function, with a single exception: when a signal interrupts an unsafe function and the signal-catching function calls an unsafe function , the behavior is undefined. 在存在信号的情况下,由IEEE Std 1003.1-2001卷定义的所有功能在信号捕获功能调用或中断时应按照定义运行,但有一个例外: 当信号中断不安全功能和信号时 - catch函数调用一个不安全的函数 ,行为是未定义的。

void C() is an unsafe function because it is not in the list of safe functions, therefore having it raise a signal causes undefined behaviour. void C()是一个不安全的函数,因为它不在安全函数列表中,因此让它引发信号会导致未定义的行为。 (I think it is also intended to mean that raising a signal from the signal handler function causes UB too, although the wording is unclear). (我认为它也意味着从信号处理函数中提升信号也会导致UB,尽管措辞不清楚)。

Being undefined behaviour, you cannot rely on an infinite loop or any other such behaviour. 作为未定义的行为,您不能依赖于无限循环或任何其他此类行为。

Other points: 其他要点:

  • Dereferencing null is undefined behaviour and is not guaranteed to generate a SIGSEGV in the first place. 取消引用null是未定义的行为,并且不保证首先生成SIGSEGV。
  • Calling printf in the signal handler is undefined behaviour because that is not one of the safe functions from the table either. 在信号处理程序中调用printf是未定义的行为,因为这也不是表中的安全函数之一。
  • It is also UB to return from a signal handler for SIGSEGV . SIGSEGV的信号处理程序返回也是UB。 The only portable way to get out of the signal handler is to abort the process with a call such as exit . 退出信号处理程序的唯一可移植方法是使用诸如exit的调用中止该过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM