简体   繁体   English

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

[英]When signal handler is not called when segment fault occurs?

Below is the operation method of my program, and there was a case where the registered handler was not called when the program was terminated due to the occurrence of a segment fault.下面是我的程序的操作方法,有一种情况是,由于发生了段错误,程序终止时没有调用注册的处理程序。

Is there a case where the registered handler can be terminated without being called when a segment fault occurs?是否存在在发生段错误时可以终止注册的处理程序而不调用的情况?

  1. When initializing program A, register handler through signal() function.( SIGSEGV, SIGABRT, SIGFPE, SIGTERM )初始化程序A时,通过signal()函数注册handler。(SIGSEGV, SIGABRT, SIGFPE, SIGTERM)
  2. fork() -> waitpid() for program A in program B fork() -> waitpid() 用于程序 B 中的程序 A
  3. Aging老化
  4. Segment Fault occurs due to unknown reason in A program由于未知原因在A程序中发生Segment Fault
  5. The waitpid status of the B program is passed to segment fault(11). B 程序的waitpid 状态被传递给segment fault(11)。
  6. The handler registered in A program is not called and ends.在 A 程序中注册的处理程序未被调用并结束。

A well-formed, well-defined C++ application will never result in a segfault.格式良好、定义良好的 C++ 应用程序永远不会导致段错误。

A segfault is a result of undefined behavior;段错误是未定义行为的结果; but when undefined behavior occurs, by definition you can not expect any specific result or behavior.但是当发生未定义的行为时,根据定义,您不能期望任何特定的结果或行为。 You have no expectation that a seg fault will occur as a result of undefined behavior, and even if occurs you cannot expect that the SIGSEGV handler will produce any expected result, at all.您不希望由于未定义的行为而导致段错误发生,即使发生了,您也根本无法期望SIGSEGV处理程序会产生任何预期的结果。

The number of examples that can be given has no limit.可以给出的例子数量没有限制。 Let's say, for example, the segfault handler attempts to remove a temporary file that gets created before the segfault.例如,假设段错误处理程序尝试删除在段错误之前创建的临时文件。 Too bad, the undefined behavior resulted in corrupting the buffer that stored the name of the temporary file, in addition to causing a segfault.太糟糕了,除了导致段错误之外,未定义的行为还导致存储临时文件名称的缓冲区损坏。 The segfault handler fails.段错误处理程序失败。 Or, even better, the corrupted filename buffer happened to match the name of another file, and it gets deleted by mistake.或者,更好的是,损坏的文件名缓冲区碰巧与另一个文件的名称相匹配,并且被错误地删除了。 If you were running as root, and the corrupted filename buffer by chance ended up containing "/bin/bash", you've just turned your machine into an unbootable brick.如果您以 root 身份运行,并且损坏的文件名缓冲区偶然包含“/bin/bash”,那么您只是将您的机器变成了一个无法启动的砖块。

Many other possibilities can also happen, limited only to one's imagination.许多其他可能性也可能发生,仅限于一个人的想象力。 You did not describe what your sigsegv handler attempts to do, but it doesn't matter.您没有描述您的 sigsegv 处理程序试图做什么,但这并不重要。 Whatever it tries to do it has no guarantee of always working.无论它尝试做什么,都不能保证始终有效。 It is too late, by the time it gets invoked undefined behavior already happened, and you have no expectation of anything happening, from that point on.为时已晚,当它被调用时,未定义的行为已经发生了,从那时起,您不希望发生任何事情。

So, whatever the segfault handler attempts to do, it has no guarantee, whatsoever that it can accomplish its task.因此,无论段错误处理程序尝试做什么,它都无法保证可以完成其任务。 By the time the segfault handler gets invoked the state of the rest of the program, and its data, is undefined and unspecified.当段错误处理程序被调用时,程序其余部分的状态及其数据是未定义和未指定的。

Which is why when there's a bug that results in a segfault, the correct way to handle it is to figure out the reason for the segfault, find the bug and fix it.这就是为什么当存在导致段错误的错误时,正确的处理方法是找出段错误的原因,找到错误并修复它。 Any attempt to remedy the situation by catching the signal and the cleaning up is, at best, a crapshoot has no guarantee of always succeeding.任何通过捕获信号和清理来补救这种情况的尝试充其量只是一次错误的尝试并不能保证总是成功。

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

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