便携式方式捕捉信号并向用户报告问题 [英] Portable way to catch signals and report problem to the user
问题描述
如果某些奇迹在我们的程序中发生segfault,我想捕获SIGSEGV并让用户(可能是一个GUI客户端)知道一个返回代码发生了严重的问题。
今天我们的信号处理程序看起来如下:
void catchSignal(int reason){
std :: cerr< 捕获信号:<原因< std :: endl;
exit(1);
}
我可以听到上面的恐怖的尖叫,此线程
有没有可移植的方式来处理信号并向用户提供信息?
p>EDIT:或至少在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)\\\
,sizeof(#X)\ n) - 1); \
break;
void catchSignal(int reason){
char s [] =捕获的信号:(;
write(STDERR_FILENO,s,sizeof(s) - 1);
switch(reason)
{
//这些是我们捕获的处理程序
PRINT_SIGNAL(SIGUSR1);
PRINT_SIGNAL(SIGHUP);
PRINT_SIGNAL );
PRINT_SIGNAL(SIGQUIT);
PRINT_SIGNAL(SIGABRT);
PRINT_SIGNAL(SIGILL);
PRINT_SIGNAL(SIGFPE);
PRINT_SIGNAL b PRINT_SIGNAL(SIGSEGV);
PRINT_SIGNAL(SIGTERM);
}
_Exit(1); //'exit'不是异步信号安全
}
编辑:在Windows上构建。
尝试构建这个窗口后,看起来'STDERR_FILENO'没有定义。但是从文档中,它的值看起来是'2'。
#include< io.h>
#define STDIO_FILENO 2
编辑:不应该从信号处理程序中调用'exit'。
href =http://stackoverflow.com/questions/103280/portable-way-to-catch-signals-and-report-problem-to-the-user#114413> fizzer ,调用_Exit在以上是用于诸如HUP和TERM的信号的大锤方法。理想情况下,当这些信号被捕获时,带有volatile sig_atomic_t类型的标志可用于通知主程序它应该退出。
以下我发现在我的
If by some miracle a segfault occurs in our program, I want to catch the SIGSEGV and let the user (possibly a GUI client) know with a single return code that a serious problem has occurred. At the same time I would like to display information on the command line to show which signal was caught.
Today our signal handler looks as follows:
void catchSignal (int reason) { std :: cerr << "Caught a signal: " << reason << std::endl; exit (1); }
I can hear the screams of horror with the above, as I have read from this thread that it is evil to call a non-reentrant function from a signal handler.
Is there a portable way to handle the signal and provide information to users?
EDIT: Or at least portable within the POSIX framework?
解决方案This table lists all of the functions that POSIX guarantees to be async-signal-safe and so can be called from a signal handler.
By using the 'write' command from this table, the following relatively "ugly" solution hopefully will do the trick:
#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 }
EDIT: Building on windows.
After trying to build this one windows, it appears that 'STDERR_FILENO' is not defined. From the documentation however its value appears to be '2'.
#include <io.h> #define STDIO_FILENO 2
EDIT: 'exit' should not be called from the signal handler either!
As pointed out by fizzer, calling _Exit in the above is a sledge hammer approach for signals such as HUP and TERM. Ideally, when these signals are caught a flag with "volatile sig_atomic_t" type can be used to notify the main program that it should exit.
The following I found useful in my searches.
这篇关于便携式方式捕捉信号并向用户报告问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!