setjmp和longjump 用法
2016-07-21 10:03
429 查看
与abort()和exit()相比,goto语句看起来是处理异常的更可行方案。goto是本地的,它只能跳到所在函数内部的标号上,而不能将控制权转移到所在程序的任意地点.为了解决这个限制,C函数库提供了setjmp()和longjmp()函数,它们分别类似于非局部标号和goto作用。
头文件 setjmp.h 申明了这些函数及jmp_buf数据类型。
原理非常简单:
1:setjmp(jump)设置“jump”点,用正确的程序上下文填充jmp_buf对象jump.这个上下文包括程序指针、栈指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
2:以后调用longjmp(jump,r)的效果就是一个非局部的goto或“长跳转”到由jump描述的上下文处(也就是到那原来设置jump的setjmp()处)。当作为长跳转的目标而被调用时,setjmp()返回r或1(如果r设为0的话),(setjmp()不能在这种情况时返回0)
通过两类返回值,setjmp()让你知道它正在被怎么使用。当设置jump时,setjmp()如你期望地执行;但当作为长跳转的目标时,setjmp()就从外面“唤醒”它的上下文。你可以用longjmp()来终止异常,用setjmp()标记相应的异常处理程序。
上边程序在调用longjump 时,就跳转到setjump处再次执行setjump,这时setjump返回非0值,从而执行else分支。
上边代码会报Segmentation fault (core dumped),这是由于执行f()函数时,setjmp会保存当前上下文,但是栈指针是当前f()函数中的,当f()返回时,会出栈,这时栈指针是相对main()的,这个时候调用longjump就将之前相对f()栈指针设置为main()函数栈指针,从而栈被dirt,虽然程序指针是对的。
头文件 setjmp.h 申明了这些函数及jmp_buf数据类型。
原理非常简单:
1:setjmp(jump)设置“jump”点,用正确的程序上下文填充jmp_buf对象jump.这个上下文包括程序指针、栈指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
2:以后调用longjmp(jump,r)的效果就是一个非局部的goto或“长跳转”到由jump描述的上下文处(也就是到那原来设置jump的setjmp()处)。当作为长跳转的目标而被调用时,setjmp()返回r或1(如果r设为0的话),(setjmp()不能在这种情况时返回0)
通过两类返回值,setjmp()让你知道它正在被怎么使用。当设置jump时,setjmp()如你期望地执行;但当作为长跳转的目标时,setjmp()就从外面“唤醒”它的上下文。你可以用longjmp()来终止异常,用setjmp()标记相应的异常处理程序。
#include <setjmp.h> #include <stdio.h> jmp_buf j; void raise_exception(void) { printf("exception raised\n"); longjmp(j, 1); /* jump to exception handler */ printf("this line should never appear\n"); } int main(void) { if (setjmp(j) == 0) { printf("''setjmp'' is initializing ''j''\n"); raise_exception(); printf("this line should never appear\n"); } else { printf("''setjmp'' was just jumped into\n"); /* this code is the exception handler */ } return 0; }
上边程序在调用longjump 时,就跳转到setjump处再次执行setjump,这时setjump返回非0值,从而执行else分支。
jmp_buf j; void f(void) { setjmp(j); } int main(void) { f(); longjmp(j, 1); /* logic error */ return 0; }
上边代码会报Segmentation fault (core dumped),这是由于执行f()函数时,setjmp会保存当前上下文,但是栈指针是当前f()函数中的,当f()返回时,会出栈,这时栈指针是相对main()的,这个时候调用longjump就将之前相对f()栈指针设置为main()函数栈指针,从而栈被dirt,虽然程序指针是对的。
相关文章推荐
- 解除springmvc限制参数对象映射个数不能超过256个
- char * a, char ** a, char * a[], char a[][], char * a[][], char ** a[][], char * a [][][]学习
- Linux C多线程编程注意事项及数据处理
- 递归的logN的优化(菲波那契数列,青蛙上台阶问题,母牛问题)!!!!
- Android Selector使用案例
- Android学习路线图
- jsp学习(三)
- Android学习路线图
- Android学习路线图
- Android堆栈分析
- C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限
- java jsp与jquery easyui整合代码下载,有n个demo教程
- Android动画之逐帧动画
- nyoj 914 Yougth 最大化
- Swiper的初始化与更新
- 利用VMware優化工具優化Windows 10系統
- maven的多环境打包部署与web.xml整合
- Dubbo架构设计详解
- MongoDB学习笔记—Linux下搭建MongoDB环境
- webview支持特效,页面内跳转