\r\n\r\n

linuxでゾンビプロセスを殺す方法

プログラムの書き方や実行方法が悪いと、リナックスコンピュータにゾンビプロセスが潜んでいることがあります。ゾンビはどのように作られ、最終的にどのように鎮めることができるのか...を学びます。

プログラムの書き方や実行方法が悪いと、Linuxコンピュータにゾンビプロセスが潜んでいることがあります。ゾンビはどのように作られ、最終的にどのように鎮めることができるのかを学びます。

Linuxにおけるプロセス状態の仕組み

Linuxはもちろん、コンピュータ上で動作しているすべてのアプリケーションやデーモンを把握しておかなければならない。その一つの方法として、プロセステーブルを整備する。カーネルメモリ内の構造体の一覧です。各プロセスは、このリストにエントリーを持ち、そのプロセスに関するいくつかの情報を含んでいます。

各プロセステーブルの構成は、あまり内容がありません。プロセスID、その他のデータ項目、そのプロセスのプロセスコントロールブロック(PCB)へのポインタが含まれます。

PCBは、Linuxが各プロセスを検索したり設定する必要がある多くの詳細を保持します。PCBはまた、プロセスが作成され、処理時間が与えられ、最終的に破棄されるときに更新されます。

Linux PCBには95以上のフィールドがあります。PCB は、task_struct.h という構造体で定義され、700 行以上の長さがあります。

  • プロセスステータス:ステータスは以下の通りです。
  • プロセス番号:オペレーティングシステムにおける一意の識別子。
  • プログラムカウンタ:このプロセスが次にCPUにアクセスするとき、システムはこのアドレスを使って、次に実行されるべきプロセスの命令を探す。
  • Registers: このプロセスが使用するCPUレジスタのリストで、アキュムレータ、インデックスレジスタ、スタックポインタを含むことができる。
  • オープンファイル一覧:このプロセスに関連するファイル。
  • CPUスケジューリング情報:プロセスに割り当てられたCPU処理時間の頻度と期間を決定するために使用される。プロセスの優先度、スケジューリングキューへのポインタ、その他のスケジューリングパラメータをPCBに記録する必要があります。
  • メモリ管理情報:プロセスメモリの開始アドレス、終了アドレス、メモリページへのポインタなど、このプロセスが使用しているメモリに関する詳細な情報。
  • I/Oステータス情報:プロセスで使用されるあらゆる入出力デバイス。

プロセス状態」は、以下のいずれでもよい。

  • R:実行中または実行可能なプロセス。実行中とは、CPUサイクルを受け取り、実行することを意味します。実行可能なプロセスとは、実行可能な状態で、CPUスロットを待っている状態です。
  • 学生:入出力操作などの操作の完了や、資源が利用可能になるのを待っているスリープ状態。
  • D:プロセスは中断されないスリープ状態です。ブロッキングシステムコールを使用しているため、システムコールが完了するまで続行できません。スリープ状態とは異なり、この状態にあるプロセスは、システムコールが完了し、プロセスに実行が戻るまで、シグナルに応答しない。
  • T:SIGSTOPシグナルを受信したため、プロセスが終了(停止)しました。SIGKILL、SIGCONTシグナル(それぞれプロセスの終了、継続を指示)に対してのみ応答します。フォアグラウンド(fg)タスクからバックグラウンド(bg)タスクに切り替えると、このような現象が起こります。
  • Z:Zombieのプロセス。プロセスが完了しても、消えることはありません。使用しているすべてのメモリを解放し、メモリから自身を削除しますが、プロセステーブルとPCBへのエントリは残ります。ステータスはEXITu ZOMBIEに設定され、親プロセスは子プロセスが終了したことを(SIGCHLDシグナルで)通知されます。

Zombie状態で子プロセスが生成されると、親プロセスはwait()関数群のいずれかを呼び出します。そして、子プロセスの状態変化を待ちます。子プロセスは、停止、継続、終了のいずれかのシグナルを受けたか?実行中のコードの自然な終了で終了するか?

状態の変化が子プロセスの実行停止を意味する場合、その終了コードが読み込まれる。その後、子 PCB は破棄され、プロセステーブルのエントリが削除されます。理想的なのは、このすべてが瞬時に行われ、ゾンビ状態のプロセスは長くは存在しないことです。

