Bug 478305 - libevent borked, upstream's event-test.c doesn't run correctly
libevent borked, upstream's event-test.c doesn't run correctly
Product: Fedora
Classification: Fedora
Component: libevent (Show other bugs)
x86_64 Linux
low Severity high
: ---
: ---
Assigned To: Steve Dickson
Fedora Extras Quality Assurance
Depends On:
  Show dependency treegraph
Reported: 2008-12-27 13:08 EST by Evan Klitzke
Modified: 2008-12-31 13:53 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2008-12-31 13:53:22 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
shows what event_set is doing (589 bytes, text/plain)
2008-12-29 03:41 EST, Evan Klitzke
no flags Details

  None (edit)
Description Evan Klitzke 2008-12-27 13:08:11 EST
So the background behind this, first. I was trying to build my own memcached (which links against libevent), and I couldn't get it working. Curiously, the memcached packaged for Fedora works (i.e. the packaged memcached works, but when I try to compile it myself it doesn't work).

The symptom that I see is that if I start up the memcached I compile (from latest upstream stable release), when I connect to memcached, memcached never gets the connection event. So if I tcpdump a session, there's a successful TCP handshake between the client and the memcached server. But strace'ing the memcached process shows that it's just looping on epoll_wait and never actually received a connection event (also doesn't receive data I send it). Again, the memcached packaged for Fedora works and I don't really know why.

So after much poking around I thought maybe libevent is broken. It turns out that there is a test program on the libevent website, at http://monkey.org/~provos/libevent/event-test.c . What this program is supposed to do is create a file called event.fifo and then print out "Write data to event.fifo". It then blocks, and if you write data to the fifo the event-test program prints out some message like:

fifo_read called with fd: 3, event: 2, arg: 0xbf813f08
Read: 1

I was able to confirm this behavior on two other machines I have (also the source is really small, it's pretty apparent that that's the intended behavior). However, if I compile this on my FC10 computer, the test program doesn't work at all. Instead it just prints out "Write data to event.fifo" and then immediately exits.

Here's the version of everything I'm running:

uname -a:
Linux gemini #1 SMP Tue Dec 16 14:47:52 EST 2008 x86_64 x86_64 x86_64 GNU/Linux

libevent is version 1.4.5 release 1.fc10 (x86_64 arch).

The test libevent program was compiled as:
gcc -o event-test event-test.c -levent

evan@gemini:~$ ldd event-test 
	linux-vdso.so.1 =>  (0x00007fff5f1ff000)
	libevent-1.4.so.2 => /usr/lib64/libevent-1.4.so.2 (0x0000003486600000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003479000000)
	libnsl.so.1 => /lib64/libnsl.so.1 (0x0000003482200000)
	librt.so.1 => /lib64/librt.so.1 (0x000000347ac00000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003483a00000)
	/lib64/ld-linux-x86-64.so.2 (0x0000003478c00000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003479c00000)
Comment 1 Evan Klitzke 2008-12-27 21:20:09 EST
FWIW, I downloaded and compiled the 1.4.9 tarball (the latest stable release). When linking against that, event-test exhibits the correct behavior.
Comment 2 Evan Klitzke 2008-12-28 15:51:53 EST
Now I'm not so sure the problem is with libevent. When I built the new libevent yesterday things were working for a while, and now they're not again. The event-test.c program exhibits the same incorrect behavior as when linked to FC10's libevent as it does when linked against the 1.4.9 libevent that I built myself (i.e. it exits immediately).

I'm going to poke around with libevent and see if I can come up with a better test case exhibiting the problem, but I don't have a lot of ideas...
Comment 3 Evan Klitzke 2008-12-29 03:41:52 EST
Created attachment 327916 [details]
shows what event_set is doing

OK, so I looked at this as much as I know how to, and here's what I've been able to find.

When I strace the programs I built with libevent (memcached and the event-test.c file) I found that after calling libevent's event_add, there was no call to epoll_ctl. This is consistent with the brokenness I see in memcached. I'm not able to connect to memcached because it's looping with epoll_wait on an epoll fd that isn't monitoring anything with it. I think it's also consistent with event-test.c exiting instead of blocking, because I guess that the epoll_add isn't really adding the fd to be monitored, so the libevent event loop has nothing to do. This makes event_dispatch return immediately.

So event_add isn't really adding the fd to be monitored. The question is, why is that? I think maybe I'm crazy or something but it looks like after returning from event_set the event struct that is passed in isn't initialized correctly? I'm kind of confused about this myself. If you run the attached C file (i.e. gcc -g -o evtest -levent evtest.c) I would expect it to print ev->ev_flags = 0x80 and ev->ev_events = 0x1 at the end, but it doesn't. This is curious to me because if I am understanding everything correctly, it looks like ev->ev_events and ev->ev_flags are correct inside of the event_set program when I run everything through gdb. IOW I might be misunderstanding things, but to me it looks like inside of event_set the struct members are correct, and then when it returns they got corrupted somehow.

Also, if you make ev not a local non-pointer allocated on the stack, and instead pass &ev to event_set you get a different result. But I'm not really a C programmer, I could be totally confused about the event_set part of the problem.

Here's what I'm seeing:

evtest.c, attached version:
EV_READ = 0x1
EV_RITE = 0x2
EV_SIGNAL = 0x400
ev->ev_flags = 0x0
ev->ev_events = 0x0

evtest.c, struct event ev declared local/on the stack:
EV_READ = 0x1
EV_RITE = 0x2
EV_SIGNAL = 0x400
ev->ev_flags = 0x7fff
ev->ev_events = 0x0

I think at this point it would be helpful if someone with better C knowledge took a look at this.
Comment 4 Evan Klitzke 2008-12-31 13:53:22 EST
err I think this one was just PEBCAK

Note You need to log in before you can comment on or make changes to this bug.