[erlang-bugs] Possible bug in file:sendfile/5

Lukas Larsson <>
Fri Jan 17 14:24:52 CET 2014


Sorry for not replying before, I thought I had, but apparently not.

I will have a look at this before the next release and try to get a fix 
in. I think that I just have to mask the error from ebadf to closed in 
this scenario which should be simple enough.

Thanks for a great and very thorough bug report!


On 17/01/14 14:08, Vincent Siliakus wrote:
> I was wondering if anybody had the time to look in to this, as this
> seems to be a bug, or at least unexpected behaviour to me and I don't
> have enough knowledge of BEAM's internals to dive deeper in to this
> myself?
> This was my first post to the erlang-bugs mailing list, so if I missed
> some guidelines how to properly report an issue to this list, please
> let me know.
> -vincent
> On Thu, Dec 12, 2013 at 3:00 PM, Vincent Siliakus <> wrote:
>> Hi,
>> It seems that file:sendfile/5 in some situations corrupts or unexpectedly
>> closes the socket it uses. I stumbled up on this while using Elli, a small
>> but flexible http server (https://github.com/knutin/elli).
>> The issue manifests itself when some clients are making single requests (ie.
>> they close the socket after receiving a response) in a short timespan, where
>> the response is a file send back to the clients, using file:sendfile/5. Once
>> in a while, after an acceptor has responded and tries to reuse the
>> connection and calls gen_tcp:recv/3 again, instead of receiving {error,
>> closed}, it receives {error, ebadf}
>> I created a small example, that imitates Elli's tcp acceptor loop, without
>> all the http parsing stuff. When running this example I can reliably
>> reproduce this issue on two systems.
>> System one is a dual core Mac Book Pro, running Ubuntu 13.10 and Erlang
>> 16B03. System two is single core VMWare VM, running Ubuntu 12.04 LTS and
>> Erlang 15B03. I tried different async-thread settings on both systems (also
>> disabling async-threads altogether, by using +A 0), which doesn't seem to
>> make a difference.
>> I published the example as a gist at github, which can be found here:
>> https://gist.github.com/zambal/7927631
>> In my example, sendfile:server/0 creates a listener, with {active, false}
>> and spawns 10 processes as acceptors on that listening socket.
>> sendfile:clients/0 spawns 50 clients that are all performing a single
>> request, after which they close the connection.
>> If you run the example and no {error, ebadf} manifests itself, you can
>> uncomment the timer:sleep(100) call on line 34, as that seems to make it
>> more likely that the error will popup. Note also that you can replace the
>> sendfile call with an alternative implementation that uses file:read_file
>> and gen_tcp:send, by changing the sendfile(Socket, Path) call with
>> sendfile2(Socket, Path) on line 32. Using the alternative implementation, I
>> can not reproduce the issue and everything seems to work as expected.
>> -vincent
> _______________________________________________
> erlang-bugs mailing list
> http://erlang.org/mailman/listinfo/erlang-bugs

More information about the erlang-bugs mailing list