2010-04-15 82 views
4

我運行下面的代碼時得到一個文件描述符泄漏:猛砸文件描述符泄漏

function get_fd_count() { 
     local fds 
     cd /proc/$$/fd; fds=(*) # avoid a StackOverflow source colorizer bug 
     echo "${#fds[@]}" 
} 

function fd_leak_func() { 
     while : ; do 
       echo ">> Current FDs: $(get_fd_count)" 
       read retval new_state < <(set +e; new_state=$(echo foo); retval=$?; printf "%d %s\n" $retval $new_state) 
     done 
} 

fd_leak_func 

測試兩個3.2.25和4.0.28。

這隻發生在函數內發生循環時;每次我們返回到頂級上下文時,額外的文件描述符都會關閉。

這是預期的行爲?更重要的是,是否有解決方法?


跟進:在報告給bash-bug郵件列表後,這被確認爲一個錯誤。切特表示,下一個版本將包含修復(截至2010年4月17日)。

+0

即使是更加怪異的,如果我在循環的末尾放置了一個'true',它會繼續上升,但是放置一個'/ bin/true'會保持它的水平爲5 – 2010-04-15 23:17:40

+0

報告它使用'bashbug'程序給新聞組,看看維護者Chet Ramey怎麼說的。 – 2010-04-16 00:40:05

+0

仍然在CentOS 6 bash 4.1.2(1) - 泄漏中泄漏。 – clacke 2013-03-04 08:52:59

回答

3

這裏有一個簡單的例子:

$ fd_leaker() { while :; do read a < <(pwd); c=(/proc/$$/fd/*); c=${#c[@]}; echo $c; done; } 
$ fd_leaker 

這個人是不是用/bin/true固定的,但它主要是通過使用(exit 0)固定的,但我得到「慶典:回聲:寫入錯誤:中斷系統調用」使用的錯誤,「修復「,或者如果我使用/bin/pwd而不是內置pwd

它似乎也是特定於read。我試過grep . < <(pwd) > /dev/null,它工作正常。當我試圖while read a; do :; done < <(pwd)

的形式額外的文件描述符:

lr-x------ 1 user user 64 2010-04-15 19:26 39 -> pipe:[8357879] 

我真的不認爲他們的失控創造意,畢竟沒有什麼遞歸的事情。我真的不知道如何在循環中添加一些東西來解決問題。

2

/bin/true放在循環的末尾修復它,但我不知道爲什麼或如何,或者爲什麼它首先發生。

+0

我在版本4.0.33(1) - 發佈,4.1.0(1) - 發佈和3.2.49(23) - 發佈中看到它。如果我在循環結尾放置一個'(exit 0)''no-op「子shell而不是'/ bin/true'(它也適用於我),它似乎也可以修復它。 – 2010-04-16 00:38:56

1

它似乎是固定在bash-4.2中。我用bash-4.2.28進行了測試,尤其是