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