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