12

我有一个特定的函数(信号处理程序),我想检测它的递归,即确定该函数是否直接或间接调用了它自己。棘手的一点是,该函数在某一时刻调用了一些不受其控制的代码,而该代码可以做任何事情。

通常,我会写一些类似的东西

void foo() {
    static int recursed = 0;
    if(recursed) {
        ...
    }
    recursed = 1;
    othercode();
    recursed = 0;
}

但在这种情况下,我担心othercode可能会使用 alongjmp或类似来突破,导致recursed保持为 1。如果我的函数以这种方式跳出,我想确保它不会将自己视为递归 if 稍后被调用(longjmp否则它不是问题的事实)。

:我认为longjmp有可能。这othercode是来自其他一些野外代码的链接信号处理程序,并且确实存在用于恢复上下文的处理程序SIGSEGVlongjmp例如,作为“故障保护”异常处理程序)。请注意,longjmp在同步信号处理程序中使用通常是安全的。无论如何,我并不特别关心其他代码是否安全,因为它不在我的控制之下。

4

2 回答 2

3

不确定代码到底会是什么样子,但你可以使用静态 void * 来代替静态 int。与其将其设置为 1,不如将其设置为指向当前堆栈帧。除了检查它是否非零之外,您还要检查以确保来自下一个堆栈帧的返回地址recursed实际上指向 foo 代码中的一个位置,并且该位置位于recursed当前堆栈指针之上,即未弹出。

听起来非常脆弱且依赖于架构。

于 2013-06-05T04:58:55.543 回答
0

根据signal(7)的 POSIX 标准,longjmp() 不是从信号处理程序内部安全调用的调用之一。在考虑这个问题之前longjmp(3)文档说,您需要确保您调用的代码使用 sigsetjmp() 和 siglongjmp()

如果您正在调用的代码跳出信号处理程序,那么我看不出您如何知道何时更新您的recursed变量,除非您还控制这个未知代码回调到您的应用程序的回调函数。

于 2013-06-05T05:13:40.747 回答