私はこの比較的大きなコード ベースで作業しており、ファイル記述子のリークが見られ、特定のプログラムを実行した後にプロセスがファイルを開くことができないと不平を言い始めます。
これは 6 日後に発生しますが、/proc/sys/fs/file-max の値を 9000 に減らすことで、3 ~ 4 時間で問題を再現できます。
常に多くのプロセスが実行されています。リークの原因となっている可能性のあるいくつかのプロセスを特定することができました。ただし、lsof または /proc//fd を介したファイル記述子のリークは見られません。
リークが疑われるプロセス (相互に通信する) を強制終了すると、リークはなくなります。FDがリリースされます。
cat /proc/sys/fs/file-nr in a while(1) ループはリークを示しています。ただし、どのプロセスでもリークは見られません。
リークが発生していることを検出するために私が書いたスクリプトを次に示します。
#!/bin/bash
if [ "$#" != "2" ];then
name=`basename $0`
echo "Usage : $name <threshold for number of pids> <check_interval>"
exit 1
fi
fd_threshold=$1
check_interval=$2
total_num_desc=0
touch pid_monitor.txt
nowdate=`date`
echo "=================================================================================================================================" >> pid_monitor.txt
echo "****************************************MONITORING STARTS AT $nowdate***************************************************" >> pid_monitor.txt
while [ 1 ]
do
for x in `ps -ef | awk '{ print $2 }'`
do
if [ "$x" != "PID" ];then
num_fd=`ls -l /proc/$x/fd 2>/dev/null | wc -l`
pname=`cat /proc/$x/cmdline 2> /dev/null`
total_num_desc=`expr $total_num_desc + $num_fd`
if [ $num_fd -gt $fd_threshold ]; then
echo "Proces name $pname($x) and number of open descriptor = $num_fd" >> pid_monitor.txt
fi
fi
done
total_nr_desc=`cat /proc/sys/fs/file-nr`
lsof_desc=`lsof | wc -l`
nowdate=`date`
echo "$nowdate : Total number of open file descriptor = $total_num_desc lsof desc: = $lsof_desc file-nr descriptor = $total_nr_desc" >> pid_monitor.txt
total_num_desc=0
sleep $2
done
./monitor.fd.sh 500 2 & テール -f pid_monitor.txt
前に述べたように、 /proc//fd でのリークは見られませんが、リークは確実に発生しており、システムのファイル記述子が不足しています。
カーネル内の何かがリークしていると思われます。Linux カーネル バージョン 2.6.23。
私の質問は次のとおりです。
「ls /proc//fd」は、 pid でプロセスにリンクされたライブラリのリスト記述子を表示します。そうでない場合、リンク先のライブラリにリークがあるかどうかを判断するにはどうすればよいですか。
リークがユーザー空間とカーネルにあることを確認するにはどうすればよいですか。
リークがカーネルにある場合、どのツールを使用してデバッグできますか?
あなたが私に与えることができる他のヒント。
辛抱強く質問に答えてくれてありがとう。
本当に助けていただければ幸いです。