繁体   English   中英

检查跳转缓冲区是否有效(非本地跳转)

[英]Check if jump buffer is valid or not (non-local jumps)

我们在代码库中实现了“longjmp-Restore堆栈环境”。 longjmp例程由特定的error_exit函数调用,该函数可以从任何地方调用。

因此,当调用longjmp时,可能没有调用setjmp例程,并且缓冲区可能具有导致崩溃的无效值。

我可以将缓冲区初始化为NULL还是可以检查是否有未设置或无效的值。 一种方法是每当调用setjmp时我都可以设置一个标志变量,我可以检查它。 但那只是一个黑客。

void error_exit()
{
    extern jmp_buf buf;
    longjmp(buf, 1);
    return 1;
}

我可以这样做吗?

void error_exit()
{
    extern jmp_buf buf;

    if(buf)
       longjmp(buf, 1);

    return 1;
}

代码是混合的C / C ++,我知道我可以在任何地方用C ++异常处理替换setjmplongjmp ,但现在这是不可能的,我可以用无效缓冲区捕获longjmp导致崩溃吗?

jmp_buf没有特别好记录。 在linux标题中,你可以找到类似的东西:

typedef int __jmp_buf[6];

struct __jmp_buf_tag {
  __jmp_buf __jmpbuf;       /* Calling environment.  */
  int __mask_was_saved;     /* Saved the signal mask?  */
  __sigset_t __saved_mask;  /* Saved signal mask.  */
};

typedef struct __jmp_buf_tag jmp_buf[1];

将其设置为零然后测试整个大小可能会浪费时间。

就个人而言,我会保留一个指向此缓冲区的指针,将其初始化为NULL并在setjmp之前设置它。

  jmp_buf physical_buf;
  jmp_buf *buf = NULL;
  ...
  buf = &physical_buf;
  if (setjmp(*buf)) {
    ...
  }

这与拥有单独的旗帜的想法相同。 此外,您可以根据需要动态分配jmp缓冲区。

知道缓冲区是否已设置并不是一个真正的问题,您可以只拥有一个包含该信息的辅助变量。

真正的问题是你不能longjmp横行,这是有不确定的行为,并且由于根本原因无法工作。 从您调用setjmp的函数返回后,该函数的堆栈将被无效并被后续调用覆盖。 所以setjmp上下文不再有效。 我不是在谈论jmp_buf本身,而是谈论它中记录的堆栈状态。

所以你唯一能做的就是有一个辅助变量来记录你是否已经设置了缓冲区,并且一旦你将函数与setjmp放在一起就会解除设置。

好问题。

据我所知,从POSIX标准( http://pubs.opengroup.org/onlinepubs/9699919799/functions/longjmp.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/setjmp.html http ://pubs.opengroup.org/onlinepubs/9699919799/basedefs/setjmp.h.html ) jmp_buf是不透明的,除了后一个引用要求它是一个数组类型:

<setjmp.h>头文件应定义数组类型jmp_buf和... sigjmp_buf

我相信在实践中你会保存bzero()缓冲区,并在跳转到它之前将它与零进行比较,但理论上,在一些尚待发现的POSIX系统中,所有零jmp_buf都是允许的。 如果你(我不会)打扰这一点,一个选择是set_jmp虚拟缓冲区你永远不会使用一些跳跃点,然后memcmpjmp_buf反对这种假jmp_buf做前跳。 这样你只能使用合法的(即由set_jmp初始化) jmp_buf

另一种方法是维护一个单独的标志,指示它是否已经初始化(或者在struct包装)。

我相信我应该在manpage re set_jmplong_jmp上插入强制警告,因为它使应用程序难以阅读,并且对信号处理有不可预测的影响(后者用sigsetjmp() )。 此外,在C ++上下文中,它显然不会展开您的异常处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM