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


467

私は殺すことができないプロセスを持っていますkill -9 <pid>。特にこのプロセスの所有者であるため、このような場合の問題は何ですか。私はそのkill選択肢を逃れることはできないと思いました。

回答:


561

kill -9SIGKILL)プロセスを強制終了する許可があれば、常に機能します。基本的に、プロセスはsetuidまたはsetgidではなく、ユーザーが開始するか、rootでなければなりません。例外が1つあります。ルートでさえ、致命的なシグナルをPID 1(initプロセス)に送信できません。

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

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

システムコールでブロックされたプロセスは、割り込み不可能なスリープ状態です。psまたはtopコマンドが(ほとんどのUnix上の)状態でそれを表示しますD(本来は「用のD ISK」、私は思います)。

長く中断できないスリープの古典的なケースは、サーバーが応答しないときにNFS経由でファイルにアクセスするプロセスです。最近の実装ではintr、割り込み不能なスリープを強制しない傾向があります(たとえば、Linuxでは、マウントオプションにより、NFSファイルアクセスを中断する信号が許可されます)。

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


92
返信は自己矛盾に見えます。SIGKILLが常に動作することを伝え始めますが、SIGKILLがカーネルのシャットダウン以外では動作しない可能性がある無停電スリープケースを引用して終わります。SIGKILLが機能しない場合も2つあります。ゾンビでは、すでに死んだプロセスを殺すことはできないので、初期設定では明らかにSIGKILLシグナルを無視します。
jlliagre

41
@jlliagre:ゾンビを殺しても意味がありません。そもそも生きているわけではありません。また、割り込み可能なスリープでプロセスを強制終了しても機能しますが、それは(他の信号と同様に)非同期です。私は編集でこれを明確にしようとしました。
ジル

3
私も、ゾンビを殺すのは理にかなっていないと書いたが、それは多くの人々がそれを試して文句を言うことを妨げない。割り込み可能なスリープでプロセスを強制終了することは、実際には設計どおりに機能しますが、システムコールが起動しない場合に失敗する可能性がある、割り込み不可能なスリープでプロセスを強制終了することについて話していました。
jlliagre

11
man 5 nfs:「 カーネル2.6.25以降、intr/ nointrmountオプションは非推奨です。これらのカーネルで保留中のNFS操作を中断できるのはSIGKILLのみです。指定されている場合、このマウントオプションは無視され、古いカーネルとの後方互換性を提供します。」
マーティンシュレーダー

4
@ imz--IvanZakharyaschev私が知っていることではありません(しかし、知らないかもしれません)。sshfsを使用すると、最後の手段として、sshfsプロセスを強制終了できます(他のFUSEファイルシステムでも同様です。この方法でいつでも強制的にアンマウントできます)。
ジル

100

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

  • ゾンビであること。つまり、親が終了ステータスを読み取らなかったプロセス。このようなプロセスは、PIDエントリ以外のリソースを消費しません。その中topでZ
  • 誤った割り込み不可能なスリープ。それは起こるべきではありませんが、バグのあるカーネルコードやバグのあるハードウェアの組み合わせでいつか発生します。唯一の方法は、再起動または待機することです。その中topにDによってシグナルが送られます。

2
ゾンビはリソースを消費しませんか?
リュックM

7
@Luc M:AFAIK no(少なくともLinuxの場合)-プロセステーブルのエントリ(つまり、PIDと所有者、終了ステータスなどの情報)を除きます。終了したという部分からの確認を待つのは、まさにプロセスです。
マチェイピエチョトカ

18
@xenoterracide:最終的にははいですが、親プロセスがまだ存在している場合(たとえば、gnome-sessionまたは同様の役割を果たしているもの)、ゾンビがいる可能性があります。技術的には、クリーンアップするのは親の仕事ですが、ゾンビが孤立したinitでクリーンアップされた場合(用語はUnixクラスが閉じられたドアで行われる理由です-孤児、ゾンビ、殺人について1つの文で聞いた人は間違った印象を持っているかもしれません)。
マチェイピエチョトカ

5
「...再起動または待機する方法のみです。」5か月が経ち、私のゾンビはまだそこにいます。
DarenW

3
親が子供の死を認めるまで@DarenW。詳細については、プログラムの作成者にお問い合わせください。
マチェイピエチョトカ

32

ゾンビプロセスがあるようです。これは無害です。ゾンビプロセスが消費する唯一のリソースは、プロセステーブルのエントリです。親プロセスが死ぬか、その子の死に反応すると、それは消えます。

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

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

13
うーん、私はいつもこの種の「ハード」フィールド名が嫌いpsです。必須フィールドが常に 8番目でありps、すべてのUnicesのすべての実装であると確信できるのは誰ですか?
構文エラー

26

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

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


6
NFSについて言及する場合は+1。数年前、これは2か月ごとに起こりました。NFSサーバーがクラッシュすると、すべての(パッチを当てた)RHELボックスのNFSクライアントがハングします。kill -9通常、60分待っても機能しませんでした。唯一の解決策は再起動することでした。
ステファンLasiewski

17

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


多くのルートキットがカーネルに自分自身を挿入して物事を単純化すると思います(ユーザーが何を持っているかを推測したり、パッチを当てたプログラムのMBをダウンロードしたりする必要はありません)。ただし、確認する価値はまだあります(++ vote)。
マチェイピエチョトカ

