我有一个特定的函数(信号处理程序),我想为其检测递归,即弄清楚该函数是直接调用还是间接调用了它自己。棘手的一点是,该函数在某一时刻调用了一些不受其控制的代码,并且该代码可以执行任何操作。

通常,我会写一些像

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

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

注意:我认为longjmp是可能的。 othercode是来自其他一些流行代码的链式信号处理程序,并且确实存在例如使用SIGSEGV还原上下文的longjmp(例如,作为“故障保护”异常处理程序)。请注意,在同步信号处理程序中使用longjmp通常是安全的。无论如何,我都不在乎其他代码是否完全安全,因为它不在我的控制之下。

最佳答案

不确定代码到底将执行什么操作,但是可以使用静态void *代替静态int。而不是将其设置为1,而是将其指向当前的堆栈框架。除了检查它是否为非零外,还要检查以确保recursed之后的下一个堆栈帧的返回地址实际上指向foo代码中的某个位置,并且recursed也位于当前堆栈指针之上,即未弹出。

听起来很脆弱,并且依赖于体系结构。

关于c - 即使存在非本地跳转,也能可靠地检测递归,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16931579/

10-10 21:20