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

Lukas Larsson lukas@REDACTED
Mon Jan 27 11:11:53 CET 2014


This issue has been identified and a fix will be in place for the next 
release. The bug only triggers if you have the socket in passive mode, 
so as a workaround for older releases you can set the socket in active 
mode before calling file:sendfile.

Lukas

On 17/01/14 14:24, Lukas Larsson wrote:
> Hello,
>
> 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!
>
> Lukas
>
> 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 <zambal@REDACTED> 
>> 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
>> erlang-bugs@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-bugs
>>
>
> _______________________________________________
> erlang-bugs mailing list
> erlang-bugs@REDACTED
> http://erlang.org/mailman/listinfo/erlang-bugs
>




More information about the erlang-bugs mailing list