c++ - 信号处理(SIGFPE)

标签 c++ signals

在下面的代码中:

#include <unistd.h>
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
using namespace std;
void signal_callback_handler(int signum)

{
printf ("Caught signal %d\n", signum);
exit (signum);
}

int main()
{
signal (SIGFPE, signal_callback_handler);

int a=4;
int b=55444;

while (1)
{
printf ("Program processing stuff here.\n");
cout<<b/a;
a--;
b++;
sleep (1);
}
return EXIT_SUCCESS;
}

当变量“a”变为 0 时,程序从操作系统获取 SIGFPE 信号,程序终止并显示消息:“捕获信号 8”。但是,如果我注释掉,“exit(signum);” 'signal_callback_handler' 定义中的一行,程序继续无休止地运行并继续在屏幕上打印“Caught Signal 8”语句。为什么会这样?为什么这个信号会以某种方式反复生成?

我本来以为信号会产生一次,经过信号处理函数后,程序会在'cout << b/a'语句后恢复,然后程序会正常继续。但是,由于这个没有发生,我怎样才能实现我的目标?

最佳答案

在 x86 中,这是因为 divide error is a fault ,这意味着当控制流返回时,程序计数器 (%rip) 将指向先前错误代码的地址,而不是下一条指令。

处理 SIGFPE 的正常策略是使用 setjmp 从信号处理程序跳转到可恢复状态。

一个来自您自己代码的简单示例(顺便说一下,永远不要在信号处理程序中使用 printf()):

#include <setjmp.h>
using namespace std;

jmp_buf excep;

void signal_callback_handler(int signum)

{
longjmp(excep, 1);
}

int main()
{
signal (SIGFPE, signal_callback_handler);

int a=4;
int b=55444;

    while (1)
    {
        printf ("Program processing stuff here.\n");
        if ( setjmp(excep) == 0 ) {
            // normal control flow
            cout<<b/a;
        }
        else {
            // from longjmp
            printf("Exception caught\n");
        }
        a--;
        b++;
        sleep (1);
    }
return EXIT_SUCCESS;
}

关于c++ - 信号处理(SIGFPE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49082174/

相关文章:

c - 信号在 Linux 上如何工作(c)?

matlab - 每次计算时,两个随机信号之间的相关性都会发生变化

c# - 使用 .Net 中的 IAmsiStream 会导致 AccessViolationException

c++ - 指针初始化之间的区别

c++ - 什么时候不使用 `auto&&` ?

c - 如何捕获Control+D信号?

c - 在 linux (ubuntu) 上用 C 语言延迟向我自己的进程发送信号

c++ - 写入和读取记录到.dat 文件 C++

c++ - cout、cin 对象的定义放在哪里?

使用更多进程在 C 中捕获 SIGTERM