簡體   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