Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6735584
Votes 0
Synopsis XNETProtocol:setStateHelper() produces bad _NET_WM_STATE messages
Category java:classes_awt
Reported Against b02
Release Fixed 7(b36)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs
Submit Date 08-AUG-2008
Description
bustos 2008-08-08

Often when a Java application creates a new window, my window manager,
sawfish, also displays an error notification, like

	Bad argument: #<subr x-atom-name>, 1866888309, 1

This particular message usually appears when I launch bugster.

That particular error happens when sawfish is interpreting the _NET_WM_STATE
message.  According to the Extended Window Manager Hints specification at
http://standards.freedesktop.org/wm-spec/1.3/index.html , it's allowed to
contain three atoms.  sawfish is finding the last atom field to be 1866888309,
which is far more than the last valid atom in my X server, which is
449 = _NET_WM_WINDOW_TYPE_TOOLTIP (according to xlsatoms).

Using truss and DTrace, I determined that java was indeed sending
the message with the invalid atom.  The stack is

              libX11.so.4`XSendEvent
              libmawt.so`Java_sun_awt_X11_XlibWrapper_XSendEvent+0x3a
              sun/awt/X11/XlibWrapper.XSendEvent(JJZJJ)I
              sun/awt/X11/XNETProtocol.setStateHelper(Lsun/awt/X11/XWindowPeer;Lsun/awt/X11/XAtom;Z)V
              sun/awt/X11/XNETProtocol.setLayer(Lsun/awt/X11/XWindowPeer;I)V
              sun/awt/X11/XWM.setLayer(Lsun/awt/X11/XWindowPeer;I)V
              sun/awt/X11/XWindowPeer.updateAlwaysOnTop()V
              sun/awt/X11/XWindowPeer.handleMapNotifyEvent(Lsun/awt/X11/XEvent;)V
              sun/awt/X11/XBaseWindow.dispatchEvent(Lsun/awt/X11/XEvent;)V
              sun/awt/X11/XBaseWindow.dispatchToWindow(Lsun/awt/X11/XEvent;)V
              sun/awt/X11/
              0xfc402edd
              0xfc402edd
              0xfc4033b9
              0xfc400244
              libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
              libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
              libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
              libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_+0xc1
              libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_+0x7e
              libjvm.so`__1cMthread_entry6FpnKJavaThread_pnGThread__v_+0xd2
              libjvm.so`__1cKJavaThreadRthread_main_inner6M_v_+0x4c
              libjvm.so`__1cKJavaThreadDrun6M_v_+0x182
              libjvm.so`java_start+0xee
              libc.so.1`_thr_setup+0x70
              libc.so.1`_lwp_start

From hg.openjdk.java.net we can see the code where XNETProtocol.setStateHelper()
calls XSendEvent():

            XClientMessageEvent req = new XClientMessageEvent();
            try {
                req.set_type((int)XConstants.ClientMessage);
                req.set_window(window.getWindow());
                req.set_message_type(XA_NET_WM_STATE.getAtom());
                req.set_format(32);
                req.set_data(0, (!set) ? _NET_WM_STATE_REMOVE : _NET_WM_STATE_ADD);
                req.set_data(1, state.getAtom());
                log.log(Level.FINE, "Setting _NET_STATE atom {0} on {1} for {2}", new Object[] {state, window, Boolean.valueOf(set)});
                XToolkit.awtLock();
                try {
                    XlibWrapper.XSendEvent(XToolkit.getDisplay(),
                                           XlibWrapper.RootWindow(XToolkit.getDisplay(), window.getScreenNumber()),
                                           false,
                                           XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask,
                                           req.pData);

Notice that the first two fields are set via set_data(), but the third is not.  Since
the code for XClientMessageEvent is generated by WrapperGenerator.java, it's
not easy to determine the code, but I suspect that the third field is not initialized
to 0.  The fact that the observed value, 1866888309, corresponds to the string
fragment "utFo" supports this.

Since the specification calls for the third field to be 0 if it's unused, it seems
that either XClientMessageEvent should be changed to set unused fields to 0,
or XNETProtocol should explicitly call set_data(2, 0).
Posted Date : 2008-08-08 22:35:24.0
Work Around
N/A
Evaluation
I have found two places where XClientMessageEvent fields are not set to 0 according to the specification: XNETProtocol.setStateHelper() and XNETProtocol.requestState() methods. Both are corrected: see suggested fix for details.

Some other _NET_WM_* messages also require their unused fields be set to 0, for example, _NET_WM_PING and _NET_WM_SYNC_REQUEST. At the current moment, these atoms are not used in AWT.
Posted Date : 2008-08-12 07:06:06.0

After more careful reading of the specification I found that only the second property being changed (data.l[2]) must be set to 0 if unused, and the rest of the fields (data.l[3] and data.l[4]) may have any values. Therefore, only setStateHelper() method should be fixed, while requestState() has no problems. Suggested fix is corrected.
Posted Date : 2008-08-12 07:26:26.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang