调试文件描述符泄漏(在内核中?)

6
我在一个相对较大的代码库中工作,在运行某些程序后,我发现文件描述符泄漏和进程开始抱怨无法打开文件。
虽然这种情况发生在6天后,但我可以通过将/proc/sys/fs/file-max中的值减小到9000来在3-4小时内复现该问题。
任何时刻有许多进程正在运行。我已经能够确定可能导致泄漏的一些进程。但是,无论是通过lsof还是/proc//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'是否会显示与pid相关进程链接库的列表描述符。如果不是,我该如何确定我正在链接到的库是否存在泄漏。

  2. 如何确认泄漏是在用户空间还是在内核空间。

  3. 如果泄漏在内核中,我可以使用什么工具进行调试?

  4. 您能给我其他的建议吗?

感谢您耐心阅读问题。

真的非常感谢您的帮助。


  1. 是的,它将显示所有描述符,包括来自链接库的描述符。
  2. 内核中很少出现fd泄漏。
  3. 看第二个。
  4. 目前问题非常不清楚,请提供更多细节。哪个系统调用失败了?出现了什么错误?
- strkol
2个回答

1

找到了问题的解决方案。

在某个函数中发生了共享内存附加,而该函数每30秒被调用一次。共享内存附加从未被分离,因此导致描述符泄漏。我猜测/proc//fd不会将共享内存附加显示为描述符。因此,我的脚本无法捕获文件描述符泄漏。


0
哪些进程开始抱怨?你看到了什么错误?你的监控脚本输出是什么?
打开文件需要两个东西,一个是文件描述符,另一个是struct file或文件描述。文件描述符是用户空间使用的,在内核中用于查找struct file。我不清楚你泄漏了哪个。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接