我编写了一个处理浮点异常信号的程序,我使用的是Ubuntu 10.4。
这是我的源代码:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
sigjmp_buf mark;
void GeneralHandler(int signo)
{
switch(signo)
{
case SIGFPE:
printf("\nERROR : Invalid Arithmetic operation.\n");
siglongjmp(mark, signo);
break;
}
exit(signo);
}
int main(void)
{
int i = 0,value = 0, ans = 0;
struct sigaction act;
act.sa_handler = GeneralHandler;
sigaction(SIGFPE, &act, NULL);
for(i = 0; i < 10; i++)
{
if(sigsetjmp(mark, 1)) continue;
printf("Value : ");
scanf("%d" ,&value);
ans = 5 / value;
printf("%d / %d = %d\n", 5, value, ans);
}
}
我正在使用siglongjmp和sigsetjmp方法从处理程序方法跳转到for循环中的main方法。
首次正常工作并显示 ERROR:无效的算术运算。,然后第二次显示浮点异常,然后退出。
节目输出:
searock @searock-desktop:〜/ C $ ./signal_continue
值:0
错误:算术运算无效。
值:0
浮点异常
searock @ searock-desktop:〜/ C $
我不确定我的计划有什么问题?为什么它第二次不显示错误:无效的算术运算?有人能指出我正确的方向吗?
答案 0 :(得分:3)
您尚未初始化struct sigaction
act
可能包含垃圾值,例如将信号处理程序配置为SA_RESETHAND或其他不良内容。
做结构
sigaction act = {};
或
memset(&act,0,sizeof act);
答案 1 :(得分:2)
我认为您不应该将logjump()
从信号处理程序返回到主代码中。信号处理程序应该只处理信号然后返回并让主程序以正常方式继续执行。
我不确定你 应该对SIGFPE做什么。 signal()
的手册页说的不太有希望:
根据POSIX,进程的行为在它之后是不确定的 忽略未生成的SIGFPE,SIGILL或SIGSEGV信号 杀死(2)或加注(3)。整数除零具有未定义的结果。 在某些架构上,它将生成SIGFPE信号。 [...]忽略这个 信号可能导致无限循环。