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