从默认致命信号的信号处理程序返回

Returning from signal handler of fatal-by-default signal

我想在默认为转储核心的致命信号上有一个信号处理程序,它将记录发生的事件,然后核心仍将被转储(除非使用 ulimit 或核心模式禁用)。

我已经测试(在 Linux 4.15 上)如果信号处理程序只是 returns,就会发生这种情况。但是,我没有在文档中找到任何明确说明这一点的明确声明。

POSIX 或 Linux 文档中是否定义了信号处理程序 returns 时会发生什么以及在哪里?


我通过调整工作所需的代码进行了第一次测试,结果比我想象的要复杂得多。当我使用简单的示例程序进行测试时,适用于所有情况的唯一方法是按照接受的答案中所述重置处理程序并重新发出信号。

核心文件在 POSIX.1-2017 XBD (3.117 Core File) 中有定义:

A file of unspecified format that may be generated when a process terminates abnormally.

POSIX.1-2017 XSH(2.4.3 Signal Actions,在 SIG_DFL 下)包含以下文本(带有来自此处的任何强调部分意味着标准中的相应文本是 XSI 阴影的):

If the default action is to terminate the process abnormally, the process is terminated as if by a call to _exit(), except that the status made available to wait(), waitid(), and waitpid() indicates abnormal termination by the signal. If the default action is to terminate the process abnormally with additional actions, implementation-defined abnormal termination actions, such as creation of a core file, may also occur.

在 XBD(13.Headers,在 <signal.h> 下)我们看到 SIGABRTSIGBUSSIGFPESIGILL, SIGQUIT, SIGSEGV, SIGSYS, SIGTRAP, SIGXCPUSIGXFSZ 标记为

A -- Abnormal termination of the process with additional actions.

因此,从 POSIX 的角度来看,无论信号配置如何,您都不能依赖正在生成的核心文件。

但是,POSIX 中每个具有默认操作 "A" 的信号在 Linux 手册中均以默认配置 "Core" 列出(signal(7)).这可能是以下关于SIGSYSSIGXCPUSIGXFSZ的手册摘录所指的内容:

Linux 2.4 conforms to the POSIX.1-2001 requirements for these signals, terminating the process with a core dump.

正如上面的 POSIX 摘录告诉我们的那样,这在 POSIX.1-2017.

中并不是硬性要求

现在仍然没有回答注册信号捕获函数是否使异常终止的信号动作无效的问题。我相信,如果确实如此,根据 XSH 的以下段落(2.4.3 Signal Actions,在 Pointer to a Function 下),它会导致至少一些信号出现未定义的行为:

The behavior of a process is undefined after it returns normally from a signal-catching function for a SIGBUS, SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(), sigqueue(), or raise().

因此,为了在所有情况下避免 UB,我相信您必须将信号配置重置为 SIG_DFL,然后重新 raise() 来自信号处理程序内的信号。此外,任何捕获这些信号的处理程序都可能 运行 在备用信号堆栈上,但我不太确定这样做是否通常安全,以及它是否在第一位。