11

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

信号を送信するとき、アプリケーションはそれを処理します。そうでない場合、カーネルはそれを扱います。そのため、アプリケーションで信号をトラップできます。

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

kill -15は、シグナル終了を表すシグナルSIGTERMを送信します。言い換えると、アプリケーションに終了を指示します。これは、シャットダウンする時間であることをアプリケーションに伝える簡単な方法です。ただし、アプリケーションが応答しない場合、kill -9がそれを殺します。

kill -9が機能しない場合は、おそらくカーネルが正常に動作していないことを意味します。再起動が必要です。今まで起こったことを思い出せません。


5
15はSIGTERM(フレンドリーキル)であり、SIGHUPではありません。SIGHUPは、制御端子が閉じている、または通信チャネルが失われるためである
JoelFan

11

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

ps -Al

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

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

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

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

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

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

:(ps -Alまたはtop)に「Z」ではなく「D」が表示される場合は、リモートマウント(NFSなど)に関連している可能性があります。私の経験では、再起動がそこに行く唯一の方法ですが、そのケースをより詳細にカバーする他の答えを確認することができます。


1
SIGCHLDを親プロセスに送信すると、親はプロセスが停止したことを認識する場合があります。これは、PPID = 1の場合でも機能するはずです。これは通常カーネルによって送信されますが、killを介して親にも送信できます(Linuxではkill -17、他の* nixのマンページを確認)。このkillの使用法は、実際には親を「殺す」のではなく、子が死んでクリーンアップする必要があることを(再)通知します。sigchldは、ゾンビ自体ではなく、ゾンビの親に送信する必要があることに注意してください。
ステファニー14年

10

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

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


1
カーネルタスクはSIGKILLの影響も受けません。これは、Btrfsで十分に頻繁に発生します。
東武

9

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

残念ながら、これはカーネル以外ではNFS以外では使用されていないと思います。


リモートサーバーにアクセスできない場合、マウントにlsアクセスするプロセスsshfsを強制終了できませんでした。FUSEまたはsshfsの解決策はありますか?将来的にそのような状況を回避するために使用できますか?2.6.30カーネル
imz-Ivan Zakharyaschev

@imz Gillesからのアドバイス(sshfsを殺すため)があります-unix.stackexchange.com/a/5648/4319
imz-イワンザカリヤシェフ

6

私がたくさん見てくれた小さなスクリプトを作成しました!

これを使用して、パスに指定された名前のプロセスを強制終了できます(これに注意してください!!)。または、「-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

4
リンクするだけでなく、代わりにここにコードを投稿できます。
シェパン

3
コードに(または少なくとも代わりに)コードの説明を少し追加します。
vonbrand

うん、しかし、「$ name」はより集約的です...実行中のパスに「$ name」を持つプロセスを強制終了します。これらの巨大なコマンドラインがあり、プロセス名が何なのかわからない場合に非常に便利です。
user36035

5

kill -9をプロセスに送信しても、そのpidは停止しますが、プロセスは自動的に再起動します(たとえば、で試してみるgnome-panelと再起動します)。


8
このようなことが起こると、PIDは実際に変わります。だから気づいたでしょう。
シェパン

2

元々ここから:

straceが何かを示しているかどうかを確認してください

strace -p <PID>

gdbでプロセスに接続してみてください

gdb <path to binary> <PID>

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


私のために働いた!(崇高なテキストをぶら下げていたUSBデバイスの
プラグを抜く

1

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

簡単に言えば、私はそれを殺すことに成功しましたgdb

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

-1

gillesの答えからの手がかりに基づいて、<defunct>システムリソースを使用している(ps単位で)「Z」とマークされたプロセスがあり、リッスンしているポートが開いていて、そのポートに接続できました。これは、それを実行した後でしたkill -9。その親は "1"(つまりinit)だったので、理論的には繰り返して消える必要があります。しかし、そうではありませんでした。走ってはいませんでしたが、「死にかけていません」

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

そして、それは、任意の数のことでkillableではなかったkill -9

そして、その親はinitそうでしたが、刈り取られていませんでした(クリーンアップ)。すなわちinit、ゾンビの子供がいました。

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

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

上記の多くは、インターウェブのさまざまな場所で「不可能」と言われています。

返されるまでに数時間かかっていた「システムコール」(この例ではioctl)を実行している内部スレッドがあったことが判明しました(これは予期された動作でした)。どうやら、システムは、ioctl呼び出しから戻るまでプロセスを「ずっと」強制終了することはできません。数時間後に戻ってきて、物事は片付けられ、ソケットはすべて自動的に閉じられました。それは死刑囚の苦しい時間です!カーネルはそれを殺すのを辛抱強く待っていました。

だから、OPに答えるために、時にはあなたは待たなければならない。長い間。その後、殺害は最終的にかかります。

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


これは、質問に対する答えではなく、あなた自身の特定のシナリオを説明しているようです。あなたの場合、長時間実行される操作のために、プロセスはそれ自体で修正されました。これは質問に記載されていません。ただし、新しい質問を提起し、それに対する回答も提供してください。結果は実装に固有であるため、質問は「再現性がない」として閉じられる可能性があると思いますが。
Centimane

確かに、私はそれがOPにどのように答えるかを追加しました。
ロジャードパック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.