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

[Libevent-users] 1.4.13 (and lower): bug in configure: kqueue test-case w/ x86_64



Long time no see guys.

Anyways, I'm here to report what I believe to be a bug in the test- case for kqueue that I noticed under Darwin 10.5 (Leopard). I've noticed that if I simply used -O0 vs -O2 I could change the test case from successful to failure. This usually indicates undefined behavior occurring. After a couple of valgrind runs and experiments with memset clears, I believe we're passing trash data to kqueue on one of the fields it actually cares about:

The bottom section of the test-case pretty much looks like this:

        ev.ident = fd[1];
        ev.filter = EVFILT_WRITE;
        ev.flags = EV_ADD | EV_ENABLE;
        ev.data = 0;
        n = kevent(kq, &ev, 1, NULL, 0, NULL);
        if (n == -1)
                exit(1);

        read(fd[0], buf, sizeof(buf));

        ts.tv_sec = 0;
        ts.tv_nsec = 0;
        n = kevent(kq, NULL, 0, &ev, 1, &ts);
        if (n == -1 || n == 0) {
                exit(1);
        }

Observe the following (I've added a length grab to the read() call and a couple printfs for the last n == check):

$ gcc -arch x86_64 -O0 -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 1
0
$ gcc -arch x86_64 -O1 -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 1
0
$ gcc -arch x86_64 -O2 -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 0
1
$ gcc -arch x86_64 -Os -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 0
1

We can see that anything with low optimization is successful - however the actual code is fairly simply and pulling no tricks, so there must be a field in the ev struct which is getting picked up in the latter cases.

     struct kevent {
             uintptr_t ident;        /* identifier for this event */
             short     filter;       /* filter for event */
             u_short   flags;        /* action flags for kqueue */
             u_int     fflags;       /* filter flag value */
             intptr_t  data;         /* filter data value */
             void      *udata;       /* opaque user data identifier */
     };

Just by adding a simple "memset(&ev, 0, sizeof ev)" above the initial ev struct assignments we're doing in the test-case, I see the following results:

$ gcc -arch x86_64 -O0 -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 1
0
$ gcc -arch x86_64 -O1 -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 1
0
$ gcc -arch x86_64 -O2 -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 1
0
$ gcc -arch x86_64 -Os -o kqt /tmp/kqt.c; ./kqt; echo $?
l == 8000
n == 1
0

The reason I think this is kind of an annoying bug is that if compiling with x86_64 on Darwin 10.5, one ends up with poll() behavior as the test-case claims kqueue is broken (because of the above issue). As far as know kqueue() doesn't have any significant issues under 10.5 (unlike 10.4). It's fairly common to use x86_64 - especially when one may be linking against other x86_64 libraries/binaries.

I haven't verified differences under 10.6 yet.

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