Linux 中的信号处理

Nar*_*yan 1 c linux signals

我想了解信号处理的工作原理,因此我决定以另一种方式处理除以零。程序应请求输入,直到不发生被零除为止。但是,我的处理程序在第一次跳转后被忽略,并且除法由系统处理。为什么会出现这种情况?

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

jmp_buf env;

void handler(int sig) {
    printf("Invalid input , try again\n");
    longjmp(env , 1);
}

int main() {
    signal(SIGFPE , handler);
    int x , y;
    setjmp(env);
    scanf("%d%d" , &x , &y);
    printf("%d\n" , x / y);
}
Run Code Online (Sandbox Code Playgroud)

JS1*_*JS1 5

您需要使用sigsetjmpsiglongjmp而不是常规版本,因为常规版本无法正确恢复您的信号掩码。这是您的代码的工作版本:

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

jmp_buf env;

void handler(int sig) {
    printf("Invalid input , try again\n");
    siglongjmp(env , 1);
}

int main() {
    int x , y;

    signal(SIGFPE , handler);
    sigsetjmp(env, 1);
    scanf("%d%d" , &x , &y);
    printf("%d %d\n" , x, y);
    printf("%d\n" , x / y);
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我尝试sigaction按照 Joachim Pileborg 在评论中的建议使用,但这对我没有帮助。我认为这里的关键是,如果您只是简单地longjmp退出信号处理程序,则信号上下文不会恢复(意味着 SIGFPE 可能会处于禁用状态)。