Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash file descriptor leak

Tags:

bash

I get a file descriptor leak when running the following code:

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

Tested on both 3.2.25 and 4.0.28.

This only happens when the loop is happening within a function; every time we return to top-level context, the extra file descriptors are closed.

Is this intended behavior? More to the point, are workarounds available?


Followup: After reporting to the bash-bug mailing list, this was confirmed as a bug. Chet indicated that a fix will be included in the next release (as of 4/17/2010).

like image 280
Charles Duffy Avatar asked Apr 15 '10 21:04

Charles Duffy


3 Answers

Here's a simplified example:

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

This one is not fixed by using /bin/true but it's mostly fixed by using (exit 0) But I get "bash: echo: write error: Interrupted system call" errors using that "fix" or if I use /bin/pwd instead of the builtin pwd.

It also seems to be specific to read. I tried grep . < <(pwd) > /dev/null and it worked properly. When I tried while read a; do :; done < <( pwd)

The extra file descriptors in the form of:

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

I really don't think the runaway creation of them is intended, after all there's nothing recursive going on. I really don't see how adding something in the loop should fix things.

like image 129
Dennis Williamson Avatar answered Sep 30 '22 05:09

Dennis Williamson


Putting a /bin/true at the end of the loop fixes it, but I don't know why or how, or why it happens in the first place.

like image 24
Ignacio Vazquez-Abrams Avatar answered Sep 30 '22 06:09

Ignacio Vazquez-Abrams


It seems to be fixed in bash-4.2. I tested with bash-4.2.28 particularly

like image 27
Divya Avatar answered Sep 30 '22 06:09

Divya