繁体   English   中英

信号处理

[英]signal handling

我只是在Mac OS X中玩信号。

为什么在我的信号处理程序完成后,以下代码不会产生SIGSEGV的默认行为? 在Linux下,代码工作正常。

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void err_crash();

void my_signal_handler (int signal)
{
    fprintf(stderr, "signal == %i\n", signal);
    fflush(stderr);
    err_crash();
}

void err_crash()
{
    static int count= 0;
    if (count)
        signal(SIGSEGV, SIG_DFL);       /* break recursion loop if we recursed */
    count++;

    // one of the two should really crash ;)
    ((void)(*((int volatile *)NULL)));
    *((int *)NULL) = 42;

    abort();                            /* in case we're not crashed yet... */
}

int main ()
{
    signal(SIGSEGV, my_signal_handler);
    err_crash();
    return 0;
}

编辑:我得到的输出如下:

bonecrusher:devel sw$ g++ signal_problems.cpp -o foo
bonecrusher:devel sw$ ./foo 
signal == 11
^C
bonecrusher:devel sw$

问题是我希望程序在signal == 11的输出之后终止,但它永远发生,我必须打断它。

这实际上让我大脑冻结了几分钟,而且在这个时代,人们不应该使用signal()的原因只会在我身上变得更强。

首先,从signal()的手册页

signal()的行为在UNIX版本中各不相同,并且在不同版本的Linux上也有不同的历史变化。 避免使用:改为使用sigaction(2)。

进一步向下:

  • 如果处置设置为函数,则首先将处置重置为SIG_DFL,或者阻止信号(参见下面的可移植性),然后使用参数signum调用处理程序。 如果处理程序的调用导致信号被阻塞,则在从处理程序返回时信号被解除阻塞。

在原来的Unix系统中,被安装的处理程序时,配置被复位为SIG_DFL, 阻断的相同类型的输入信号,然后将其跑处理函数。 System V提供了这个,而linux内核也是如此。

这意味着,一旦代码在linux系统上运行,一旦调用第二个异常,它将直接退出。

现在到了有趣的部分。 BSD试图改善这种行为。 再次从手册页:

在BSD上,当调用信号处理程序时,信号处理不会被重置,并且在处理程序执行时阻止信号的其他实例被传递。

由于mac osx部分基于BSD,一旦代码在mac osx上运行,一旦调用第二个异常,它将处于挂起状态并等待第一个异常的处理程序退出。 但既然你永远不会退出,那你就陷入了僵局。

这就是为什么一个人应该使用sigaction()而不是signal()

现在来一些提示:

处理程序应该简短,并快速返回。 如果您正在执行计算并调用其他函数,那么您可能做错了。 信号不能替代事件驱动的框架。

调用非异步安全的函数很糟糕。 考虑如果在调用fprintf期间发生异常会发生什么,并且在处理程序内部再次调用fprintf 信号处理程序和程序数据都可能被破坏,因为它们在流本身上运行。

更多阅读: “信号处理程序”中的“Do”和“Do not”

根据POSIX

如果在阻塞时生成任何SIGFPE,SIGILL,SIGSEGV或SIGBUS信号,则结果是未定义的,除非信号由kill()函数, sigqueue()函数或raise()函数生成。

因为SIGSEGV在SIGSEGV信号处理程序中被阻塞,所以在这种情况下结果是未定义的,并且任何行为都是有效的。 如果您不希望它被阻止,您可以使用带有SA_NODEFER标志的sigaction()安装信号处理程序,或使用sigprocmask()来取消阻塞信号处理程序中的信号。

在调试器中运行它并单步执行您希望崩溃的指令。

无法保证写入无效地址必须创建分段错误。 也许Mac OS X会为您映射这些地址,而您正在覆盖一些良性的东西。

暂无
暂无

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

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