Home | Software Map | Motif Forums | Bug Home sponsored by ICS 
Full Text Bug Listing
 
Desktop hang: motif application in XGrabPointer
Bug#: 1328 Product: OpenMotif Version: 2.2.3 Platform: All
OS/Version: Linux Status: CLOSED Severity: critical Priority: High
Resolution: FIXED Assigned To: openmotif-devel@motifzone.net Reported By: richard.coe@med.ge.com
Component: MotifCode Target milestone:2.3.1
URL: 
Summary: Desktop hang: motif application in XGrabPointer
Description:
On system that is sufficiently busy, it's possible to lock up the
current motif application in a Mouse grab after clicking and releasing
a motif menu.  Hitting escape does not release the mouse.

We found many ways to make the system busy, but the easiest is to run
the following sh script:

while : ; do
    xlsfonts -fn *
done

I have not confirmed, but it seems that this problem originates with the
fix to bug 1269.  In that fix, XmGrabPointer was (correctly) modified
to resubmit the XtGrabPointer() if the event time is no longer valid.

The problem stems from the fact that the XtUngrabPointer() call made
later fails also.  The XtUngrabPointer() function call to XUngrabPointer()
fails, but the Xt function does not check nor return the return code.  
I'm not convinced that this is a Xt bug, since it originates by passing
in CurrentTime into XtGrabPointer call.

Here are tracebacks that show 1st and 2nd call to XtGrabPointer(),
and the failing call to XtUngrabPointer()

Breakpoint 1, 0x4bf15c06 in XGrabPointer () from /usr/X11R6/lib/libX11.so.6
#0  0x4bf15c06 in XGrabPointer () from /usr/X11R6/lib/libX11.so.6
#1  0x4c1dd4bb in XtUngrabButton () from /usr/X11R6/lib/libXt.so.6
#2  0x4c1dd892 in XtGrabPointer () from /usr/X11R6/lib/libXt.so.6
#3  0xb7ae9247 in _XmGrabPointer (widget=0x8ef9b78, owner_events=1,
    event_mask=60, pointer_mode=0, keyboard_mode=1, confine_to=0,
    cursor=58720263, time=360776) at MenuUtil.c:154
#4  0xb7aea3ae in _XmMenuGrabKeyboardAndPointer (widget=0x8ef9b78, time=360776)
    at MenuUtil.c:1079
#5  0xb7ae81cf in ChangeManaged (w=0x8ef9d10) at MenuShell.c:1612
#6  0x4c1d8e26 in XtUnmanageChild () from /usr/X11R6/lib/libXt.so.6
#7  0x4c1d9159 in XtManageChildren () from /usr/X11R6/lib/libXt.so.6
#8  0x4c1d9238 in XtManageChild () from /usr/X11R6/lib/libXt.so.6
#9  0xb7aa3d1f in Popup (cb=0x8efa8d0, event=0xbfffd980) at CascadeB.c:1790
#10 0xb7aa3636 in MenuBarSelect (wid=0x8efa8d0, event=0xbfffd980, param=0x0,
    num_param=0x4c204b38) at CascadeB.c:1317
#11 0x4c1f56d7 in _XtMatchAtom () from /usr/X11R6/lib/libXt.so.6
#12 0x4c1f5c0b in _XtMatchAtom () from /usr/X11R6/lib/libXt.so.6
#13 0x4c1f6203 in _XtTranslateEvent () from /usr/X11R6/lib/libXt.so.6
#14 0x4c1ce76b in XtDispatchEventToWidget () from /usr/X11R6/lib/libXt.so.6
#15 0x4c1cf2b4 in _XtOnGrabList () from /usr/X11R6/lib/libXt.so.6
#16 0x4c1cf46f in XtDispatchEvent () from /usr/X11R6/lib/libXt.so.6
#17 0x08084391 in main (argc=2, argv=0xbfffda84)

Breakpoint 1, 0x4bf15c06 in XGrabPointer () from /usr/X11R6/lib/libX11.so.6
#0  0x4bf15c06 in XGrabPointer () from /usr/X11R6/lib/libX11.so.6
#1  0x4c1dd4bb in XtUngrabButton () from /usr/X11R6/lib/libXt.so.6
#2  0x4c1dd892 in XtGrabPointer () from /usr/X11R6/lib/libXt.so.6
#3  0xb7ae9247 in _XmGrabPointer (widget=0x8ef9b78, owner_events=1,
    event_mask=60, pointer_mode=0, keyboard_mode=1, confine_to=0,
    cursor=58720263, time=0) at MenuUtil.c:154
