【发布时间】:2013-08-27 21:43:03
【问题描述】:
这里的目标是捕获 SIGINT 以关闭小型套接字服务器上的服务器套接字。我尝试使用嵌套函数来保持代码清洁。但是……
当我执行 Ctrl-C(SIGINT,对吗?)时,我得到 Illegal instruction: 4。阅读this post 后,我尝试将-mmacosx-version-min=10.8 添加到编译标志中,因为我使用的是10.8。 Ctrl-C 时同样的错误。
这里有两个问题:为什么我会得到`Illegal instruction 4"?如何在不使用全局变量的情况下关闭服务器套接字?
我的软件:
Mac OSX 10.8.4
GCC 4.2.1
这是我的编译方式:
gcc -fnested-functions main.c
代码如下:
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void register_sigint_handler(int *serverSocket)
{
void sigint_handler(int signal) {
printf("Shutting down...\n");
printf("Server socket was %d\n", *serverSocket);
close(*serverSocket);
exit(0);
}
signal(SIGINT, &sigint_handler);
}
int main(void) {
int serverSocket = 0, guestSocket = 0;
register_sigint_handler(&serverSocket);
serverSocket = socket(PF_INET, SOCK_STREAM, 0);
while (1) {}
close(serverSocket);
return 0;
}
【问题讨论】:
-
您是否尝试过使用调试器 (gdb/lldb)?
-
这不会导致您的问题,但从信号处理程序调用
printf是不安全的。信号处理程序在其中可以做的事情非常有限——最安全的做法是设置一个标志(volatile sigatomic_t类型),然后在主循环期间定期检查该标志,并注意EINTR来自accept(2)和select(2)等系统调用的错误代码。 -
@AdamRosenfield:由于代码使用的是套接字,它可能可以使用POSIX 提供的不太严格的规则,这些规则可以安全地从信号处理程序中调用。安全列表仍然不包括
printf(),但它确实允许使用许多其他功能,包括write()。但是,您评论的主旨仍然准确:(1) 不要致电printf()等人,以及 (2) 在信号处理程序中的操作要谨慎。