我正在调查setjmp/longjmp,发现setjmp保存指令指针、堆栈指针等寄存器。
但是,我无法理解的是,不能在调用setjmp和longjmp之间修改线程本身堆栈中的数据。在这种情况下,longjmp不会像预期的那样工作。
为了说明清楚,例如,当longjmp恢复堆栈指针时,假设堆栈指针现在指向的内存中的数据与调用setjmp时不同。这会发生吗?如果那样的话,我们不是有麻烦了吗?
另外,语句的意思是,“在调用setjmp()例程的例程返回之后,可能不会调用longjmp()例程。”
发布于 2011-11-01 16:16:59
堆栈指针标记堆栈的“已使用”部分和“未使用”部分之间的分隔。当您调用setjmp时,所有当前调用帧都位于“二手”侧,而在setjmp之后但在调用setjmp的函数返回之前发生的任何调用都将其调用帧放在保存的堆栈指针的“未使用”一侧。注意,在调用setjmp的函数之后调用setjmp会调用未定义的行为,因此不需要考虑这种情况。
现在,一些现有调用帧中的局部变量可能是在setjmp之后修改的,无论是通过调用函数还是通过指针,这就是为什么在许多情况下需要使用volatile的原因之一.
发布于 2011-11-01 16:10:51
setjmp()/longjmp()不是用来保存堆栈的,这就是setcontext()/getcontext()的目的。
标准指定在调用setjmp()的函数中定义的、在setjmp()和longjmp()调用之间更改的非易失性自动变量的值在longjmp()之后未指定。出于同样的原因,对于如何调用setjmp()也有一些限制。
发布于 2011-11-01 16:28:14
C中的setjmp/longjmp (以下简称slj)特性很难看,其行为可能因实现而异。尽管如此,由于没有异常,slj有时在C中是必要的(请注意,C++提供的异常在几乎所有方面都优于slj,并且slj与许多C++功能交互不良)。
在使用slj时,您应该记住以下几点:假设例程父()调用常规Setter(),后者调用setjmp(),然后调用跳线器,后者反过来调用longjmp()。
尽管setjmp/longjmp()有时是有用的,但它们也可能非常危险。在大多数情况下,不存在导致未定义行为的保护错误代码,而且在许多现实世界中,不适当的使用可能会导致糟糕的事情发生(与某些类型的未定义行为不同,实际上的结果可能与程序员的意图一致)。
https://stackoverflow.com/questions/7969075
复制相似问题