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


24

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


カーネルまたは標準ツールがランダムなプロセスにSIGTERMを送信するケースは考えられません。プログラムの実行内容と開始方法について教えてください。プログラムの終了ステータスをどうやって知りましたか?問題を再現できますか?確認できるログはありますか?
ジル 'SO-悪である停止

シリアル回線の読み取りと書き込みを行っており、UDPおよびTCP要求に応答しています。実行をbashスクリプトでラップしたので、終了コードを知っています。
michelemarcon

1
Posixのドキュメントでは、SIGTERMは厳密にユーザーレベルのイベントであることが示されています。他の誰かがあなたのサーバープログラムを殺すことができた可能性はありますか?
シェルター

3
あなたは!戻りコード0は、正常終了を意味します。SIGTERMがあった場合、$?143(128 +シグナル番号)に設定されます。
ジル 'SO-悪であるのをやめる'

1
また、^ CはSIGINT、SIGTERMないであり、それは130のコードで出る
flarn2006

回答:


13

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

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

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

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

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

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


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

¹ 大まかに言えば


シグナルを受信したときに終了ステータスがどのように決定されるかについてのわかりやすい説明。ただし、この回答はOPの質問には対応していません。
コードフォレスター

1
@codeforesterタイトルの質問ではなく、本文の質問に答えました。さて、本文の質問の1つ-誤解に基づいていることを考えると、少し厄介です。残りの部分について少し説明します。
ジル 'SO-悪であるのをやめる'

それはシェルに依存します。ksh93では256 + signum、yashでは384 + signum
ステファンシャゼラス

256を超える値を使用すると、kshが渡されるのを防ぐため、必ずしも良いとは限りませんexit。このyashアプローチは適切な妥協案ですが、別のアプローチについてはrcを参照してください。プロセス終了時のデフォルトの終了コード
ステファンシャゼラス

10

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

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

それはによってデフォルトで送信された信号だkillpkillkillallfuser -k...コマンド。

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.