Re: infinite loop in dbcancel

Joshua Lang <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
Excellent. Thanks for the quick turnaround!

> On Mar 20, 2016, at 4:22 AM, Frediano Ziglio <[email protected]> wrote:
> 
> Fixed (master and 0.95)!
> 
> Expect usually snapshots tomorrow.
> 
> Frediano
> 
> 
> 2016-03-17 21:28 GMT+00:00 Joshua Lang <[email protected]>:
>> Ugh. Well I don't have a Windows host setup currently for testing...
>> Also, it does seem strange that the code loops if the returned error is
>> EWOULDBLOCK or EAGAIN. That should never happen in a read after the select
>> (poll) has successfully returned the file descriptor is ready for reading.
>> 
>>> On Thu, Mar 17, 2016 at 2:24 PM, Frediano Ziglio <[email protected]> wrote:
>>> 
>>>> On 17 Mar 2016 21:21, "Joshua Lang" <[email protected]> wrote:
>>>> 
>>>> That seems reasonable. Would you like a pull request?
>>> 
>>> You can. However I think on Windows you have to call a function to set the
>>> error and I don't know which constant would be better. On Windows these
>>> kind of error (socket ones) have no relation with c errno
>>> 
>>> Frediano
>>> 
>>>> On Thu, Mar 17, 2016 at 12:55 PM, Frediano Ziglio <[email protected]>
>>>> wrote:
>>>> 
>>>>> 2016-03-16 19:23 GMT+00:00 Joshua Lang <[email protected]>:
>>>>>> FreeTDS version: 0.95.79
>>>>>> OS: Debian 7.9 (wheezy)
>>>>>> 
>>>>>> Here's the scenario:
>>>>>> 
>>>>>> Application has a long-running (pooled) connection to a database.
>>>>>> The database is restarted.
>>>>>> The application then consumes as much of one CPU as it can.
>>>>>> 
>>>>>> Unfortunately I have yet to find a simple repro for this issue
>>> locally,
>>>>> but
>>>>>> here is what I've found debugging the live application:
>>>>>> 
>>>>>> strace shows a constant stream of the following call:
>>>>>> 
>>>>>> poll([{fd=150, events=POLLOUT}, {fd=98, events=POLLIN}], 2, 1000) = 1
>>>>>> ([{fd=150, revents=POLLOUT|POLLERR|POLLHUP}])
>>>>>> 
>>>>>> The (relevant) stack trace from gdb:
>>>>>> 
>>>>>> (gdb) bt
>>>>>> #0  0x00007f1fae4d16b3 in *__GI___poll (fds=<optimized out>,
>>>>>> nfds=<optimized out>, timeout=1000)
>>>>>>    at ../sysdeps/unix/sysv/linux/poll.c:87
>>>>>> #1  0x00007f1fa50ff883 in tds_select () from
>>>>>> /opt/zillow/services/mortgage-api-external/zpr/lib/libsybdb.so.5
>>>>>> #2  0x00007f1fa50ffe70 in tds_goodwrite () from
>>>>>> /opt/zillow/services/mortgage-api-external/zpr/lib/libsybdb.so.5
>>>>>> #3  0x00007f1fa5100062 in tds_connection_write () from
>>>>>> /opt/zillow/services/mortgage-api-external/zpr/lib/libsybdb.so.5
>>>>>> #4  0x00007f1fa51046f7 in tds_put_cancel () from
>>>>>> /opt/zillow/services/mortgage-api-external/zpr/lib/libsybdb.so.5
>>>>>> #5  0x00007f1fa50f574b in tds_send_cancel () from
>>>>>> /opt/zillow/services/mortgage-api-external/zpr/lib/libsybdb.so.5
>>>>>> #6  0x00007f1fa50c3560 in dbcancel () from
>>>>>> /opt/zillow/services/mortgage-api-external/zpr/lib/libsybdb.so.5
>>>>>> 
>>>>>> 
>>>>>> I've stepped through this with gdb and here are the results:
>>>>>> 1. tds_select is called, returning -1 (verified in gdb)
>>>>>> 2. errno returns to 11 (EAGAIN) (verified in gdb, by stepping through
>>> the
>>>>>> c-lib function call to return it)
>>>>>> 3. TDSSOCK_WOULDBLOCK therefore causes the loop to repeat:
>>>>>> https://github.com/FreeTDS/freetds/blob/master/src/tds/net.c#L803
>>> and
>>>>> we're
>>>>>> back to step 1 and an infinite loop
>>>>>> 
>>>>>> The TDSSOCK_WOULDBLOCK seems strange to me, and the comment after it
>>>>>> agrees. I wouldn't expect the socket read to block if the poll call
>>> just
>>>>>> indicated it was ready for read.
>>>>> 
>>>>> 
>>>>> I think the problem is in tds_select. After poll returns 1 we check
>>>>> for error and return correctly -1 as failure however errno is not set
>>>>> so it's still the old value. I would try to set to something like
>>>>> EPIPE before returning -1.
>>>>> 
>>>>> Frediano
>>>>> _______________________________________________
>>>>> FreeTDS mailing list
>>>>> [email protected]
>>>>> http://lists.ibiblio.org/mailman/listinfo/freetds
>>>> _______________________________________________
>>>> FreeTDS mailing list
>>>> [email protected]
>>>> http://lists.ibiblio.org/mailman/listinfo/freetds
>>> _______________________________________________
>>> FreeTDS mailing list
>>> [email protected]
>>> http://lists.ibiblio.org/mailman/listinfo/freetds
>> _______________________________________________
>> FreeTDS mailing list
>> [email protected]
>> http://lists.ibiblio.org/mailman/listinfo/freetds
> _______________________________________________
> FreeTDS mailing list
> [email protected]
> http://lists.ibiblio.org/mailman/listinfo/freetds
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.