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

use*_*468 5 kernel memory-leaks lsof file-descriptor linux-kernel

我正在相对较大的代码库中工作,在该代码库中我看到文件描述符泄漏,并且进程开始抱怨在运行某些程序后它们无法打开文件。

尽管这是在6天后发生的,但我可以通过将/ proc / sys / fs / file-max中的值减小为9000来在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
Run Code Online (Sandbox Code Playgroud)

./monitor.fd.sh 500 2和tail -f pid_monitor.txt

正如我之前提到的,我没有在/ proc // fd中看到任何泄漏,但是可以肯定地发生了泄漏,并且系统用尽了文件描述符。

我怀疑内核中的某些内容正在泄漏。Linux内核版本2.6.23。

我的问题如下:

  1. 'ls / proc // fd'将显示任何使用pid链接到进程的库的列表描述符。如果没有,我该如何确定我链接到的库中何时有泄漏。

  2. 我如何确认泄漏在用户空间与内核中。

  3. 如果泄漏发生在内核中,我可以使用哪些工具进行调试?

  4. 您可以给我其他提示。

感谢您耐心地解决问题。

非常感谢您的帮助。

mpe*_*mpe 0

哪些进程开始抱怨?您看到的错误是什么?您的监控脚本的输出是什么?

要打开文件,您需要两个东西:文件描述符和struct file- 或文件描述。文件描述符是用户空间使用的,在内核内部它用于查找struct file. 我不清楚你在泄漏哪一个。