2012-04-18 369 views
4

私はファイル記述子のリークが見られる比較的大きなコードベースで作業しており、プロセスは特定のプログラムを実行した後でファイルを開くことができないと不平を言っています。これは、6日後に起こるもののファイルディスクリプタのリークをデバッグする(カーネル内)

、私が実行している多くのプロセスがありますが9000

にを/ proc/sys/fs /ファイルの最大の値を減らすことにより、3-4時間で問題を再現することができていますいつでも。私は、リークの原因となっている可能性のあるプロセスのポイント・カップルをピン止めすることができました。しかし、lsofまたは/ proc/fdを通してファイル記述子のリークは見られません。

私が漏れの疑いがあるプロセス(彼らは互いに通信する)を殺すと、漏れはなくなります。 FDがリリースされます。

while(1)ループでcat/proc/sys/fs/file-nrがリークを示しています。しかし、どのプロセスでもリークは見られません。ここで

は私が起こっていることの漏れを検出するために書いたスクリプトです:

#!/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 & は、tail -f pid_monitor.txt

私は先に述べたように、私は/ proc/fdに漏れは見られませんが、漏れは確実に起きていて、システムはファイル記述子を使い果たしています。

カーネル内の何かが漏れていると思われます。 Linuxカーネルバージョン2.6.23。私の質問があり

は次のとおりです。

  1. ウィル 'lsのは/ proc // FDは、' showリスト記述子をPIDのプロセスにリンクされている任意のライブラリのために。どうすればライブラリに漏れがあるのか​​を判断する方法はありません。私はリンクしています。

  2. カーネルのリークがユーザー空間にあるかどうかを確認する方法を教えてください。

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

  4. その他のヒントを教えてください。

ご質問ありがとうございます。

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

+0

1.はい、それはリンクされたライブラリからのものも含め、すべての記述子を、表示されます。 2.カーネルでfdのリークが起こる可能性は非常に低いです。 3. 2を見てください。4.問題が何であるかはっきりしていません。詳細を教えてください。どのシステムコールが失敗し、どのようなエラーがありますか? – strkol

答えて

0

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

ファイルを開くには、ファイルディスクリプタとファイルディスクリプションの2つが必要です。ファイルディスクリプタはユーザ空間が使用するもので、カーネルの内部ではstruct fileを参照するために使用されます。あなたが漏れているのは私には分かりません。

0

問題の解決方法が見つかりました。

一部の機能で共有メモリ接続が発生し、その機能が30秒ごとに呼び出されていました。共有メモリのアタッチは決して切り離されていなかったため、ディスクリプタのリークが発生しました。私は/ proc/fdは共有メモリをディスクリプタとしてアタッチしていないと思います。したがって、私のスクリプトはどのプロセスが記述子を漏らしているかをキャッシュすることができませんでした。

関連する問題