#4  0xb7aea3ae in _XmMenuGrabKeyboardAndPointer (widget=0x8ef9b78, time=360776)
    at MenuUtil.c:1079
#5  0xb7ae81cf in ChangeManaged (w=0x8ef9d10) at MenuShell.c:1612
#6  0x4c1d8e26 in XtUnmanageChild () from /usr/X11R6/lib/libXt.so.6
#7  0x4c1d9159 in XtManageChildren () from /usr/X11R6/lib/libXt.so.6
#8  0x4c1d9238 in XtManageChild () from /usr/X11R6/lib/libXt.so.6
#9  0xb7aa3d1f in Popup (cb=0x8efa8d0, event=0xbfffd980) at CascadeB.c:1790
#10 0xb7aa3636 in MenuBarSelect (wid=0x8efa8d0, event=0xbfffd980, param=0x0,
    num_param=0x4c204b38) at CascadeB.c:1317
#11 0x4c1f56d7 in _XtMatchAtom () from /usr/X11R6/lib/libXt.so.6
#12 0x4c1f5c0b in _XtMatchAtom () from /usr/X11R6/lib/libXt.so.6
#13 0x4c1f6203 in _XtTranslateEvent () from /usr/X11R6/lib/libXt.so.6
#14 0x4c1ce76b in XtDispatchEventToWidget () from /usr/X11R6/lib/libXt.so.6
#15 0x4c1cf2b4 in _XtOnGrabList () from /usr/X11R6/lib/libXt.so.6
#16 0x4c1cf46f in XtDispatchEvent () from /usr/X11R6/lib/libXt.so.6
#17 0x08084391 in main (argc=2, argv=0xbfffda84)

Breakpoint 2, 0x4bf293d6 in XUngrabPointer () from /usr/X11R6/lib/libX11.so.6
#0  0x4bf293d6 in XUngrabPointer () from /usr/X11R6/lib/libX11.so.6
#1  0x4c1dd670 in XtUngrabButton () from /usr/X11R6/lib/libXt.so.6
#2  0x4c1dd932 in XtUngrabPointer () from /usr/X11R6/lib/libXt.so.6
#3  0xb7ae8ba4 in PopdownDone (widget=0x8efa160, event=0x80d34cc, params=0x0,
    num_params=0x0) at MenuShell.c:2107
#4  0xb7b79846 in _XmMenuPopDown (w=0x8efa160, event=0xbfffd980, popped_up=0x0)
    at RCMenu.c:755
#5  0xb7b7b549 in CheckUnpostAndReplay (rc=0x8efa160, event=0xbfffd980)
    at RCMenu.c:2343
#6  0xb7b7b5e0 in _XmHandleMenuButtonPress (wid=0x8efa160, event=0xbfffd980)
    at RCMenu.c:2380
#7  0xb7b7b6c9 in _XmMenuBtnDown (wid=0x8ef9b78, event=0xbfffd980, params=0x0,
    num_params=0x4c204b38) at RCMenu.c:2466
#8  0x4c1f56d7 in _XtMatchAtom () from /usr/X11R6/lib/libXt.so.6
#9  0x4c1f5c0b in _XtMatchAtom () from /usr/X11R6/lib/libXt.so.6
#10 0x4c1f6203 in _XtTranslateEvent () from /usr/X11R6/lib/libXt.so.6
#11 0x4c1ce76b in XtDispatchEventToWidget () from /usr/X11R6/lib/libXt.so.6
#12 0x4c1cf257 in _XtOnGrabList () from /usr/X11R6/lib/libXt.so.6
#13 0x4c1cf46f in XtDispatchEvent () from /usr/X11R6/lib/libXt.so.6
#14 0x08084391 in main (argc=2, argv=0xbfffda84)


This is not a pretty fix ...
It would be nice to know if _XmGrabPointer() changed the event time.
It would be nice to know if and why the XUngrabPointer failed in
XtUngrabPointer.

--- MenuShell.c.orig    2006-03-02 16:54:22.563857352 -0600
+++ MenuShell.c 2006-03-02 16:54:48.700883920 -0600
@@ -2105,6 +2105,7 @@ PopdownDone(

     /* Cleanup grabs */
     XtUngrabPointer((Widget) ms, _time);
+    XUngrabPointer(XtDisplay(ms), CurrentTime);
 }


------- Additional Comments From Yura Syrota 2006-03-20 09:51 -------
I unable to reproduce the bug even if I put sleep() before XtUngrabPointer().
Probably this bug has been fixed in my version of X. Could you provide info
about your version, please?


