回答に何を期待するかは 100% 明確ではありませんが、一般的な考え方を説明しようと思います。
まず第一に、「デバッグ」シグナルと呼べるものは次のとおりです (およびそれらがいつ期待されるか):
SIGILL
、SIGFPE
— プログラムが不正な命令を実行しようとすると、通常、間違ったCFLAGS
アセンブリや独自のアセンブリ (または深刻なランダム破損) が表示される可能性があります。
SIGABRT
— 呼び出しが原因abort()
で、たとえばassert()
. ライブラリから取得することもできるため、通常は処理する必要があります。
SIGSEGV
— 無効なメモリ アクセス。おそらく、すでにすべてのことを知っているでしょう。
SIGBUS
mmap()
— I/O を実行し、アクセスできないメモリを読み書きしようとすると発生する可能性があります。mmap()
また、ベースの I/O がスペースを使い果たしたときにも起こりました。
SIGPIPE
— パイプで I/O を実行しているときに、パイプが反対側から切断された場合。
- POSIX
SIGSYS
は無効なシステム コールも指定しており、おそらくそれもキャッチしたいと思うでしょう (ただし、私はそれを確認できませんでした)。
関連する操作を使用している場合は、これらのシグナルを処理する必要があると思います。#ifdef
それらはすべてPOSIXにありますが、すべてのシステムがそれらを実装しているかどうかはわかりませSIG*
ん#ifdef
。
プログラムの実行中に遭遇する可能性のあるその他のシグナルは次のとおりです。
SIGALRM
— を使用する場合alarm()
、
SIGPOLL
— ポーリングを使用する場合、
SIGCHLD
— プロセスを生成するとき…</li>
そして、これらは基本的に、関連する操作を使用するときにとにかく処理しているシグナルであり、デフォルトで終了しますが、とにかくそれらのための他のハンドラーが必要です。
そして最後に、 userによって送信されたシグナルを処理することを期待する場合、それは厳しいケースです — ユーザーは事実上すべてのシグナルを送信できるからです。man signal
したがって、すべてを適切に処理したい場合は、デフォルトで終了アクションまたは中止アクションになるすべてのシグナルをキャッチする必要があります。
期待できるシグナルの一般的なサブセットをキャッチしたい場合は、次のようになります。
SIGHUP
プログラムを持つ端末 (または関連する場合は他の親) が死亡したとき、
SIGINT
^c キーの場合、
SIGQUIT
^\ キーの場合、
SIGTERM
終了要求(kill
デフォルトでプログラムおよび他の同様のツールによって送信される)の場合、
SIGUSR1
およびSIGUSR2
ユーザー定義のシグナルであり、通常はプログラム固有のアクションを実行するために使用されます。それらはユーザーによって送信され、何らかの理由でデフォルトでプログラムを強制終了します。
もありますSIGKILL
が、標準ではキャッチできません。
最も重要な信号をカバーできたことを願っています。私は Linux ユーザーであり、他の *nix にもキャッチしたい特定のシグナルがいくつかあることに注意してください。
それは通常、あなたが何を達成したいかによって異なります。ソフトウェアがランダムなシグナルによって中断されるのを防ぐことは良い考えですが、それらすべて、特にユーザーによって直接送信されるものによって強制終了されるのを防ぐことは通常価値がありません。
ユーザーがアプリを強制終了したい場合は、とにかくそれを達成できます。一般的なものを処理するだけで十分なはずSIGINT
です —そしてSIGTERM
. SIGQUIT
私は個人的に(^\ キー) が重要なタスクさえも終了させずにアプリケーションを強制終了することを期待しています (SIGKILL
そうです)。
編集します。最後の文の論理的根拠として、次のことを考えてみてください: 重要なデータを削除したなど、ばかげたことをしただけです。または、終了時のクリーンアップ手順に何か問題があることに気付いただけです。シグナルがキャッチされないようにプログラムを終了したいのですが、すぐに戻ります。たとえそれが壊れたデータになるとしても、データがないよりも壊れたデータを持っていることを本当に好むことがあります (必要なものを回復できることを願っています)。