便携式的方式来捕捉信号和报告问题向用户
-
01-07-2019 - |
题
如果通过一些奇迹的出现段错误发生在我们的程序,我想赶上"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可用于通知主程序它应该退出。
以下我发现我的搜索很有用。
- Unix信号编程简介
- 扩展传统信号 醇>
其他提示
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*-他的错误信息具有合理的成功机会。
编写一个启动程序来运行程序并向用户报告异常退出代码。