[英]Detect recursion robustly even in the presence of non-local jumps
我有一个特殊的函数(信号处理程序),我想检测它的递归,即确定函数是否直接或间接调用自身。 棘手的一点是该函数在一个点上调用一些不受其控制的代码,并且该代码可以执行任何操作。
通常,我只会写一些类似的东西
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
位于当前堆栈指针之上,即不弹出。
听起来非常脆弱,依赖于架构。
根据信号(7)的POSIX标准,longjmp()不是从信号处理程序内部调用的安全调用之一。 在考虑这个问题之前, longjmp(3)文档说,你需要确保你调用的代码使用sigsetjmp()和siglongjmp()
如果你调用的代码跳出信号处理程序,那么我不知道你怎么知道何时更新你的recursed
变量,除非你还控制这个未知代码回调到你的应用程序的回调函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.