← Back to team overview

registry team mailing list archive

[Bug 257659] Re: XOrg::XNextEvent() crashed with SIGSEGV

 

Launchpad has imported 2 comments from the remote bug at
http://bugs.freedesktop.org/show_bug.cgi?id=17923.

If you reply to an imported comment from within Launchpad, your comment
will be sent to the remote bug automatically. Read more about
Launchpad's inter-bugtracker facilities at
https://help.launchpad.net/InterBugTracking.

------------------------------------------------------------------------
On 2008-10-06T04:08:24+00:00 Fumihito-yoshida wrote:

XNextEvent() segfault when XlibDisplayIOError is true
It cause by xcb_io.c::_XReadEvents() and xcb_io.c::_XSend()'s some code.
This problem affected to libX11 1.1.2 -1.1.5 and git (Release: R7.2 - R7.4) .

When dpy->head is null, the XNextEvent() called _XReadEvents(),
but xcb_io.c::_XReadEvents() and xcb_io.c::_XSend() has dpy->flags check,
when XlibDiskpayIOError bit is set, their procedure return without any work.

       if(dpy->flags & XlibDisplayIOError)
               return;

So, XNextEvent()'s dpy is still null, and crash.

This problem will crash IIIMF, Compiz and so on.


in Classical X event loop:
 // It will cause segfault in some conditions....

Display *pdisplay;
XEvent event;
pdisplay = XOpenDisplay(NULL);

for (; ;){
       XNextEvent(pdisplay, &event);
       /* X Event Handler */
}

This code causes segfault at XNextEvent(). If you trace it, you will
find below crash point.

--- XNextEvent() ----------------------------------
int
XNextEvent (
       register Display *dpy,
       register XEvent *event)
{
       register _XQEvent *qelt;

       LockDisplay(dpy);

       if (dpy->head == NULL)
           _XReadEvents(dpy);  // <- it hope _XReadEvents return valid
                                      //  handler, it believev
dpy->head != null...
       qelt = dpy->head;
       *event = qelt->event; // <- but, dpy->head->event is null, CRASH.
                                     // Because dpy->head is null!
       _XDeq(dpy, NULL, qelt);
       UnlockDisplay(dpy);
       return 0;
}
--------------------------------------------------

If you replace "if(dpy->head == null)" to "while(dpy->head == null)",
the problem solved.
// Notice: if => while replacement cause busy loop and possible infinite loop.

This segfaults conditions are:
 a) X Event queue is empty.
 b) XDisplayIOError is true.
You call XNextEvent() when (a && b), your program will segfault.


Case2: Modern X event loop style is below:
 // It wont cause segfault, and lockless.

Display *pdisplay;
XEvent event;
pdisplay = XOpenDisplay(NULL);

for (; ;){
       if (XPending()){
               XNextEvent(pdisplay, &event);
               /* X Event Handler */
       }
       /* other event looping and some usleeps. */
}

Because this implement want evading XNextEvent()'s blocking.
XNextEvent() always return least one events, but when X event
queue is empty, cause blocking-wait for next new events.

But, man XNextEvent(3) says:
|  The XNextEvent function copies the first event from the event queue
|  into the specified XEvent structure and then removes it from the queue.
|  If the event queue is empty, XNextEvent flushes the output buffer and
|  blocks until an event is received.

Current implement is not "blocks", "sometimes blocks, sometimes crash".

And we have big issue, the classical X event loop(Case1) are not failure
in old-days, their coding were(are?) right. (But, their old style coding are not
efficient, we need modern style.).

We can find their classical event loop in many code asset, they will crash
by this problem.....

I suggest dirty hack.
 XlibDisplayIOError flag can be cleard with some wait times.

--- NextEvent.c.orig
+++ NextEvent.c
@@ -45,9 +45,14 @@
       register _XQEvent *qelt;

       LockDisplay(dpy);

-       if (dpy->head == NULL)
+        while(dpy->head == NULL){
           _XReadEvents(dpy);
+           usleep(400);
+       }
       qelt = dpy->head;
       *event = qelt->event;
       _XDeq(dpy, NULL, qelt);

Reply at: https://bugs.launchpad.net/xorg-server/+bug/257659/comments/4

------------------------------------------------------------------------
On 2009-01-09T06:53:41+00:00 Tom Jaeger wrote:

Does your application use XTest?  If so, can you check if this patch
fixes the issue?

http://cgit.freedesktop.org/xorg/xserver/commit/?id=b2756a71a432f7cf7c870a48676c98625512558d

Reply at: https://bugs.launchpad.net/xorg-server/+bug/257659/comments/12


** Changed in: xorg-server
   Importance: Unknown => Medium

-- 
XOrg::XNextEvent() crashed with SIGSEGV
https://bugs.launchpad.net/bugs/257659
You received this bug notification because you are a member of Registry
Administrators, which is the registrant for Debian.