複数のスレッドを開始するアプリケーションがあります。シグナルハンドラーを使用してシグナルをキャッチしています。
アプリケーションを終了させたくありませんSIGSEGV
; シグナルが発生したスレッドのみを終了し、他のスレッドでアプリケーション全体のフローを継続したいと思います。出来ますか?
複数のスレッドを開始するアプリケーションがあります。シグナルハンドラーを使用してシグナルをキャッチしています。
アプリケーションを終了させたくありませんSIGSEGV
; シグナルが発生したスレッドのみを終了し、他のスレッドでアプリケーション全体のフローを継続したいと思います。出来ますか?
が発生した場合SIGSEGV
は、プログラムが未定義の動作を既に呼び出していることを示します。つまり、プログラム全体の状態が未定義/不確定/無効です。実際には、回復して走り続けることができる可能性がありますが、保証はなく、危険な場合があります。
asveikau が述べたようlongjmp
に、シグナル ハンドラーから抜け出してクリーンアップを試みることもできますが、クラッシュがmalloc
、free
、printf
、またはグローバル データまたは共有されているデータの状態を変更する関数の途中で発生した場合、これはさらに混乱を招く可能性があります。他のスレッド、またはlongjmp
宛先のクリーンアップ コードでアクセスされるスレッド。状態が壊れているか矛盾している可能性があります。また、ロックが保持され、永久に解放できないままになっている可能性があります。
これが起こらないことを確認できる場合 (たとえば、動作が正しくないスレッドが async-signal-unsafe 関数をまったく呼び出さない場合longjmp
) は、シグナル ハンドラから安全に呼び出してpthread_exit
.
sa_mask
別の方法として、すべてのシグナルをforに追加してからシグナル ハンドラーSIGSEGV
に書き込むことにより、シグナル ハンドラーでスレッドを永続的にフリーズすることもできますfor (;;) pause();
。これは 100% "安全" ですが、クラッシュしているスレッドによってロックが保持されていた場合、プロセスがデッドロック状態になる可能性があります。これはおそらく、破損した状態を他のスレッドに公開し、データをさらに破壊するよりも「悪くない」...