Linux C捕获终止信号

我有一个使用套接字,数据库连接和类似的过程。 它基本上是一个在传感器数据和Web界面之间进行中继的服务器进程,因此,确保应用程序(如果遇难​​)正常终止非常重要。

我如何处理意外的exception,如segfaults(至less用于debugging),以及杀死信号,以便我可以closures任何连接,并停止任何线程运行,使进程不会留下任何混乱的使用?

Solutions Collecting From Web of "Linux C捕获终止信号"

您可以安装信号处理程序来捕获信号 – 但是,只有99%的情况下,您只想退出并让Linux操作系统负责清理工作 – 它将愉快地关闭所有文件,套接字,可用内存和关闭线程。

所以除非有什么特别的事情要做,比如发送一个消息到套接字上,那么你应该退出这个过程,不要试图捕获这个信号。

捕捉信号很难。 你必须要小心。 您的第一步是使用sigaction为所需信号安装信号处理程序。

  • 选择一组信号来响应并选择它们对于您的过程的意义。 例如, SIGTERM退出, SIGHUP重新启动, SIGUSR1重新加载配置等。

  • 不要尝试对所有信号作出响应,也不要试图在程序中显示错误信号之后进行“清理”。 SIGKILL不能被捕获。 SIGSEGVSIGBUS和其他类似的应用程序不应该被捕获,除非你有一个非常好的理由。 如果你想调试,然后提高核心转储ulimit – 将调试器附加到核心图像比任何你或我可以编码更有效。 (如果你试图在SIGSEGV或类似的东西之后进行清理,请认识到清理代码可能会导致额外的SIGSEGV并且事情会变SIGSEGV糟糕,只要避免一团糟,让SIGSEGV终止你的程序。)

  • 你如何处理信号是棘手的。 如果您的应用程序有一个主循环(例如, selectpoll ),那么信号处理程序可以设置一个标志或写一个字节到一个特殊的管道,以通知主循环退出。 您也可以使用siglongjmp跳出信号处理程序,但这很难正确,通常不是您想要的。

如果不知道应用程序的结构和功能,很难推荐一些东西。

另外请记住,信号处理程序本身应该几乎没有。 信号处理程序调用许多函数是不安全的。

我有时候喜欢在SIGSEGV上进行回溯,捕捉部分如下:

 #include <stdio.h> #include <stdlib.h> #include <signal.h> void sig_handler(int); int main() { signal(SIGSEGV, sig_handler); int *p = NULL; return *p; } void sig_handler(int sig) { switch (sig) { case SIGSEGV: fprintf(stderr, "give out a backtrace or something...\n"); abort(); default: fprintf(stderr, "wasn't expecting that!\n"); abort(); } } 

你要非常小心地处理这些事情,例如确保你不能触发另一个信号。