使用setjmp的时候,同一个信号只能触发一次

Linux的异常处理
    基于setjmplongjmp的运行控制方式是Linux平台上C语言处理异常的标准方案,已被广泛运用到由C语言开发的软件系统和链接库中,例如jpg解析库,加密解密库等等。setjmplongjmp是以C语言标准库函数的形式提供的,
setjmp 函数能够保存程序当前的执行环境,即程序的状态,该被保存的程序状态可以在随后程序执行的某一点被longjmp函数恢复,程序的控制流也将跳转到调用setjmp时的执行点,实现非本地局部跳转("non-local goto")的机制。
问题描述:
      在编写基于异常的代码混淆程序时,signal注册的异常信号处理程序只能执行一次,第二次发生异常时异常处理函数没有被调用。
分析:
1. 搞清楚Linux的信号处理流程:
   [1] 收到信号,例如SIGFPE
   [2] 进入signal注册的信号处理函数,此时,SIGFPE自动被加入到进程信号屏蔽字
   [3] 执行信号处理函数
   [4] 信号处理结束,恢复信号屏蔽字,SIGFPE被取消阻塞
   [5] 返回到产生信号地方继续执行
2. 分析异常处理函数没有被调用的原因:
      异常信号处理函数在结束前没有取消对SIGFPE信号的阻塞,直接调用longjmp()进行控制流转移。所以在后面的执行过程中再次遇到SIGFPE信号,系统会自动根据 信号屏蔽字进行屏蔽,异常处理函数也就无法被调用。
3. 该问题的解决办法:
      使用sigsetjmp和siglongjmp函数替换setjmp和longjmp函数。siglongjmp功能与longjmp类似,不同的是siglongjmp会自动恢复进程的信号屏蔽字,因此相同的异常信号再次发生时就不会被系统屏蔽了。


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

jmp_buf jmpbuffer;

void fun(int i){
    siglongjmp(jmpbuffer, 1);
    return;
}
int main(int argc, char** argv) {
    signal(SIGUSR2, fun );
    if( sigsetjmp(jmpbuffer, SIGUSR1) == 1){
        printf("==000====\n");
    }
/*
    struct sigaction act, oact;
    act.sa_handler=fun;
    sigemptyset(&act. sa_mask);
    act. sa_flags = 0;
    sigaction(SIGUSR2, &act, &oact);
*/
    sleep(5000);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值