12

再帰を検出したい特定の関数 (シグナル ハンドラ) があります。つまり、関数が直接または間接的に自分自身を呼び出しているかどうかを調べます。注意が必要な点は、ある時点で関数がその制御下にないコードを呼び出し、そのコードが何でもできることです。

通常、私は次のようなものを書くだけです

void foo() {
    static int recursed = 0;
    if(recursed) {
        ...
    }
    recursed = 1;
    othercode();
    recursed = 0;
}

othercodeしかし、この場合、 a などを使用しlongjmpて抜け出し、結果として 1 のままになる可能性があることを懸念していrecursedます。後で呼び出された場合の再帰 (それ以外の場合は、それがlongjmp外れるという事実は問題ではありません)。

longjmp可能性が高いと思います。これは、他のイン ザ ワイルド コードからのチェーン シグナル ハンドラであり、たとえば、コンテキストを復元するために使用othercodeするハンドラが存在します(たとえば、「障害保護」例外ハンドラとして)。同期シグナルハンドラでの使用は、一般的に安全であることに注意してください。いずれにせよ、他のコードが安全かどうかは特に気にしません。それは私の管理下にあるものではないからです。SIGSEGVlongjmplongjmp

4

2 に答える 2

0

signal(7)の POSIX 標準によると、 longjmp() は、シグナル ハンドラ内から安全に呼び出すことができる呼び出しの 1 つではありません。この問題について考える前に、longjmp(3)のドキュメントによると、呼び出しているコードが sigsetjmp() と siglongjmp() を使用していることを確認する必要があります。

recursed呼び出しているコードがシグナル ハンドラーから飛び出している場合、この未知のコードがアプリケーションにコールバックするコールバック関数も制御しない限り、変数を更新するタイミングを知る方法がわかりません。

于 2013-06-05T05:13:40.747 に答える