免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3927 | 回复: 7
打印 上一主题 下一主题

关于setjmp和longjmp函数结果 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-16 15:39 |只看该作者 |倒序浏览
给位帮忙看下,为什么输出结果是这样,按道理来说应该不会挂掉啊:
hello world
the value = 1
Dbg->the is signal_handler function
hello world
the value = 1
Segmentation fault





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

void test_function()
{
    int *p =NULL ;
    *p = 0 ;

}


jmp_buf gJmpBuf ;

void signal_handler(int num)
{

    printf("Dbg->the is signal_handler function\n");
    longjmp(gJmpBuf,0);
}

int main()
{

    int a = 1 ;

    setjmp(gJmpBuf);
    printf("hello world \n");
    signal(SIGSEGV,signal_handler) ;

    printf("the value = %d \n",a) ;
    test_function() ;
    printf("the value  ++ =  %d \n",a++) ;

    return  0 ;
}

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2011-09-16 17:49 |只看该作者
回复 1# bin_linux96


    既然是在 signal handler 里面,就不要用 longjmp() 了,用 siglongjmp() 吧。

论坛徽章:
0
3 [报告]
发表于 2011-09-16 18:02 |只看该作者
回复 2# MMMIX


    我想让程序一遇到段错误就执行 信号处理函数,可是signal hander 为什么只运行了一次??但第二次发生段错误时,程序直接挂掉了...

论坛徽章:
0
4 [报告]
发表于 2011-09-18 00:12 |只看该作者
第一次调用handler的时候 The SEGV signal is blocked  ,你即使jump出来但还是处于阻塞的状态,再调用的时候就崩溃了

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
5 [报告]
发表于 2011-09-18 14:54 |只看该作者
回复 1# bin_linux96


    我寫的一個:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <signal.h>
  5. #include <setjmp.h>

  6. sigjmp_buf main_env;
  7. int trigger_cnt = 1;
  8. int segv_cnt = 1;

  9. void
  10. segv_trigger(void)
  11. {
  12.         printf("SIGSEGV tigger %d.\n", trigger_cnt++);
  13.         int *p = NULL;
  14.         *p = 0;
  15. }

  16. void
  17. segv_handler(int signum)
  18. {
  19.         assert(signum == SIGSEGV);
  20.         printf("SIGSEGV has been catched %d times.\n", segv_cnt++);
  21.         siglongjmp(main_env, 1);
  22. }

  23. int
  24. main(void)
  25. {
  26.         struct sigaction segv_act;
  27.         volatile int longjmp_cnt;

  28.         segv_act.sa_handler = segv_handler;
  29.         sigemptyset(&segv_act.sa_mask);
  30.         segv_act.sa_flags = 0;
  31.         if (sigaction(SIGSEGV, &segv_act, 0) < 0) {
  32.                 perror("sigaction");
  33.                 exit(EXIT_FAILURE);
  34.         }

  35.         longjmp_cnt = 1;

  36.         if (sigsetjmp(main_env, 1) != 0) {
  37.                 printf("Long jump %d.\n", longjmp_cnt++);
  38.                 if (longjmp_cnt > 3)
  39.                         exit(EXIT_SUCCESS);
  40.         }

  41.         segv_trigger();

  42.         /* UNREACHABLE */
  43.         exit(EXIT_SUCCESS);
  44. }
复制代码

论坛徽章:
0
6 [报告]
发表于 2011-09-21 11:07 |只看该作者
请用sigsetjmp, siglongjmp
sigsetjmp根据返回值做处理

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
7 [报告]
发表于 2012-01-02 18:32 |只看该作者
本帖最后由 embeddedlwp 于 2012-01-02 18:42 编辑

回复 1# bin_linux96


    我在redhat 9 linux 2.4.20-8上运行这个程序没有问题啊。

    《APUE》说调用longjmp有一个问题,当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动的加到进程的信号屏蔽字中。这阻止了后来产生的这种信号中断该信号处理程序。在FreeBSD 5.2.1和Mac OS X 10.3中,setjmp和longjmp保存和恢复信号屏蔽字。但是,Linux 2.4.22和Solaris 9并不执行这种操作。

    不知是不是上边这个原因。

   但是我在redhat 9 linux 2.4.20-8系统上,在信号处理程序中使用setjmp,longjmp没有出现什么错误,跟使用sigsetjmp,longjmp一样。  
   
   不解!求MMMIX版主指点!

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
8 [报告]
发表于 2012-01-02 19:25 |只看该作者
embeddedlwp 发表于 2012-01-02 18:32
回复 1# bin_linux96

 但是我在redhat 9 linux 2.4.20-8系统上,在信号处理程序中使用setjmp,longjmp没有出现什么错误,跟使用sigsetjmp,longjmp一样。  


之所以要引入 sigsetjmp/siglongjmp,就是因為 setjmp/longjmp 在處理 signal mask 的時候在不同系統上行為不一致,可現在明明有了 sigsetjmp/siglongjmp 你非要在 signal handler 中用 setjmp/longjmp,這不是給自己找麻煩麼?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP