zoukankan      html  css  js  c++  java
  • 【原创】setjmp longjump一些注意点及使用方法

    setjmp longjump一些注意点及使用方法

    jmp_buf结构体的定义

    #define _JBLEN  9
    typedef struct { int _jb[_JBLEN + 1]; } jmp_buf[1];

    int a()

    {

      jmp_buf env;

      if(setjmp(env) != 0) {exit(0);} //若是异常跳到此,则退出

      longjmp(env, 5); //异常跳转,错误码5

    setjmp(env) 后,env保存的是当前函数a的堆栈地址信息(存在寄存器中)(栈顶指向地址,计数器等),

    若此时a没返回,调用了longjmp(env, ret),则寄存器中的数据恢复成env里保存的地址等,相当于程序又退回到setjmp处去运行了

    但是栈里的数据还是运行longjmp时的状态,并且会设置setjmp的返回值为ret,此时可以根据ret的值进行switch错误处理(=0是第一次正常运行)。

    但是如果是在函数a return后,再调用b函数,b函数内执行longjmp(env, ret),此时是不对的,容易出现段错误。因为env中存的运行时寄存器状态(地址,计数器等)是针对a的栈环境有效,在b函数的栈里可能就是一些无效的值,所以不能这么写。

    所以用这2个接口要注意:1.先setjmp再longjmp  2.longjmp的位置必须在setjmp的有效范围内(不能在setjmp所在函数a外,但可以在a里面调用的函数b里)

    C++中伪代码

    try

      xxxx

        throw(xx)

          xxxx

    catch

      switch 处理错误码等

    end

    C里面用setjmp实现类似try catch功能

    #include <setjmp.h>

    ....

    jmp_buf env;

    switch(setjmp(env)){

      case 0:

        xxxx

          if 出现异常 {longjump(env, 分类处理的错误码);}

        xxxx

        break;

      case 某个错误码:

        错误处理

        break;

      default:

        break;

    }

    ....

    另:《unix环境高级编程》7.10小节有对这个函数的讲解

  • 相关阅读:
    qemu-img check命令详解
    cinder migrate基础内容-1
    lvm常用指令
    ceph 快照,克隆
    http请求工作流程
    Python 生成二维码
    python 往 elasticsearch 存入数据时,文档字段类型问题注意事项
    python 往 elasticsearch 存入数据,然后通过kinaba 检索分析
    git 删除某次提交
    git 强制回滚【覆盖】远程 源码库
  • 原文地址:https://www.cnblogs.com/vanishfan/p/4318616.html
Copyright © 2011-2022 走看看