Chinaunix首页 | 论坛 | 博客
  • 博客访问: 582004
  • 博文数量: 353
  • 博客积分: 1104
  • 博客等级: 少尉
  • 技术积分: 1457
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-23 23:02
个人简介

1、刚工作时做Linux 流控;后来做安全操作系统;再后来做操作系统加固;现在做TCP 加速。唉!没离开过类Unix!!!但是水平有限。。

文章存档

2015年(80)

2013年(4)

2012年(90)

2011年(177)

2010年(1)

2009年(1)

分类:

2011-10-24 17:48:43

linux中特殊的跳转函数sigsetjmp()和siglongjmp()
如果是在low-0level subroutine中处理中断和错误的时候特别有用
在使用函数的时候,需要先声明一个sigjmp_buf型的变量,用来保存某一位置(时刻)堆栈上下文的信息。

原型:

//直接调用则返回0, 从siglongjmp调用返回则返回非0值.

int sigsetjmp(sigjmp_buf env, int savesigs);

void siglongjmp(sigjmp_buf env, int val);


sigsetjmp会将当前的堆栈上下文保存在变量env中,这个变量会在后面的siglongjmp中用到。但是当调用个sigsetjmp的函数返

回的时候,env变量将会失效;
如果savesigs非零,阻塞的信号集合也会保存在env变量中,当调用siglongjmp的时候,阻塞的信号集也会被恢复。如果

sigsetjmp本身直接返回,则返回值为0;若sigsetjmp在siglongjmp使用env之后返回,则返回值为非零。

其具体用法见下面的例子:

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
 
static sigjmp_buf jmpbuf;

void sig_fpe(int signo)
{
   siglongjmp(jmpbuf, 1);
}
 
int main(int argc, char *argv[])
{
    signal(SIGFPE, sig_fpe);
     if (sigsetjmp(jmpbuf, 1) == 0)
// try

        {
// {

              int ret = 10 / 0;
// int ret = 10 / 0;


        }
// }

    else
// catch

        {
// {

             printf("catch exception\n");
// printf("catch excetion\n");

        }
// }

}

其结果如下,说明捕捉到了除零的错误信号:

catch exception

结果分析:

分析:在第一次调用sigsetjmp的时候,由于之前没有调用siglongjmp,所以sigsetjmp的返回值为0,故执行int ret = 10 / 0;的操作这时候产生了一个SIGFPE信号,然后会进入SIGFPE信号的handler中。在handler中调用了siglongjmp,恢复了env,这时候会回到保存env之处,继续重新执行if,由于在本次sigsetjmp调用之前已经有siglongjmp恢复了env,故返回值为非零。从而最终打印出捕捉到的异常信息。这个功能其实相当于cpp中的异常捕捉try...catch块。

阅读(3303) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~