誰かがオペレーティングシステムプログラマーであるか、システムレベルのライブラリコードを書いている場合は、セグメンテーションフォールトハンドラーを書くのが理にかなっています。たとえば、OSプログラマーは、そのアプリケーションプロセスにシグナルSIGSEGVを送信するコードを記述します。または、システムライブラリプログラマがその信号SIGSEGVを処理し、セグメンテーション違反を作成するためのライブラリコードによって引き起こされた操作を元に戻す場合があります。しかし、なぜCのアプリケーションプログラマーはセグメンテーションフォールトハンドラーを作成する必要があるのでしょうか。彼がハンドラーを作成する場合、彼はすでにメモリの一部を破損しています。アプリケーションプログラマーがセグメンテーション違反を処理し、プログラムの実行を継続するためのインスタンスを提供できますか?
5 に答える
私の知る限り、セグメンテーションハンドラーはアプリケーションレベルで記述して、デバッグ情報(メモリダンプ、レジスタの値、その他のアプリケーション固有の情報など)を出力してからアプリケーションを終了できます。
セグメンテーション違反によりメモリが破損している可能性があるため、ダンプする正しい情報がすべて得られる場合と得られない場合があることに注意してください。
セグメンテーション違反の後、プログラムの実行を続行できる状況を認識していません。SOの他の尊敬されるユーザーがこれに光を当てることができるかもしれません.
処理SIGSEGV
などにより、状態を保存し、是正措置を取ることができます。 Mr 32 (およびその他) は正しく、メイン ライン コードを単純に再起動することはできません。代わりに次のことができます。これにより、メイン ラインの再開が可能になります。また、関数のみを呼び出すには細心の注意を払う必要があります。これは非常にトリッキーです。ただし、一部のアプリケーションは、longjmp()
siglongjmp()
async safe
- 健康/安全 - 壊滅的な状態が起こらないようにするため。
- 財務 - 金銭の損失につながる可能性のあるトランザクション データの損失。
- 制御システム - 化学者向けのサンプル滴定ソフトウェア。
- 診断 - 将来のソフトウェアを改善するために、クラッシュ状態がログに記録される場合があります。ジェイによると
通話exit()
はおそらく良くなく、_exit()
より良いでしょう。違いはatexit()
呼び出しです。
参照: Cert async safe、Glibc async-safe list、Similar question、longjmp()
および signal not port、async-safe
これらは OS ごとに異なります。アドバイスはシステムに依存します。
その他の問題
- プログラムで使用されるライブラリによっては、
SIGSEGV
. 間違いなく Empress データベースのバージョンがそれをフックします。ライブラリが何を使用しているかを知り、それらとの間で連鎖する必要があります。 - スタックとヒープ (malloc など) が破損する可能性がある
jump_buf
ため、エラー処理は特に偏執的である可能性があります。 - 重要な部分をより単純な別のタスクに延期するなど、他の多くの代替ソリューションがあります。
longjmp()
シグナルからの呼び出しは、C99 標準に従って定義されていませんが、ほとんどのシステムでうまく機能します。siglongjmp()
あなたがより衒学的であれば使用することができます。診断ログには問題ありませんが、リストされている他の用途 (安全性など) には使用しません。ウォッチドッグ タスクに通知する方が適切かもしれません。
SIGKILL、SIGCONT、SIGSTOP以外のシグナルをキャッチできます。したがって、SIGSEGVをキャッチすることはできますが、終了しないことにした場合、動作は予測できなくなります。
library programmer might handle that signal SIGSEGV and may
undo the operations caused by the library code for creating segmentation
セグメンテーション違反が発生すると、スレッドまたはプロセスが停止します。
セグメンテーション違反の原因となったコードを元に戻すことはできません。むしろ、そのコンポーネントを再起動できます。
セグメンテーション違反は、想定されていないメモリの部分にプログラムが書き込むことによって発生します。アプリケーション開発者は、これを処理するためのコードを作成するのではなく、それを回避するためのコードを作成します。これが、メモリへの書き込み時にチェックをバインドした理由です。