web-dev-qa-db-ja.com

システムはいつSIGTERMをプロセスに送信しますか?

サーバープログラムがSIGTERMを受信して​​停止しました(終了コード0で)。それに十分なメモリがあったと確信しているので、私はこれに驚いています。 linux(busybox)はどのような条件でSIGTERMをプロセスに送信しますか?

24
michelemarcon

これが問題であることが判明した場合に何らかの解決策があるように、これを回答として投稿します。

終了ステータス0は、正常なプログラムからの通常の終了を意味します。 終了プログラム は、終了ステータスとして0〜255の整数を選択できます。通常、プログラムは小さな値を使用します。値126以上は、特別な条件を報告するためにシェルによって使用されるため、それらを回避するのが最善です。

C APIレベルでは、プログラム 16ビットのステータスを報告¹ は、プログラムの終了ステータスと、プログラムを強制終了したシグナル(存在する場合)の両方をエンコードします。

シェルでは、 コマンドの終了ステータス$?に保存)は、プログラムの実際の終了ステータスとシグナル値を統合します。プログラムがシグナルによって強制終了された場合、$?は128より大きい値に設定されます(ほとんどのシェルでは、この値は128にシグナル番号を加えたものです。ATTkshは256 +シグナル番号を使用し、yashは384 +シグナル番号を使用するため、あいまいさを回避できますが、他のシェルにはありません続きます)。

特に、$?が0の場合、プログラムは正常に終了しました。

これには、SIGTERMを受信するがそのためのシグナルハンドラーがあり、最終的には正常に終了する(おそらくSIGTERMシグナルの間接的な結果として)場合も含まれます。


タイトルの質問に答えるために、SIGTERMがシステムによって自動的に送信されることはありません。端末が消えたときにSIGHUPのように自動的に送信されるシグナルがいくつかあります。プロセスが実行すべきでないことを実行したときにSIGSEGV/SIGBUS/SIGILL、壊れたパイプ/ソケットに書き込んだときにSIGPIPEなどがあります。端末のキーを押したために送信されるいくつかの信号、主にSIGINT Ctrl+C、SIGQUIT Ctrl+\ およびSIGTSTP Ctrl+Z、しかしSIGTERMはそれらの1つではありません。プロセスがSIGTERMを受信すると、他のプロセスがそのシグナルを送信しました。

¹ 大ざっぱに言えば

SIGTERMは、管理上プロセスを終了するために通常使用されるシグナルです。

これは、カーネルが送信するシグナルではありませんが、プロセスが通常(正常に)別のプロセスを終了するために送信するシグナルです。

これは、killpkillkillall...コマンドによってデフォルトで送信される信号です。

それはデーモンに送信されるシグナルであり、デーモンを停止します(service some-service stop)、またはシャットダウン前にinitによって送信されます(SIGTERMで時間内に終了することができなかったプロセスのSIGKILLが続きます)。

SIGTERMはnotで送信されるシグナルであることに注意してください^C。送信された信号は^CはSIGINTです。

10