这篇文章主要讲解了“setjmp的使用方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“setjmp的使用方法”吧!
成都创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站制作、成都网站设计、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的五台网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
以前对于C语言的setjmp和longjmp从来都是知道有这么个函数, 但是不知道什么情况下要使用, 甚至于不知道setjmp的实现机制是什么样子的.
这次在实现coroutine的过程中虽然没有使用setjmp来实现, 但是由于setjmp来实现coroutine的所有操作都是可以在用户态进行的, 因此顺便研究了一下setjmp的实现机制.
与我猜测大致一样, 在call stack上来讲setjmp一定先于或等于longjmp处于的位置, 这样其实longjmp所做的不过就是将当前寄存器上下文恢复成setjmp函数保存的值即可. 调用longjmp的函数与调用setjmp的函数共用一个栈空间, 因此longjmp恢复完寄存器后造成的结果就是恢复寄存器上下文并将栈空间释放到setjmp位于的地方.
那么这就很好解释为什么不能将setjmp使用函数再封装一层了, 假设使用函数封装setjmp代码如下:
int try(jmp_buf jmp)
{
int err;
err = setjmp(jmp);
printf("%d\n", err);
return err;
}
void execption(jmp_buff j, int err)
{
return longjmp(j, err)
}
int main()
{
jmp_buff j;
try(j);
execption(j, 2);
}
如上代码其实try函数与execption共用部分栈空间, 当longjmp回到try函数时, 即使用寄存器被恢复了, 但是事实上try函数的栈结构已经被破坏了, 此时longjmp之后try函数的行为是无法预料的.
------------------------
| main |
|-----------------------
| try | excption |
|---------| |
|---------|------------|
在使用setjmp时一定要注意栈是否被覆盖的问题, 即调用setjmp时所保存的esp的信息直到调用前longjmp之前, 不应该会出更有比setjmp保存esp时更多的空闲空间(如栈是自顶向下增加, 则setjmp到longjmp之间出现的esp的值绝不能大于setjmp保存的esp的值.
感谢各位的阅读,以上就是“setjmp的使用方法”的内容了,经过本文的学习后,相信大家对setjmp的使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!