6

私はこの比較的大きなコード ベースで作業しており、ファイル記述子のリークが見られ、特定のプログラムを実行した後にプロセスがファイルを開くことができないと不平を言い始めます。

これは 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。

私の質問は次のとおりです。

  1. 「ls /proc//fd」は、 pid でプロセスにリンクされたライブラリのリスト記述子を表示します。そうでない場合、リンク先のライブラリにリークがあるかどうかを判断するにはどうすればよいですか。

  2. リークがユーザー空間とカーネルにあることを確認するにはどうすればよいですか。

  3. リークがカーネルにある場合、どのツールを使用してデバッグできますか?

  4. あなたが私に与えることができる他のヒント。

辛抱強く質問に答えてくれてありがとう。

本当に助けていただければ幸いです。

4

2 に答える 2

1

問題の解決策を見つけました。

一部の関数で共有メモリ接続が発生し、その関数は30秒ごとに呼び出されていました。共有メモリ接続が切り離されることはなかったため、記述子がリークしました。/ proc//fdは共有メモリ接続を記述子として表示しないと思います。したがって、私のスクリプトはファイル記述子のリークをキャッチできませんでした。

于 2012-04-25T22:40:03.310 に答える
0

どのプロセスが不平を言い始めますか? そして、あなたが見るエラーは何ですか?監視スクリプトの出力は何ですか?

ファイルを開くには、ファイル記述子とstruct file- またはファイルの説明の 2 つが必要です。ファイル記述子は、ユーザー空間が使用するものであり、カーネル内でstruct file. あなたがどれを漏らしているのかは私には明らかではありません。

于 2012-04-22T10:49:09.933 に答える