------- Additional Comments From richard.coe@med.ge.com 2006-03-23 16:23 -------
How to reproduce:
    (1) compile the attached program: menuTest.c
    (2) in a separate window, start the following sh program
        while : ; do
            xlsfonts -fn '*'
        done
    (3) start menuTest
    (4) make sure UIShell is not a (0,0) so you can click outside of the
        UI to the left.
    (5) click on 'textPageButton'
    (6) click on 'seriesPageButton'
    (7) click outside the UI
    (8) rapidly click 'textPageButton', where 'seriesPageButton' appears,
        and outside the UI
    (9) repeat at step (5) 

    Eventually, within several clicks the mouse will stick in the
    right-hand state.


------- Additional Comments From richard.coe@med.ge.com 2006-03-23 16:26 -------
/* testcase: motif bugzilla bug 1328
 *
 * compile with:
 *
 * cc -o menuTest menuTest.o -L/usr/X11R6/lib -lXm -lXt -lX11
 *
 */
#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/CoreP.h>
#include <X11/Shell.h>

#include <Xm/Xm.h>
#include <Xm/MwmUtil.h>
#include <Xm/MenuShell.h>

#include <Xm/ArrowB.h>
#include <Xm/CascadeB.h>
#include <Xm/DrawingA.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/RepType.h>
#include <Xm/RowColumn.h>
#include <Xm/ScrollBar.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>

#include <X11/Xmu/Editres.h>

Widget topLevel;

char *buf[4096];

void
activateCB_seriesPageButton(Widget w, XtPointer v, XtPointer u)
{
    /* compute something */
    memset(buf, 0, 4096);
    sleep(6);
    printf("button pushed\n");
}

int
main(int argc, char **argv)
{
    Widget UIShell, UIDrawingArea, mButton;
    Widget textPageMenu, textPagePane, textPagePane_shell;
    Widget seriesPageButton, textPageButton;
    XtAppContext app_context;

    topLevel = XtVaAppInitialize(&app_context, "menuTest", NULL, 0, &argc, argv,
        NULL, NULL, 0);

    XtAddEventHandler(topLevel, (EventMask) 0, True,
            (XtEventHandler) _XEditResCheckMessages, NULL);

    UIShell = XtVaCreatePopupShell("UIShell", topLevelShellWidgetClass,
            topLevel,
            XmNwidth, 256,
            XmNheight, 320,
            XmNx, 0,
            XmNmappedWhenManaged, True,
            NULL);

    UIDrawingArea = XtVaCreateManagedWidget("UIDrawingArea",
            xmDrawingAreaWidgetClass,
            UIShell,
            XmNresizePolicy, XmRESIZE_NONE,
            XmNwidth, 256,
            XmNheight, 320,
            XmNx, 300,
            XmNy, 300,
            XmNunitType, XmPIXELS,
            XmNmarginHeight, 1,
            XmNmarginWidth, 1,
            XmNmappedWhenManaged, True,
            NULL );


    mButton = XtVaCreateManagedWidget( "mButton",
            xmPushButtonWidgetClass, UIDrawingArea,
            XmNx, 3,
            XmNy, 190,
            XmNwidth, 60,
            XmNheight, 60,
            XmNmappedWhenManaged, True,
            NULL );

        /* Creation of textPageMenu */
    textPageMenu = XtVaCreateManagedWidget( "textPageMenu",
                    xmRowColumnWidgetClass, 
                    UIDrawingArea,
                    XmNrowColumnType, XmMENU_BAR,
                    XmNmenuAccelerator, "<KeyUp>F10",
                    XmNwidth, 60,
                    XmNheight, 55,
                    NULL );

    /* Creation of textPagePane */
    textPagePane_shell = XtVaCreatePopupShell ("textPagePane_shell",
                    xmMenuShellWidgetClass, textPageMenu,
                    XmNwidth, 1,
                    XmNheight, 1,
                    XmNallowShellResize, TRUE,
                    XmNoverrideRedirect, TRUE,
                    NULL );

    textPagePane = XtVaCreateWidget( "textPagePane",
                    xmRowColumnWidgetClass,
                    textPagePane_shell,
                    XmNrowColumnType, XmMENU_PULLDOWN,
                    XmNresizeHeight, TRUE,
                    XmNresizeWidth, TRUE,
                    XmNheight, 1,
                    XmNwidth, 1,
                    XmNadjustMargin, TRUE,
                    XmNadjustLast, TRUE,
                    XmNmarginWidth, 3,
                    NULL );

    /* Creation of seriesPageButton */
    seriesPageButton = XtVaCreateManagedWidget( "seriesPageButton",
                        xmPushButtonWidgetClass,
                        textPagePane,
                        NULL );
    XtAddCallback( seriesPageButton, XmNactivateCallback,
            (XtCallbackProc) activateCB_seriesPageButton,
            (XtPointer) NULL );

    /* Creation of textPageButton */
    textPageButton = XtVaCreateManagedWidget( "textPageButton",
                    xmCascadeButtonWidgetClass,
                    textPageMenu,
                    XmNsubMenuId, textPagePane,
                    XmNheight, 54,
                    XmNmarginHeight, 0,
                    XmNmarginWidth, 0,
                    XmNrecomputeSize, FALSE,
                    XmNx, 0,
                    XmNy, 0,
                    NULL );

    XtRealizeWidget(topLevel);
    XtPopup(UIShell, 0);
    XtAppMainLoop(app_context);
}


