[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] [nicholas.marriott@xxxxxxxxx: libevent and invalid fds]



On Wed, Feb 08, 2012 at 11:37:45AM -0500, Nick Mathewson wrote:
> On Tue, Feb 7, 2012 at 1:47 PM, Nicholas Marriott
> <nicholas.marriott@xxxxxxxxx> wrote:
> > Forwarding this message to ML at Nick's request...
> >
> > Hi
> >
> > You may remember a few months ago you fixed a problem with kqueue and
> > EPIPE on pipes - I backported this fix to 1.4 and recently applied it to
> > OpenBSD.
> >
> > However, this is causing problems with Google Chrome. From what we can
> > gather it appears the problem is with EBADF - when kqueue returns EBADF
> > for an fd, libevent fires the read callback, same as for EPIPE. This
> > makes Chrome segfault somewhere in a huge mess of C++ that I can't
> > figure my way through.
> 
> Hm.  So IIRC, we first added that EBADF in, it was (supposedly)
> because some kqueue implementations produced EBADF in response to one
> side of a pipe being closed while we were watching the other with
> kqueue.

I don't know - previously it would continue on EBADF (plus EINVAL and
ENOENT) but when that appeared, shrug...

EBADF is in r1.1 of the OpenBSD kqueue.c which means it was there when
libevent was first imported in June 2002:

                if (events[i].flags & EV_ERROR) {
                        /*
                         * Error messages that can happen, when a delete fails.
                         *   EBADF happens when the file discriptor has been
                         *   closed,
                         *   ENOENT when the file discriptor was closed and
                         *   then reopened.
                         * An error is also indicated when a callback deletes
                         * an event we are still processing.  In that case
                         * the data field is set to ENOENT.
                         */
                        if (events[i].data == EBADF ||
                            events[i].data == ENOENT)
                                continue;
                        return (-1);
                }

That is all about delete but no word on what happens with add which is
what we have now :-).

> Do we know what platform or platforms this might have been?  I'm not
> convinced atm that it's a real thing.  I've attached a small test
> program that tries closing the read and the write side of a pipe, both
> before and after the point where it is added to the kqueue. Can we
> find any platform where it says "bad file descriptor"?  If not, your
> fix would indeed seem to be the easy way around the present issue.

I get exactly the same output on OpenBSD and OS X which are the only
platforms I have with kqueue around right now:

$ ./kqtest
pipefd[0] = {4,5}
pipefd[1] = {6,7}
pipefd[2] = {8,9}
pipefd[3] = {10,11}
1 events:
  9: filter=fffffffe flags=4000 error=32 [Broken pipe]
3 events:
  4: filter=ffffffff flags=8001
  11: filter=fffffffe flags=8001
  6: filter=ffffffff flags=8001
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.