我是Linux信号的新手,请帮忙。 以下代码在Linux 2.6 gcc中运行时获得核心转储。
$ ./a.out
浮点异常(核心转储)
问题:
1.由于安装了过程信号掩码,第40行(z = x / y)生成的“SIGFPGE”不应被阻止吗?
2.如果没有阻塞,由于已经安装了信号处理程序,信号处理程序不应该捕获“SIGFPE”而不是核心转储?
3.如果我注释掉第40行(z = x / y),并使用第42行(加注(SIGFPE)),那么一切都按预期工作。这里x / 0和提升SIGFPE有什么区别?
以下是代码:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void sig_handler(int signum)
{
printf("sig_handler() received signal %d\n", signum);
}
int main(int argc, char * argv[])
{
// setup signal mask, block all signals
sigset_t set;
sigfillset(&set);
if(sigprocmask(SIG_BLOCK, &set, NULL)<0)
{
perror("failed to set sigmask");
return -1;
}
// install signal handler for SIGFPE
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_mask = set;
act.sa_flags = 0;
if(sigaction( SIGFPE, &act, NULL)<0)
{
perror("sigaction failed");
exit(-1);
}
volatile int x =1;
volatile int y =0;
volatile int z = x/y;
//raise(SIGFPE);
printf("point 1000\n");
return 0;
}
答案 0 :(得分:4)
信号被阻塞时由硬件陷阱引起的任何SIGFPE都会导致未定义的行为:
如果在阻塞时生成任何SIGFPE,SIGILL,SIGSEGV或SIGBUS信号,则结果是未定义的,除非信号是由kill()函数,sigqueue()函数或raise(由)生成的( )功能。
答案 1 :(得分:0)
man signal
根据POSIX,在忽略非由kill(2)或raise(3)生成的SIGFPE,SIGILL或SIGSEGV信号后,进程的行为是不确定的。整数除以零会产生不确定的结果。
在某些体系结构上,它将生成SIGFPE信号。 (也将最大负整数除以-1可能会生成SIGFPE)。忽略此信号可能会导致无限循环。
我试图弄清楚为什么负/正无穷大是由零除而产生的:IEEE 754, division by zero
这是您永远不想得到的地方:
void divZeroHdlr(int sig) {
printf("div by zero: %d\n",sig)
exit(1);}
int main(int argc, char *argv[]) {
signal(SIGFPE, divZeroHdlr)
int n = 1/0}