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

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

Forwarding this message to ML at Nick's request...


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

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.

It doesn't do it with EVENT_NOKQUEUE though, so I was looking at how
poll and kqueue both handle EBADF and it appears there are differences:

I'm testing using libevent 2.0.16 here on OS X but the results are the
same with 1.4 on OpenBSD. Using this test program:

#include <err.h>
#include <event.h>
#include <fcntl.h>
#include <unistd.h>

cb(int fd, short events, void *closure)
	printf("XXX %d\n", events);

	int p[2];
	struct event ev;

	if (pipe(p) != 0)
		err(1, "pipe");

	if (event_init() == NULL)
		err(1, "event_init");

	event_set(&ev, p[0], EV_READ|EV_WRITE, cb, NULL);
	if (event_add(&ev, NULL) != 0)
		err(1, "event_add");


	for (;;) {
		if (event_dispatch() < 0)
			err(1, "event_dispatch");

I get these results:

$ ./evtestx
$ EVENT_NOKQUEUE=1 ./evtestx
[warn] select: Bad file descriptor
evtestx: event_dispatch: Bad file descriptor

Instrumenting kqueue.c shows this is the EBADF case in event[i].data.

So, the questions is... what should libevent be doing if you add an
invalid file descriptor? According to the poll backend (and Google,
apparently), it should be doing nothing.

So what about the diff below? I don't remember anything about EBADF
before (just EPIPE), so I don't know if there are any implications.


--- kqueue.c.orig       2012-02-07 15:55:17.000000000 +0000
+++ kqueue.c    2012-02-07 15:55:40.000000000 +0000
@@ -339,6 +339,8 @@
                         * occur on an add if the fd was one side of a pipe,
                         * and the other side was closed. */
                        case EBADF:
+                               continue;
                        /* These two can occur on an add if the fd was one side
                         * of a pipe, and the other side was closed. */
                        case EPERM:

To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.