Bug 20336

Summary: libxcb crashes on select() with high file descriptor value
Product: XCB Reporter: Michael Ost <most>
Component: LibraryAssignee: xcb mailing list dummy <xcb>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: xorg-team
Version: 1.1   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: libxcb-1.1-use-poll.patch
libX11-spec.patch

Description Michael Ost 2009-02-26 12:47:29 UTC
If you call check_internal_connections (src/xcb_io.c) in an application that has more than FD_SETSIZE files already open, the select() calls they make will corrupt that stack and crash the app.

This is the old poll() vs select() bug. Replacing select() with poll() fixes
it.
Comment 1 Michael Ost 2009-02-26 12:48:49 UTC
Created attachment 23334 [details] [review]
libxcb-1.1-use-poll.patch

This patch replaces select() with poll() if USE_POLL is set by configure. It
was built against the libX11-1.1.3-5.fc8 that came with Fedora 8. It fixes the
crash I was seeing.
Comment 2 Michael Ost 2009-02-26 12:50:52 UTC
Created attachment 23335 [details] [review]
libX11-spec.patch

This patches the Fedora 8 spec file to include attachment #23334 [details] [review], above. It was built against the spec file for 1.1.3-4.fc8.
Comment 3 Julien Danjou 2009-03-13 02:08:16 UTC
I'd suggest to simply drop select() in favor of poll().

What do you think, fellow XCB developers?
Comment 4 Peter Harris 2009-03-13 08:27:28 UTC
(In reply to comment #3)
> I'd suggest to simply drop select() in favor of poll().
> 
> What do you think, fellow XCB developers?

Is poll() available on every platform that XCB intends to support?

At the very least, the Win32 patch posted to the list recently would need to be updated to restore select() there. (This bug isn't applicable to the Win32 implementation of select, and Win32 doesn't have poll)
Comment 5 Julien Danjou 2009-03-14 00:47:08 UTC
poll() is POSIX.1-2001. Do we attend to support system that are not POSIX.1-2001 ?

I doubt so.
Comment 6 Peter Harris 2009-03-14 06:21:37 UTC
(In reply to comment #5)
> poll() is POSIX.1-2001. Do we attend to support system that are not
> POSIX.1-2001 ?

Given that XCB is now the transport layer for Xlib, yes. XCB needs to support every platform that Xlib runs on.

I think Xlib may have dropped support for VMS and the original Cray, but a standard that sounds like it is only 8 years old is far too recent for Xlib to require.

That said, I cannot find a list of currently supported Xlib platforms.
Comment 7 James Cloos 2009-03-14 09:56:30 UTC
I find these files in my aclocal:

ac_sys_dev_poll.m4
ax_have_epoll.m4
ax_have_poll.m4

All three from the archive at:

http://autoconf-archive.cryp.to/

I suspect libxcb should use epoll(7) where that is available, else
poll(2), else select(2).  With /dev/poll thrown in there somewhere.

(Someone from Sun should specify whether /dev/poll is preferred on
Solaris.)

Also, I see from epoll(7) that FreeBSD has something called kqueue
which is similar to epoll(7).  After some gogoling I find that at
least NetBSD has a pollts(2) call.

Also, when using poll(2), should ppoll(2) be preferred?

And when falling back to select(2), should pselect(2) be preferred?

I beleive libxcb should use the best option for each platform.

Someone must already have figured out the best choices for each
platform and written suitable autotools macros and #if code for
this problem space....
Comment 8 Julien Danjou 2009-03-14 10:26:49 UTC
Well, not against but this kind of idea to drop select() in this case we are going to reimplement libev[1].

[1] http://libev.schmorp.de
Comment 9 RĂ©mi Cardona 2009-03-15 11:38:00 UTC
Does it really matter anyway? I mean, who is going to use libX11 or xcb intensively without using a higher-level toolkit of some sort?

I suggest picking one that is cross-platform and doesn't crash - poll(), although old, works fine - and those who need better performance/throughput can use whatever mechanism they like, or whatever mechanism their toolkit's event loop uses.

I do suggest writing a note somewhere in the documentation though.

Cheers :)
Comment 10 Alan Coopersmith 2009-03-16 16:59:31 UTC
(In reply to comment #7)
> (Someone from Sun should specify whether /dev/poll is preferred on
> Solaris.)

/dev/poll is more efficient when monitoring a large number of fd's, but
does libxcb really monitor more than one or two fd's?   There's also the
event ports interface in Solaris 10 and later if you're making a full 
list of options...

References:
http://developers.sun.com/solaris/articles/polling_efficient.html
http://developers.sun.com/solaris/articles/event_completion.html
http://blogs.sun.com/dap/entry/event_ports_and_performance
http://blogs.sun.com/dap/entry/event_ports_and_performance_take
http://blogs.sun.com/dap/entry/libevent_and_solaris_event_ports

As noted in the last one, perhaps a library like libev/libevent that already
handles all the platform specific optimizations is best if you don't want
to just stick to poll().
Comment 11 James Cloos 2009-03-28 14:49:02 UTC
Given all of the replies, it does seem best to default to poll(2) and
fall back to select(2) if poll(2) is unavailable.
Comment 12 Julien Danjou 2009-03-30 02:12:32 UTC
commit f916062edf0e04cd4e0a78f6975892f59fae3b60
Author: Michael Ost <most@museresearch.com>
Date:   Mon Mar 30 11:09:32 2009 +0200

    use poll() instead of select() when available
    
    Signed-off-by: Julien Danjou <julien@danjou.info>

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.