为什么信号不会被抓住?

时间:2011-07-12 16:47:43

标签: objective-c macos unix posix signals

在我的main()的最开始,我有:

signal(SIGTERM, SIGTERM_handler);

SIGTERM_handler是:

void SIGTERM_handler(int signum) {

    NSLog(@"Caught signal: [%d]. Cleaning up ...",signum);
    //cleanup();
    NSLog(@"Done cleaning up. Exiting ...");
    exit(EXIT_FAILURE);
}

永远不会打印这些线条。当我在处理程序中设置断点时,它们永远不会被击中。我不会在任何地方拨打sigaction()。设置GDB以传递我关心的信号(handle SIGTERM SIGINT pass stop printhandle SIGTERM SIGINT pass nostop print)。甚至默认的信号处理程序也不起作用 - 向程序发送SIGINT(我没有指定处理程序)也没有任何作用。

导致这种情况的原因是什么?

4 个答案:

答案 0 :(得分:5)

我不知道Objective C,但我确实有使用信号处理程序的经验,所以我会像POSIX和C一样回答。

在信号处理程序中调用任何未记录为“异步信号安全”的函数是一种风险,应该避免。调用信号处理程序时,不能对堆栈或任何其他状态做任何假设。当调用信号处理程序时,堆栈甚至可能被“删除”(在创建或破坏帧的过程中)。调用信号处理程序时,库可能具有不一致的状态。

声明在事件循环中检查的volatile标志(int),或者其他任何东西,以查看它是否已更改。信号处理程序应该只设置该标志并返回,没有别的。 (除非您的平台执行SVR4样式的信号,在这种情况下,您还需要在信号处理程序中重新安装信号处理程序。)

响应信号的日志消息和其他活动应该通过任何代码检查标志并处理标志所隐含的事件来完成。

你看到的症状可能不是由于信号处理程序中的库调用(我的钱真的会在gdb交互上),但我绝对建议从信号处理程序中取出所有库调用。

答案 1 :(得分:2)

Shawn,所以你正在使用CZMQ,它会在你执行zctx_new()时为了自己的目的而转移信号。我的建议是尽可能让CZMQ做它的事情并使用它提供的机制捕获中断,这是全局zctx_interrupted变量,并且在任何阻塞ZMQ调用中,返回null和EINTR错误代码。

答案 2 :(得分:0)

事实证明与czmq的zsocket_new有关。切换到zctx__socket_new修复它。我还没有深入了解究竟发生了什么。

答案 3 :(得分:0)

你是在调试器中运行它吗?我遇到了在GDB启动内外的iOS平台上处理不同信号的问题。我认为在OSX中也会出现同样的问题。已经很长时间了,我不能给你具体细节