繁体   English   中英

即使存在非本地跳转,也可以稳健地检测递归

[英]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.

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