我想对默认转储内核的致命信号使用信号处理程序,该日志处理程序将记录发生情况,然后仍将转储内核(除非使用ulimit或内核模式禁用了)。
我已经测试过(在Linux 4.15上),如果信号处理程序只是返回,就会发生这种情况。但是,我在文档中未找到任何明确声明可以明确指出这一点。
在POSIX或Linux文档中是否定义了信号处理程序返回时将发生什么以及在哪里发生?
我通过调整完成工作所需的代码进行了第一个测试,它比我想的要复杂得多。当我使用简单的示例程序进行测试时,在所有情况下都有效的唯一方法是重置处理程序并按照接受的答案中所述重新引发信号。
答案 0 :(得分:2)
核心文件在POSIX.1-2017 XBD(3.117 Core File)中具有定义:
进程异常终止时可能生成的格式不确定的文件。
POSIX.1-2017 XSH( 2.4.3 Signal Actions ,在SIG_DFL下)包含以下文本(此处强调的部分表示标准中的相应文本XSI阴影):
如果默认操作是异常终止该进程,则该过程就像通过调用
_exit()
一样终止,除了wait()
,waitid()
和waitpid()
表示信号异常终止。 如果默认操作是使用其他操作异常终止进程,则可能还会发生实现定义的异常终止操作,例如创建核心文件。
在XBD( 13。标头,在<signal.h>下)中,我们看到SIGABRT
,SIGBUS
,SIGFPE
,SIGILL
, SIGQUIT
,SIGSEGV
, SIGSYS
, SIGTRAP
, SIGXCPU
和 SIGXFSZ
标记为
A-异常终止进程,并执行其他操作。
因此,从POSIX角度来看,无论信号布置如何,您都不能依赖于正在生成的核心文件。
但是,在Linux手册(signal(7)
)中列出了POSIX中具有默认操作“ A”的每个信号,其默认配置为“ Core”。以下是本手册中有关SIGSYS
,SIGXCPU
和SIGXFSZ
的摘录所指的内容:
Linux 2.4符合这些信号的POSIX.1-2001要求,以核心转储终止进程。
以上POSIX摘录告诉我们,在POSIX.1-2017中这不是硬性要求。
现在,如果注册信号捕获功能是否使异常终止的信号动作无效,仍然无法回答问题。我相信,如果这样做的话,则会导致至少一些信号产生不确定的行为,如XSH的以下段落所述( 2.4.3 Signal Actions ,在Pointer to a Function下):>
进程的行为在从信号捕获函数正常返回
SIGBUS
,SIGFPE
,SIGILL
或SIGSEGV
信号(通常不是信号捕获函数)后未定义由kill()
,sigqueue()
或raise()
生成。
因此,为了在所有情况下都避免使用UB,我相信您必须将信号配置重置为SIG_DFL
,然后无论如何都要从信号处理程序中重新raise()
信号。此外,任何捕获这些信号的处理程序都可能应该在备用信号堆栈上运行,但是我不确定这是否通常使它安全以及是否放在首位。