如果通过一些奇迹的出现段错误发生在我们的程序,我想赶上"SIGSEGV",并让用户(可能是一个GUI客户)知道一个单一的返回代码是一个严重的问题已经发生。在同一时间,我想显示信息的命令行为显示哪些信号被抓住了。

今天,我们的信号处理程序看起来如下:

void catchSignal (int reason) {
  std :: cerr << "Caught a signal: " << reason << std::endl;
  exit (1);
}

我可以听到尖叫声的恐怖与上述,因为我已经读这个 螺纹 这是邪恶的呼叫一个非重入职能从一个信号处理程序。

是否有一个便携式的方式来处理信号和提供信息的用户?

编辑: 或者至少便携式内POSIX框架?

有帮助吗?

解决方案

列出了POSIX保证异步信号安全的所有函数,因此可以从信号处理程序中调用。

通过使用该表中的'write'命令,以下相对“丑陋”的命令解决方案希望能解决这个问题:

#include <csignal>

#ifdef _WINDOWS_
#define _exit _Exit
#else
#include <unistd.h>
#endif

#define PRINT_SIGNAL(X) case X: \
          write (STDERR_FILENO, #X ")\n" , sizeof(#X ")\n")-1); \
          break;

void catchSignal (int reason) {
  char s[] = "Caught signal: (";
  write (STDERR_FILENO, s, sizeof(s) - 1);
  switch (reason)
  {
    // These are the handlers that we catch
    PRINT_SIGNAL(SIGUSR1);
    PRINT_SIGNAL(SIGHUP);
    PRINT_SIGNAL(SIGINT);
    PRINT_SIGNAL(SIGQUIT);
    PRINT_SIGNAL(SIGABRT);
    PRINT_SIGNAL(SIGILL);
    PRINT_SIGNAL(SIGFPE);
    PRINT_SIGNAL(SIGBUS);
    PRINT_SIGNAL(SIGSEGV);
    PRINT_SIGNAL(SIGTERM);
  }

  _Exit (1);  // 'exit' is not async-signal-safe
}

编辑:在Windows上构建。

尝试构建此窗口后,似乎未定义“STDERR_FILENO”。然而,从文档中它的值似乎是'2'。

#include <io.h>
#define STDIO_FILENO 2

编辑:不应该从信号处理程序调用'exit'!

正如 fizzer所指出的那样,在上面调用_Exit是一种用于HUP和TERM等信号的大锤方法。理想地,当这些信号被捕获具有“volatile sig_atomic_t”的标志时。 type可用于通知主程序它应该退出。

以下我发现我的搜索很有用。

  1. Unix信号编程简介
  2. 扩展传统信号

其他提示

FWIW,2也是Windows上的标准错误,但是你需要一些条件编译,因为它们的write()被称为_write()。你也想要

#ifdef SIGUSR1 /* or whatever */

等所有对信号的引用都不能保证由C标准定义。

另外,如上所述,您不希望像这样处理SIGUSR1,SIGHUP,SIGINT,SIGQUIT和SIGTERM。

理查德,仍然没有足够的业评论,以一个新的回答我很害怕。这些都是异步的信号;你有没有想法时,他们交付,因此可能你会在图书馆的代码需要完成,以保持一致。信号处理程序对这些信号,因此需要返回。如果你call exit(),图书馆将做一些工作后的主要(),其中包括调用功能登记atexit()和清洁标准流。这种处理可能会失败,如果说,你的信号来到了一个标准图书馆I/O功能。因此,在C90你是不是允许call exit().我现在看到的C99放松的要求通过提供新的功能请()于标准库.h。请()可以安全地从一个处理程序进一步的信号。请()不会叫atexit()功能以及可以省略清理的标准流在实施的自由裁量权。

到bk1e(评论的几个员额) 事实上,"SIGSEGV"是同步的,是为什么你不能使用的功能设计成不能重入。如果有什么功能的崩溃,被锁定,以及功能由信号处理程序,试图获得同样的锁?

这是一种可能性,但它不是'事实上,"SIGSEGV"是同步的,'这就是问题所在。呼吁非重入职能从处理程序是很糟糕的异步信号的原因有两个:

  • 异步信号处理程序 (一般)希望返回和 恢复正常程序的执行。一个 处理程序同步信号 (通常)会终止 无论如何,所以你还没失去了如果 你崩溃。
  • 在一个有悖常理的意义,你有绝对的控制,当一个同步的信号被输送-它发生了因为你执行你有缺陷的代码,并在没有任何其他时间。你有没有控制在所有当一个异步信号被输送。除非运自己的I/O码是ifself缺陷的原因-比如输出一个糟糕的char*-他的错误信息具有合理的成功机会。

编写一个启动程序来运行程序并向用户报告异常退出代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top