c语言中setjmp与longjmp(4)

sigsetjmp() is similar to setjmp(). If savesigs is non-zero, the set of blocked signals is saved in env and will be restored if a siglongjmp() is later performed with this env.

Exception handling
在这种情况下使用时,主要用于以下几种情况:
* As the condition to an if, switch or iteration statement
* As above in conjunction with a single ! or comparison with an integer constant
* As a statement (with the return value unused)

过多的滥用可能会导致出现错误(cause undefined behaviour)。编译器和环境不会去在意是否使用了这些约定。
另一个例子如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
 
void first(void);
void second(void);
 
/* This program's output is:
 
calling first
calling second
entering second
second failed with type 3 exception; remapping to type 1.
first failed, exception type 1
 
*/
 
/* Use a file scoped static variable for the exception stack so we can access
 * it anywhere within this translation unit. */
static jmp_buf exception_env;
static int exception_type;
 
int main() {
    volatile void *mem_buffer;
 
    mem_buffer = NULL;
    if (setjmp(exception_env)) {
        /* if we get here there was an exception */
        printf("first failed, exception type %d/n", exception_type);
    } else {
        /* Run code that may signal failure via longjmp. */
        printf("calling first/n");
        first();
        mem_buffer = malloc(300); /* allocate a resource */
        printf(strcpy((char*) mem_buffer, "first succeeded!")); /* ... this will not happen */
    }
    if (mem_buffer)
        free((void*) mem_buffer); /* carefully deallocate resource */
    return 0;
}
 
void first(void) {
    jmp_buf my_env;
 
    printf("calling second/n");
    memcpy(my_env, exception_env, sizeof(jmp_buf));
    switch (setjmp(exception_env)) {
        case 3:
            /* if we get here there was an exception. */
            printf("second failed with type 3 exception; remapping to type 1./n");
            exception_type = 1;
 
        default: /* fall through */
            memcpy(exception_env, my_env, sizeof(jmp_buf)); /* restore exception stack */
            longjmp(exception_env, exception_type); /* continue handling the exception */
 
        case 0:
            /* normal, desired operation */
            second();
            printf("second succeeded/n");  /* not reached */
    }
    memcpy(exception_env, my_env, sizeof(jmp_buf)); /* restore exception stack */
}
 
void second(void) {
    printf("entering second/n" ); /* reached */
    exception_type = 3;
    longjmp(exception_env, exception_type); /* declare that the program has failed */
    printf("leaving second/n"); /* not reached */
}

 

具体详见wiki百科 http://en.wikipedia.org/wiki/Setjmp.h

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
setjmplongjmpC语言提供的两个非常重要的函数,目的是实现函数间的跳转和状态保存。 setjmp函数用于保存当前函数执行的上下文,同时返回一个int类型的值。这个值由setjmp函数自动生成,用于之后调用longjmp函数时确定跳转目标。 longjmp函数则用于恢复之前setjmp所保存下来的上下文,使得程序能够直接跳转到指定的目标。 下面是setjmplongjmp在mips汇编语言的实现: setjmp: ``` #setjmp implementation in MIPS assembly language .text .align 2 .globl setjmp .ent setjmp setjmp: addi sp, sp, -32 # allocate stack frame sw ra, 28(sp) # save return address sw fp, 24(sp) # save frame pointer addi fp, sp, 32 # set new frame pointer sw a0, 0(fp) # save jmp_buf li v0, 0 # return 0 jr ra .end setjmp ``` longjmp: ``` #longjmp implementation in MIPS assembly language .text .align 2 .globl longjmp .ent longjmp longjmp: lw fp, 24(sp) # restore frame pointer lw ra, 28(sp) # restore return address addi sp, sp, 32 # deallocate stack frame lw t0, 0(fp) # restore jmp_buf lw ra, 4(t0) # restore return address lw sp, 8(t0) # restore stack pointer lw s0, 12(t0) # restore frame pointer jr ra .end longjmp ``` 以上是setjmplongjmp在MIPS汇编语言的实现。需要注意的是,这里使用了MIPS体系结构的调用约定,即函数返回值在v0寄存器,函数参数在a0-a3寄存器,被调用者保存的寄存器在栈帧。在实际使用,应根据特定的编译器和操作系统的要求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值