究竟是什么"程序状态" setjmp保存吗?

时间:2014-08-12 14:24:22

标签: c longjmp setjmp

我已经读过setjmp“将程序状态保存在传入的jmp_buf变量中”,但是我还没有找到任何关于它究竟是什么的描述。它是否复制了所有应用程序的内存?只是寄存器?堆栈?

4 个答案:

答案 0 :(得分:4)

以下内容来自Peter Prinz和Tony Crawford的 C in a Nutshell

  
    

setjmp()宏将调用时的当前环境保存在其参数指定的缓冲区中。环境包括堆栈,以及具有自动存储持续时间的所有变量。

  

以下是 ISO / IEC 9899:TC2 在第7.13节中所说的内容:

  
    

调用setjmp宏的环境包含足以调用longjmp函数以将执行返回到正确的块并调用该块的信息,如果它是递归调用的。它不包括浮点状态标志,打开文件或抽象机器的任何其他组件的状态。

  

以下是P.J. Plauger在他的书 The Standard C Library 中的有趣参考:

  
    

实施setjmp的一个危险在于表达式评估。典型的计算机具有一定数量的寄存器,用于在评估表达式时保存中间结果。但是,写一个足够复杂的表达式,你可能会耗尽可用的寄存器...... setjmp必须猜测存储在jmp_buf数据对象中的“调用上下文”的数量。可以肯定的是,必须保存某些寄存器。

  

最后,来自Peter Van Der Linden的 Expert C Programming

  
    

Setjmp将程序计数器的副本和当前指针保存到堆栈顶部。

  

根据以上信息,我认为“当前环境”需要实施。

答案 1 :(得分:3)

根据平台ABI,它只是需要在函数调用中保留的寄存器。

来源:在各种操作系统上对x86,x64,arm32,arm64上的setjmp进行反汇编。

答案 2 :(得分:1)

setjmp()函数保存大多数通用寄存器的内容,其保存方式与保存在任何函数条目中的方式相同。它还保存堆栈指针和返回地址。所有这些都放在缓冲区中。然后它安排函数返回零。

longjmp()函数恢复通用寄存器和堆栈指针,然后跳转到先前保存的返回地址。在实践中,它可以显式地执行此操作,或者通过设置堆栈并执行正常的函数返回。在这种情况下,该函数返回一个非零值。

原理是一样的,但在我遇到的许多不同的CPU中,细节有很大不同。

答案 3 :(得分:0)

来自setjmp联机帮助页

   setjmp()  and  longjmp(3)  are  useful for dealing with errors and interrupts encountered in a
   low-level subroutine of a program.  setjmp() saves the stack context/environment  in  env  for
   later  use  by longjmp(3).  The stack context will be invalidated if the function which called
   setjmp() returns.

基本上,它会记住当前的堆栈位置和寄存器状态。当你调用longjmp时,你会跳回到相同的程序计数器和堆栈位置,并恢复一些额外的寄存器。

这些通常被称为“非本地的”。它们不像是一个可以复制内存状态或类似内容的分支。