Skip to Content.
Sympa Menu

freetds - Re: [freetds] infinite loop in dbcancel

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Frediano Ziglio <freddy77 AT gmail.com>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] infinite loop in dbcancel
  • Date: Sun, 20 Mar 2016 11:22:46 +0000

Fixed (master and 0.95)!

Expect usually snapshots tomorrow.

Frediano


2016-03-17 21:28 GMT+00:00 Joshua Lang <joshua.h.lang AT gmail.com>:
> 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 <freddy77 AT gmail.com> wrote:
>
>> On 17 Mar 2016 21:21, "Joshua Lang" <joshua.h.lang AT gmail.com> 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 <freddy77 AT gmail.com>
>> > wrote:
>> >
>> > > 2016-03-16 19:23 GMT+00:00 Joshua Lang <joshua.h.lang AT gmail.com>:
>> > > > 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
>> > > FreeTDS AT lists.ibiblio.org
>> > > http://lists.ibiblio.org/mailman/listinfo/freetds
>> > >
>> > _______________________________________________
>> > FreeTDS mailing list
>> > FreeTDS AT lists.ibiblio.org
>> > http://lists.ibiblio.org/mailman/listinfo/freetds
>> _______________________________________________
>> FreeTDS mailing list
>> FreeTDS AT lists.ibiblio.org
>> http://lists.ibiblio.org/mailman/listinfo/freetds
>>
> _______________________________________________
> FreeTDS mailing list
> FreeTDS AT lists.ibiblio.org
> http://lists.ibiblio.org/mailman/listinfo/freetds




Archive powered by MHonArc 2.6.24.

Top of Page