------- Additional Comments From Yura Syrota 2006-03-27 10:46 -------
Still unable to reproduce. I use X.Org X11 6.8.2. What about you?


------- Additional Comments From richard.coe@med.ge.com 2006-03-27 18:03 -------
I can reproduce this using Xorg X11 6.8.2

Since I can reproduce it, what traces, debugging or other information do 
you require in order to accept my proposed solution ?


------- Additional Comments From Yura Syrota 2006-03-29 08:54 -------
Could you also trace Xt calls?


------- Additional Comments From richard.coe@med.ge.com 2007-05-14 14:57 -------
This problem occurs anywhere XtUngrabPointer() is called with _time.

diff -urp openMotif-2.2.3/lib/Xm/MenuShell.c openMotif-2.2.3.new/lib/Xm/MenuShell.c
--- openMotif-2.2.3/lib/Xm/MenuShell.c  2007-03-05 19:01:17.118437768 -0600
+++ openMotif-2.2.3.new/lib/Xm/MenuShell.c      2007-03-02 16:33:24.625651160 -0600
@@ -1646,7 +1646,7 @@ ChangeManaged(

       if (RC_Type(rowcol) == XmMENU_POPUP)
       {
-        XtUngrabPointer(w, _time);
+        XtUngrabPointer(w, CurrentTime);
       }
    }
    mst->RC_ButtonEventStatus.verified = False;
@@ -2104,8 +2104,8 @@ PopdownDone(
     menuSTrait -> disarm((Widget) rowcol);

     /* Cleanup grabs */
-    XtUngrabPointer((Widget) ms, _time);
-    XUngrabPointer(XtDisplay(ms), CurrentTime);
+    XtUngrabPointer((Widget) ms, CurrentTime);
+    /* XUngrabPointer(XtDisplay(ms), CurrentTime); */
 }

 /*ARGSUSED*/