関連:Linuxでバックグラウンドプロセスを実行・制御する方法

linuxでゾンビプロセスが発生する原因は何ですか?

親プロセスの書き方が悪いと、子プロセスを生成するときに wait() 関数を呼び出さないことがあります。これは、子プロセスの状態変化を何も監視していないことを意味し、SIGCHLDシグナルは無視されることになる。あるいは、別のアプリケーションが親プロセスの実行に影響を与えている。これは、プログラミングの不備や悪意が原因である可能性がある。

しかし、親プロセスが子プロセスの状態変化を監視しなければ、適切なシステムハウスキーピングは行われない。子プロセスが終了しても、PCBやプロセステーブルのエントリを削除しない。これにより、ゾンビの状態がPCBから削除されることはありません。

ボットはある程度のメモリを必要としますが、通常は問題を起こしません。プロセステーブルのエントリは小さいが、プロセスIDは解放されるまで再利用できない。64ビットOSでは、PCBはプロセステーブルのエントリよりはるかに大きいので、これは何の問題も発生しないと思われます。

ご想像の通り、大量のゾンビが発生すると、他のプロセスが利用できるメモリ量に影響を与えます。しかし、それだけのゾンビがいるのであれば、親アプリケーションやオペレーティングシステムに重大な問題があることになります。

ゾンビプロセスの削除方法

ゾンビプロセスはすでに死んでいるので、殺すことはできない。メモリから削除され、SIGKILL信号を送信する場所がないため、いかなる信号にも応答しません。親プロセスにSIGCHLDシグナルを送ってみることもできますが、子プロセスが終了したときにうまくいかなかったのであれば、現在もうまくいくとは思えません。

唯一の確実な解決策は、親プロセスを終了させることです。終了すると、その子プロセスは、Linuxシステム上で最初に動作するプロセスであるinitプロセス(プロセスIDは1)に継承されます。

initプロセスは定期的に必要なボットのクリーンアップを行うので、ボットを殺すには、ボットを作ったプロセスを殺すだけでよい。 topコマンドは、ボットがあるかどうかを確認する便利な方法である。

と入力する。

top

このシステムには8つのゾンビプロセスがあります。psコマンドを使用し、egrepにパイプすることでこれらを一覧することができます。この場合も、ゾンビプロセスのステータスフラグは "Z" で、通常は "defunct" も表示されます。

と入力する。

ps aux | egrep "Z|defunct"

ゾンビプロセスが掲載されます。

ボットプロセスIDを見つけるには、上部を何度もスクロールするよりもずっとすっきりした方法です。また、これらのボットを生成する「badprg」というアプリケーションも確認されました。

最初のゾンビのプロセスIDは7641ですが、その親のプロセスIDを見つける必要があります。再びpsを使用します。出力オプション(-o)を使用して、親のプロセスIDのみを表示するようにpsに指示し、それをppid=flagで渡します。

探しているプロセスは、-p(プロセス)オプションを使用して、ゾンビのプロセスIDを渡すことで表示されます。

そこで、プロセス7641のプロセス情報を検索するために以下のコマンドを入力しますが、親プロセスのIDしか報告されません。

ps -o ppid= -p 7641

親プロセスIDが7636であることがわかります。これで再びpsを使って相互参照することができます。

直前の親プロセスの名前と一致していることがわかる。親プロセスを終了させるには、以下のようにSIGKILLオプションとkillコマンドを併用します。

kill -SIGKILL 7636

親プロセスのオーナーによっては、sudoを使用する必要がある場合もあります。

ゾンビは怖くない...。

...巨大な大群でない限り。恐れるに足らず、単純な再起動で一掃されるものもいくつかある。

しかし、あるアプリケーションやプロセスが常にボットを生成していることに気づいたら、これを調べる必要があります。おそらく急ごしらえのプログラムであり、その場合、子プロセスの後に適切にクリーンアップできるアップデート版が存在する可能性があります。

あなたが興味を持っているかもしれない記事

匿名者
匿名者

0 件の投稿

作家リスト

  1. admin 0 投稿
  2. 匿名者 0 投稿

おすすめ