【问题标题】:setjmp and longjmp - understanding with examplessetjmp 和 longjmp - 用例子理解
【发布时间】:2011-07-31 16:58:01
【问题描述】:

我知道setjmp和longjmp的定义。 setjmp 将环境存储在堆栈上下文中,另一个用于恢复。

但我认为我在某些地方缺乏理解。有人可以借助好的示例向我解释我如何保证,如何保存以及如何恢复?

我看到 jmp_buf 中指向了很多 CPU 寄存器。但是我如何保证它被恢复了呢?

请用简洁的例子帮助我解释。我用谷歌搜索并提到了其他有关堆栈溢出的问题,但没有一个给出明确的例子。

提前非常感谢。

P.S:它应该只来自 Linux/Unix 上下文。

【问题讨论】:

标签: linux unix setjmp


【解决方案1】:

当调用longjmp()时,所有这些寄存器都会自动恢复,并在对应的setjmp()调用处继续执行,但这一次setjmp()有不同的返回值(类似于fork()有不同的返回值在父母和孩子)。

setjmp()/longjmp()只保存有限的环境。特别是,它们只保存堆栈指针,而不是完整堆栈,因此您只能返回相同的函数或调用函数。 POSIX 有setcontext(),它允许在堆栈之间切换,使其更直接地用于实现诸如用户空间线程(原纤维、绿色线程等)之类的东西。

【讨论】:

  • 感谢您的回答,对于迟到的回复感到抱歉。我只是在检查你和维基百科的例子。
  • 当您最初不屏蔽 sigprocmask(SIG_UNBLOCK, &ss, NULL); 时,它的意义何在?
  • 这个例子我得到了,谢谢。因此,在第一个实例中,setjmp 返回“0”,因此不进入循环,而是发生除以零(SIGFPE),将其带到信号处理程序,从那里调用 longjmp,并返回非零值,因此进入if 语句,最后退出。现在很清楚,但为什么是 sigprocmask?它是多余的,除非您首先使用了 SIG_BLOCK。对吗?
  • @kingsmasher1:请参阅注释,根据 POSIX,信号在执行其自己的信号处理程序时被阻塞(除非您将 SA_NODEFER 传递给 sigaction())。通常,信号从处理程序返回时会被解除阻塞,但我们永远不会返回,因此显式解除阻塞。最好改用sigsetjmp()/siglongjmp(),他们应该注意这一点。
  • 使用SA_NODEFER 会更好,至少从性能的角度来看是这样。 sigprocmasksigsetjmpsiglongjmp 每一个都会产生一个系统调用,这是相当昂贵的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多