diff -urp openMotif-2.2.3/lib/Xm/RCMenu.c openMotif-2.2.3.new/lib/Xm/RCMenu.c
--- openMotif-2.2.3/lib/Xm/RCMenu.c     2002-01-30 09:47:19.000000000 -0600
+++ openMotif-2.2.3.new/lib/Xm/RCMenu.c 2007-03-02 16:34:18.757421880 -0600
@@ -735,7 +735,7 @@ _XmMenuPopDown(
         {   
             /* No submenus posted; must clean up ourselves */
             _XmMenuFocus( (Widget) rc, XmMENU_END, _time);
-            XtUngrabPointer( (Widget) rc, _time);
+            XtUngrabPointer( (Widget) rc, CurrentTime);

             MenuBarCleanup(rc);
             _XmSetInDragMode((Widget) rc, False);
@@ -760,7 +760,7 @@ _XmMenuPopDown(
       {  
          _XmMenuFocus(XtParent(rc), XmMENU_END, _time);
         MenuDisarm ((Widget) toplevel_menu);
-        XtUngrabPointer(XtParent(rc), _time);
+        XtUngrabPointer(XtParent(rc), CurrentTime);
       }
    }
    else if (IsOption(toplevel_menu) &&
@@ -772,7 +772,7 @@ _XmMenuPopDown(
         menu_shell_class.popdownEveryone))((Widget) XtParent(rc), event,
         NULL, NULL);
       MenuDisarm ((Widget) toplevel_menu);
-      XtUngrabPointer(XtParent(rc), _time);
+      XtUngrabPointer(XtParent(rc), CurrentTime);
    }
    else
       (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
@@ -2522,7 +2522,7 @@ _XmMenuBtnUp(
          MenuBarCleanup(w);
       MenuDisarm((Widget) w);
       _XmMenuFocus( (Widget) w, XmMENU_END, _time);
-      XtUngrabPointer( (Widget) w, _time);
+      XtUngrabPointer( (Widget) w, CurrentTime);
    }
    _XmSetInDragMode((Widget) w, False);

diff -urp openMotif-2.2.3/lib/Xm/RCPopup.c openMotif-2.2.3.new/lib/Xm/RCPopup.c
--- openMotif-2.2.3/lib/Xm/RCPopup.c    2003-08-21 14:19:37.000000000 -0500
+++ openMotif-2.2.3.new/lib/Xm/RCPopup.c        2007-03-02 16:35:07.427022976 -0600
@@ -489,7 +489,7 @@ _XmRC_PostTimeOut( XtPointer wid )
   popup->row_column.popup_workproc = 0;
   if (mst->RC_ButtonEventStatus.waiting_to_be_managed)
   {
-     XtUngrabPointer((Widget) popup, _time);
+     XtUngrabPointer((Widget) popup, CurrentTime);
      mst->RC_ButtonEventStatus.waiting_to_be_managed = FALSE;
      mst->RC_ButtonEventStatus.verified = FALSE;
   }


------- Additional Comments From akonoval@ics.com 2008-04-03 04:15 -------
I still cannot reproduce the issue.
I investigated it looking thought the code. 
In my opinion the bug cannot happen.The issue can occur if the specified time is
earlier than the last-pointer-grab time or is later than the current X server
time (according to XUngrabPointer manual).

Variable _time always coming time from event. I can't imagine how _time can be
less than  last-pointer-grab time or later than X server time. Do you have any
idea why ungrab can fail there?


------- Additional Comments From richard.coe@med.ge.com 2008-04-11 15:54 -------
I can recreate this at will.

In the Xserver, when anything other than CurrentTime is passed in,
ProcUngrabPointer() compares the time passed in to both currentTime and grabTime.
If the time parameter is outside these two values (LATER and EARLIER,
respectively) then the Ungrab is not performed.

What do you need from me to show this error occurring so that it can be fixed?


------- Additional Comments From richard.coe@med.ge.com 2008-05-21 16:48 -------
    timeline: not to scale 
   <-----|------------|-------------|---------------|----------->
         X0           X1            X2              X3 
         
    X0: is the timestamp of the initial event
    X1: is the timestamp of the initial grab attempt
    X2: is the actual timestamp of the grab event
    X3: is the timestamp of the ungrab event
    
    At (X1), _XmGrabPointer() calls XtGrabPointer(..., X0) which fails.
    At (X2), _XmGrabPointer() calls XtGrabPointer(..., CurrentTime) which succeeds
    At (X3), PopdownDone() calls XtUngrabPointer(..., X0) which fails.
    Now the pointer is stuck.
    
    The code which does (X2) was added by bug 1269.


------- Additional Comments From akonoval@ics.com 2008-05-29 07:41 -------
&#65279;Probably  the fix for bug 1269 caused your problem. Could you try to reproduce
the bug without that bugfix, and inform me if something change or not. 
In code it is looks like:
_XmGrabPointer(
	Widget widget,
	Bool owner_events,
	unsigned int event_mask,
	int pointer_mode,
	int keyboard_mode,
	Window confine_to,
	Cursor cursor,
		Time time )
{
   register int status = 0, retry;

   for (retry=0; retry < 5; retry++)
   {
      if ((status = XtGrabPointer(widget, owner_events, event_mask,
         			  pointer_mode, keyboard_mode, confine_to,
				  cursor, time)) == GrabSuccess)
	  {
		  fprintf(stderr,"status_= %d\n",status);
	 	break;
	  }
 /*     if (status == GrabInvalidTime)
	time = CurrentTime;
*/
      XmeMicroSleep(1000);
   }
   if (status != GrabSuccess)
      XmeWarning((Widget) widget, GRABPTRERROR);
	fprintf(stderr,"%s, time = %d\n","_XmGrabPointer", time);
   return(status);
}
Sorry for asking you to check my suggestions, but I still cannot reproduce the bug.


------- Additional Comments From Ihor Hayvuk 2008-08-28 13:31 -------
Patch for the bug #1269 has been dropped.


------- Additional Comments From Ihor Hayvuk 2008-08-28 13:33 -------
Fixed in CVS HEAD and openmotif_2_3 branches


Update this bug

Submit a Patch for this bug

Note: All patches are submitted under the MIT License.