当发生段错误时不调用信号处理程序?

When signal handler is not called when segment fault occurs?

下面是我的程序的运行方法,曾经有过因为segment fault导致程序终止时注册的handler没有被调用的情况

是否存在当段错误发生时注册的处理程序可以在未被调用的情况下终止的情况?

  1. 程序A初始化时,通过signal()函数注册handler(SIGSEGV, SIGABRT, SIGFPE, SIGTERM)
  2. 程序 B 中程序 A 的 fork() -> waitpid()
  3. 老化
  4. A程序出现段错误,原因不明
  5. B程序的waitpid状态传给segment fault(11)。
  6. A程序中注册的handler未调用结束

well-formed、well-defined C++ 应用程序永远不会导致段错误。

段错误是未定义行为的结果;但是当未定义的行为发生时,根据定义你不能期望任何特定的结果或行为。您不希望由于未定义的行为而发生段错误,即使发生,您也不能指望 SIGSEGV 处理程序会产生任何预期的结果。

可以给出的例子数量没有限制。比方说,段错误处理程序试图删除在段错误之前创建的临时文件。太糟糕了,除了导致段错误之外,未定义的行为还导致存储临时文件名称的缓冲区损坏。段错误处理程序失败。或者,更好的是,损坏的文件名缓冲区碰巧与另一个文件的名称相匹配,并且它被错误地删除了。如果您 运行 是根用户,并且损坏的文件名缓冲区偶然包含“/bin/bash”,那么您只是将您的机器变成了一块无法启动的砖块。

许多其他的可能性也可能发生,只限于一个人的想象力。您没有描述您的 sigsegv 处理程序试图做什么,但这并不重要。无论它试图做什么,都不能保证总是有效。为时已晚,当它被调用时,未定义的行为已经发生,从那时起你不会期望发生任何事情。

因此,无论段错误处理程序试图做什么,它都无法保证能够完成其任务。当段错误处理程序被调用时,程序其余部分的状态及其数据是未定义和未指定的。

这就是为什么当出现导致段错误的错误时,正确的处理方法是找出段错误的原因,找到错误并修复它。任何通过捕获信号和清理来补救这种情况的尝试充其量只是一次冒险,并不能保证总是成功。