web-dev-qa-db-ja.com

「kill -9」が機能しない場合はどうなりますか?

kill -9 <pid>で強制終了できないプロセスがあります。特に私がそのプロセスの所有者であるため、そのような場合の問題は何ですか。そのkillオプションを回避できるものはないと思いました。

491
tshepang

kill -9[〜#〜] sigkill [〜#〜] )は、プロセスを強制終了する権限がある場合は常に機能します。基本的に、プロセスはsetuidやsetgidではなく、ユーザーが開始するか、rootである必要があります。例外が1つあります。rootでもPID 1(initプロセス)に致命的な信号を送信できません。

しかしながら kill -9の動作は保証されていません即時。 SIGKILLを含むすべてのシグナルは非同期で配信されます。カーネルは、シグナルの配信に時間がかかる場合があります。通常、信号の配信には最大で数マイクロ秒かかり、ターゲットがタイムスライスを取得するのにかかる時間だけです。ただし、ターゲットに シグナルをブロック がある場合、シグナルはターゲットがブロックを解除するまでキューに入れられます。

通常、プロセスはSIGKILLをブロックできません。しかし、カーネルコードは可能であり、プロセスは システムコール を呼び出すときにカーネルコードを実行します。カーネルコードは、システムコールに割り込むと、カーネルのどこかに、またはより一般的には一部のカーネルの不変条件に違反する、不適切な形式のデータ構造が生じる場合に、すべての信号をブロックします。したがって、(バグや設計ミスにより)システムコールが無期限にブロックされた場合、事実上プロセスを強制終了する方法がない可能性があります。 (ただし、プロセスは、システムコールが完了すると強制終了されます。)

システムコールでブロックされたプロセスは 無停電スリープ です。 psまたはtopコマンドは、(ほとんどのユニスでは)状態Dで表示します(元は「disk」と思います)。

長い中断のないスリープの典型的なケースは、サーバーが応答していないときに [〜#〜] nfs [〜#〜] を介してファイルにアクセスするプロセスです。最新の実装では、中断のないスリープを強制する傾向はありません(たとえば、Linuxでは、intrマウントオプションにより、NFSファイルアクセスを中断する信号を許可します)。

ZまたはH出力にps(またはLinuxではtopとマークされたエントリ、区別がわからない)が表示される場合があります。これらは技術的にはプロセスではなく、ゾンビプロセスであり、プロセステーブルのエントリにすぎず、親プロセスに子の死を通知できるように保持されます。親プロセス 注意を払う (または死ぬ)になると、それらはなくなります。

いつかプロセスが存在し、次の理由で強制終了できません:

  • ゾンビであること。つまり親が終了ステータスを読み取らなかったプロセス。このようなプロセスは、PIDエントリ以外のリソースを消費しません。 topでは、信号Z
  • 中断のない誤った睡眠。それは起こるべきではありませんが、バグのあるカーネルコードおよび/またはバグのあるハードウェアの組み合わせにより、時々起こります。唯一の方法は、再起動または待機することです。 topでは、Dによって通知されます。
101

ゾンビプロセス があるようです。これは無害です。ゾンビプロセスが消費する唯一のリソースは、プロセステーブルのエントリです。親プロセスが死んだり、子供の死に反応したりすると、この問題は解消されます。

topまたは次のコマンドを使用して、プロセスがゾンビであるかどうかを確認できます。

ps aux | awk '$8=="Z" {print $2}'
32
Josh

手がかりがないか、/var/log/kern.logおよび/var/log/dmesg(または同等のもの)を確認してください。私の経験では、NFSマウントのネットワーク接続が突然切断された場合、またはデバイスドライバーがクラッシュした場合にのみ、これが発生しました。ハードドライブもクラッシュした場合に発生する可能性があると私は信じています。

lsofを使用すると、プロセスが開いているデバイスファイルを確認できます。

26
LawrenceC

@ Maciej 'sおよび@ Gilles ' sの回答で問題が解決せず、プロセスを認識できない場合(およびディストリビューションでそれが何であるかを尋ねる場合)答えを出さないでください)。ルートキットやその他の所有の兆候がないか確認します。ルートキットは、プロセスの強制終了を防ぐだけではありません。実際、多くの人はあなたがそれらを見ることを防ぐことができます。しかし、1つの小さなプログラムを変更するのを忘れた場合、それらは発見される可能性があります(例:topは変更したが、htopは変更しなかった)。ほとんどの場合、これは事実ではありませんが、申し訳ありませんが安全です。

17
xenoterracide

Killは実際にはシグナルを送信することを意味します。送信できる信号は複数あります。 kill -9は特別なシグナルです。

シグナルを送信するとき、アプリケーションはそれを扱います。そうでなければ、カーネルがそれを扱います。アプリケーションでシグナルをトラップできます。

しかし、私はキル-9は特別だと言った。アプリケーションがそれを取得しないという点で特別です。カーネルに直接移動し、可能な限り最初の機会にアプリケーションを本当に強制終了します。言い換えれば、それを殺します

kill -15は、SIGNAL TERMINATEを表すシグナルSIGTERMを送信します。つまり、アプリケーションに終了するように指示します。これは、シャットダウンするときがきたことをアプリケーションに知らせるためのわかりやすい方法です。ただし、アプリケーションが応答していない場合は、kill -9を実行すると、アプリケーションが強制終了されます。

kill -9が機能しない場合は、カーネルが正常に動作していない可能性があります。再起動が必要です。今までに起こったことを思い出すことはできません。

11
DeveloperChris

まず、そのゾンビプロセス(非常に可能性が高い)かどうかを確認します。

ps -Al

次のようなものが表示されます。

0 Z  1000 24589     1  0  80   0 -     0 exit   ?        00:00:00 soffice.bin <defunct>

(左側の「Z」に注意してください)

5番目の列が1でない場合は、親プロセスがあることを意味します。 その親プロセスIDを強制終了してみてください

そのPPID = 1、それを殺さないでください!!の場合、他のどのデバイスまたはプロセスがそれに関連している可能性があるかを考えてください。

たとえば、マウントされたデバイスまたはSambaを使用していた場合は、マウント解除してみてください。それはゾンビプロセスを解放するかもしれません。

[〜#〜]ノート[〜#〜]ps -Al(またはtop)は、「Z」ではなく「D」を示します。これは、リモートマウント(NFSなど)に関連している可能性があります。私の経験では、再起動がそこに行く唯一の方法ですが、そのケースをより詳しくカバーする他の回答をチェックすることができます。

11
lepe

InitプロセスはSIGKILLの影響を受けません。

これは、カーネルスレッド、つまりPPIDが0の「プロセス」にも当てはまります。

10
jlliagre

他の人が述べたように、無停電睡眠中のプロセスはすぐに(または場合によってはまったく)殺すことはできません。特定のシナリオ、特にプロセスがNFSで待機している一般的なケースでこの問題を解決するために、別のプロセス状態TASK_KILLABLEが追加されたことは注目に値します。参照 http://lwn.net/Articles/288056/

残念ながら、これはカーネルのどこかで使用されているとは思いませんが、NFSです。

10
user36054

私がたくさん見るのに役立つ小さなスクリプトを作りました!

これを使用して、パスに指定された名前のプロセスを強制終了できます(これに注意してください!!)または、「-u username」パラメーターを使用して、特定のユーザーのプロセスを強制終了できます。

#!/bin/bash

if [ "$1" == "-u" ] ; then\n
        PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
        processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
        echo "############# Killing all processes of user: $2 ############################"
else
        echo "############# Killing processes by name: $1 ############################"
        processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi


for process in $processes ; do
        # "command" stores the entire commandline of the process that will be killed
        #it may be useful to show it but in some cases it is counter-productive
        #command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
        echo "Killing process: $process"
        echo ""
        kill -9 $process
done
6
user36035

プロセスにkill -9を送信した場合でも、そのpidは停止しますが、プロセスは自動的に再起動します(たとえば、gnome-panel、それは再起動します):ここではそうでしょうか?

5
dag729

から ここでは元々

straceが何かを表示するかどうかを確認します

strace -p <PID>

gdbでプロセスにアタッチしてみてください

gdb <path to binary> <PID>

プロセスが、アンマウント、カーネルモジュールの削除、または物理的な切断/取り外しが可能なデバイスと対話していた場合は、それを試してください。

2
nmz787

このような問題がありました。これは私がstraceで起動し、Ctrl + Cで中断したプログラムでした。最終的にT(トレースまたは停止)状態になりました。どのようにして起こったのか正確にはわかりませんが、SIGKILLで強制終了することはできませんでした。

要するに、私はgdbでそれを殺すことに成功しました:

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit

ジルの答えからの手がかりに基づいて、システムリソースを使用している「Z」(psで「」)とマークされたプロセスがありました。それは、待機しているポートが開いていて、それに接続できました。これはkill -9上に。その親は "1"(つまりinit)だったので、理論的には消えるだけです。しかし、そうではありませんでした。実行されていませんでした。

だから私の場合、それはゾンビでしたが、それでもリソースを消費しています... FWIW。

そして、それはkill -9

そして、その親はinitでしたが、刈り取られていませんでした(片付け)。つまりinitにはゾンビの子供がいました。

また、問題を解決するために再起動する必要はありませんでした。問題を回避するには、再起動で「うまくいくはず」でしたが、シャットダウンが高速になりました。ただ優雅ではありませんが、それはまだ可能でした。

そして、それはゾンビプロセスが所有するLISTENポートでした(そして、ローカルホストにローカルホストに接続されたCLOSE_WAITステータスのような他のいくつかのポート)。そしてそれはまだ接続を受け入れました。ゾンビとしても。まだポートをクリーンアップするまでには至っていなかったので、受け入れられる可能性はありませんでしたが、着信接続はまだtcpリスニングポートのバックログに追加されていました。

内部に "システムコール"(この場合はioctl)を実行していて、戻るのに数時間かかっていた(これは予想された)内部スレッドがあったことがわかりました。どうやら、システムはそれから戻るまで「ずっと」それを殺すことができない。数時間後、それはクリアされ、ソケットはすべて自動的に閉じられました。悲惨な死の時間だ!

また、dmesgをチェックして、カーネルパニック(つまり、カーネルバグ)があったかどうかを確認します。

0
rogerdpack