freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: Frediano Ziglio <freddy77 AT gmail.com>
- To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
- Subject: Re: [freetds] infinite loop in dbcancel
- Date: Thu, 17 Mar 2016 19:55:10 +0000
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] infinite loop in dbcancel,
Joshua Lang, 03/16/2016
-
Re: [freetds] infinite loop in dbcancel,
Frediano Ziglio, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Joshua Lang, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Frediano Ziglio, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Joshua Lang, 03/17/2016
- Re: [freetds] infinite loop in dbcancel, Frediano Ziglio, 03/18/2016
-
Re: [freetds] infinite loop in dbcancel,
Frediano Ziglio, 03/20/2016
- Re: [freetds] infinite loop in dbcancel, Joshua Lang, 03/20/2016
- Re: [freetds] infinite loop in dbcancel, Sergio NNX, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Joshua Lang, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Frediano Ziglio, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Joshua Lang, 03/17/2016
-
Re: [freetds] infinite loop in dbcancel,
Frediano Ziglio, 03/17/2016
Archive powered by MHonArc 2.6.24.