Objective c 为什么信号不会被捕获?

Objective c 为什么信号不会被捕获?,objective-c,macos,unix,posix,signals,Objective C,Macos,Unix,Posix,Signals,在main()的开头,我有: SIGTERM_处理程序是: void SIGTERM_handler(int signum) { NSLog(@"Caught signal: [%d]. Cleaning up ...",signum); //cleanup(); NSLog(@"Done cleaning up. Exiting ..."); exit(EXIT_FAILURE); } 这些行永远不会打印出来。当我在处理程序中设置断点时,它们永远不会被命中。

在main()的开头,我有:

SIGTERM_处理程序是:

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 print
还是
handle SIGTERM SIGINT pass nostop print
)。即使是默认的信号处理程序也不起作用-向程序发送SIGINT(我没有为其指定处理程序)也不起任何作用


这可能是什么原因造成的?

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

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

声明一个volatile标志(int),该标志在事件循环中被检查,或者其他什么,以查看它是否已更改。信号处理程序只应设置该标志并返回,而不应设置其他内容。(除非您的平台执行SVR4样式的信号,否则在这种情况下,您还需要在信号处理程序中重新安装信号处理程序。)

响应信号的日志消息和其他活动应该由检查标志并处理标志所暗示的事件的代码来完成


您看到的症状可能不是由于信号处理程序中的库调用造成的(老实说,我的钱将花在gdb交互上),但我绝对建议将所有库调用从信号处理程序中取出。

事实证明,这与czmq有关。切换到修复它。我还没有深入了解到底发生了什么。

你是在调试器中运行这个吗?我遇到过这样的问题,即在从GDB发布的iOS平台内部和外部,信号的处理方式有所不同。我认为OSX中也存在同样的问题。这已经有很长时间了,我无法给您提供详细信息,所以您使用的是CZMQ,每当您执行zctx_new()时,它会将信号转移到自己的目的。我的建议是,如果可能的话,让CZMQ做它自己的事情,并使用它提供的机制(全局zctx_interrupted变量)捕获中断,并且在任何阻塞ZMQ调用中,返回空值和EINTR错误代码。

日志文件缓冲区是否可能没有刷新?当它在gdb中运行时,如何向进程发送信号?我建议尝试其他信号之一(比如kill-1或kill-2),我用
kill-2
kill-15
和其他信号发送信号。我知道这是可行的,因为如果我打开do“handle…stop”,那么GDB确实会停止,并说我的程序收到了一个信号;它仍然不会触发处理程序。
void SIGTERM_handler(int signum) {

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