分割故障处理

时间:2021-09-23 20:44:30

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 ??

在这篇类似文章的评论中:分割错误处理程序中的分割错误有些人评论说它应该是无限循环的,但它不是当前的行为。有人能向我解释一下发生了什么事吗?

1 个解决方案

#1


2  

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这本书应当像定义从或signal-catching打断了函数调用的时候,有一个例外:当一个信号中断不安全功能和signal-catching函数调用一个不安全的函数,其行为是未定义的。

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. (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).

void C()是一个不安全的函数,因为它不在安全函数列表中,因此它发出信号会导致未定义的行为。(我认为这也意味着从信号处理函数中提取信号也会导致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. The only portable way to get out of the signal handler is to abort the process with a call such as exit.
  • 它也是从SIGSEGV的信号处理器返回的UB。离开信号处理程序的惟一可移植性方法是使用诸如exit之类的调用中止进程。

#1


2  

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这本书应当像定义从或signal-catching打断了函数调用的时候,有一个例外:当一个信号中断不安全功能和signal-catching函数调用一个不安全的函数,其行为是未定义的。

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. (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).

void C()是一个不安全的函数,因为它不在安全函数列表中,因此它发出信号会导致未定义的行为。(我认为这也意味着从信号处理函数中提取信号也会导致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. The only portable way to get out of the signal handler is to abort the process with a call such as exit.
  • 它也是从SIGSEGV的信号处理器返回的UB。离开信号处理程序的惟一可移植性方法是使用诸如exit之类的调用中止进程。