首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于setjmp/longjmp

关于setjmp/longjmp
EN

Stack Overflow用户
提问于 2011-11-01 15:52:28
回答 4查看 10K关注 0票数 11

我正在调查setjmp/longjmp,发现setjmp保存指令指针、堆栈指针等寄存器。

但是,我无法理解的是,不能在调用setjmplongjmp之间修改线程本身堆栈中的数据。在这种情况下,longjmp不会像预期的那样工作。

为了说明清楚,例如,当longjmp恢复堆栈指针时,假设堆栈指针现在指向的内存中的数据与调用setjmp时不同。这会发生吗?如果那样的话,我们不是有麻烦了吗?

另外,语句的意思是,“在调用setjmp()例程的例程返回之后,可能不会调用longjmp()例程。”

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-11-01 16:16:59

堆栈指针标记堆栈的“已使用”部分和“未使用”部分之间的分隔。当您调用setjmp时,所有当前调用帧都位于“二手”侧,而在setjmp之后但在调用setjmp的函数返回之前发生的任何调用都将其调用帧放在保存的堆栈指针的“未使用”一侧。注意,在调用setjmp的函数之后调用setjmp会调用未定义的行为,因此不需要考虑这种情况。

现在,一些现有调用帧中的局部变量可能是在setjmp之后修改的,无论是通过调用函数还是通过指针,这就是为什么在许多情况下需要使用volatile的原因之一.

票数 6
EN

Stack Overflow用户

发布于 2011-11-01 16:10:51

setjmp()/longjmp()不是用来保存堆栈的,这就是setcontext()/getcontext()的目的。

标准指定在调用setjmp()的函数中定义的、在setjmp()longjmp()调用之间更改的非易失性自动变量的值在longjmp()之后未指定。出于同样的原因,对于如何调用setjmp()也有一些限制。

票数 6
EN

Stack Overflow用户

发布于 2011-11-01 16:28:14

C中的setjmp/longjmp (以下简称slj)特性很难看,其行为可能因实现而异。尽管如此,由于没有异常,slj有时在C中是必要的(请注意,C++提供的异常在几乎所有方面都优于slj,并且slj与许多C++功能交互不良)。

在使用slj时,您应该记住以下几点:假设例程父()调用常规Setter(),后者调用setjmp(),然后调用跳线器,后者反过来调用longjmp()。

  1. 代码可以合法地退出执行setjmp的作用域,而不需要执行长the;但是,一旦作用域退出,先前创建的jmp_buf就必须被视为无效。编译器可能不会做任何事情来标记它,但是任何使用它的尝试都可能导致不可预测的行为,可能包括跳转到任意地址。
  2. ()中的任何局部变量都会随着对longjmp()的调用而消失,使它们的值变得无关紧要。每当控件通过任何方式返回到父控件时,
  3. 的局部变量都将与调用Setter时一样,除非这些变量的地址被获取并使用这些指针进行更改;无论如何,setjmp/longjmp不会以任何方式影响它们的值。如果这些变量的地址没有被占用,那么setjmp()可能会缓存这些变量的值,而longjmp()可能会恢复它们。但是,在这种情况下,变量在缓存时和恢复时之间将无法改变,因此缓存/还原不会产生明显的效果。
  4. -- Setter中的变量可能被setjmp()缓存,也可能不被缓存。在进行了longjmp()调用之后,这些变量可能具有执行setjmp()时的值,或者在调用最终调用longjmp()的例程时所拥有的值,或者它们的任何组合。至少在某些C方言中,这些变量可能被声明为“易失性”,以防止它们被缓存。

尽管setjmp/longjmp()有时是有用的,但它们也可能非常危险。在大多数情况下,不存在导致未定义行为的保护错误代码,而且在许多现实世界中,不适当的使用可能会导致糟糕的事情发生(与某些类型的未定义行为不同,实际上的结果可能与程序员的意图一致)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7969075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档