United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6532373 xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed.
JDK-6532373 : xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed.

Details
Type:
Bug
Submit Date:
2007-03-08
Status:
Resolved
Updated Date:
2011-02-16
Project Name:
JDK
Resolved Date:
2007-10-09
Component:
client-libs
OS:
linux
Sub-Component:
java.awt
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6,7
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Duplicate:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0-b105, mixed mode)

(also occurs with jdk1.7.0-b09 snapshot)

ADDITIONAL OS VERSION INFORMATION :
Linux kellyc-desktop 2.6.20-9-generic #2 SMP Sun Feb 25 22:59:06 UTC 2007 x86_64 GNU/Linux
Ubuntu Feisty 7.04

EXTRA RELEVANT SYSTEM CONFIGURATION :
libxcb1                                  1.0-1.1

A DESCRIPTION OF THE PROBLEM :
Starting up any java app that uses awt gives this error immediately upon startup. E.g. jconsole. See this forum post: http://forum.java.sun.com/thread.jspa?threadID=782829

The error is: xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed.

This occurs with the latest 1.7.0-b09 snapshot build. However if I build 1.7.0-b09 (svn trunk revision #70) from source on my machine, it works fine in both the regular binary and fastdebug binary, so this could be related to something in the standard build environment, or perhaps related to the defines in XlibWrapper.c that look related to locking and are only enabled on internal builds.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Install java on a ubuntu 7.04 (feisty) system with updates applied.
Try to run jconsole from a terminal.
The error occurs.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
jconsole window should open.
ACTUAL -
no window opens.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed.

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
downgrade xcb and xlib

                                    

Comments
EVALUATION

This issue has been already discussed in different forums, for example:

http://lwjgl.org/forum/index.php/topic,2168.0.html

In a few words, the answer is: AWT is not supposed (yet) to be used with XCB, or at least this nobody checked this. Probably, we need to pay more attention to XCB support.
                                     
2007-03-09
EVALUATION

as far asI understand to trigger this problem we need to call either XLockDisplay() or
XUnlockDisplay.  I've grepped for these names in our code and found nothing :(
So, I suspect it is a bug in some library we use (like Xrandr).

It would be nice to get stack trace for triggered assertion to understand what does
trigger this.  (Hope submitter should be able to get it)
                                     
2007-03-12
EVALUATION

well, it looks like everyone believe that the cause of the problem is old version of
Xinerama we use.  We have updated it in 7.0 and so the problem must not be reproducible 
with latest builds of jdk 7.

Since I can not check this (I have no environment for this :(  It would be nice to get confirmation from the comunity.
                                     
2007-06-04
EVALUATION

I've developed the small test (attached) to demonstrate the problem and it looks like the problem is not in the code but in the environment  :(   The test is very simple: it calls LockDisplay() and _XReply(), in usual situation it hangs because there is no replies, but on in bad it throws the assertion.

Here is what you need to reproduce the problem:
you need to build the test on platform which doesn't have xcb and then run it on a platform with xcb.

My theory about why we have the problem is as follows:

the test uses X11 library for LockDisplay() and Xext library for _XReply().  And it looks like the direct calls to LockDisplay() are not intercepted by XCB and so XReply() triggers the assertion :(

So, I'd say that this is no a java bug, but some problem with the way XCB is used on a platform :(
                                     
2007-06-26
EVALUATION

https://bugs.freedesktop.org/show_bug.cgi?id=11390

was filed against this problem, and since XCB team has accepted it, I'm closing this CR as
not a java bug.
                                     
2007-06-28
EVALUATION

The XCB team has determined this is not their bug, since JDK is using a statically
linked, non-thread-safe copy of libXinerama.  See Comment #3 on
https://bugs.freedesktop.org/show_bug.cgi?id=11390
                                     
2007-07-26
EVALUATION

I can not say that I do like the decision XCB team made, but I do understand why they
choose it :/

Will see what we can do here.

I'm not sure if we can always rely on Xinerama installed on a platform :( need to evaluate
this.
                                     
2007-07-26
EVALUATION

it looks like the only way for us is to use dlopen to work with Xinerama.
Since it is 2D who works with this stuff, I'm reassigning the problem to them.
                                     
2007-08-06
EVALUATION

awt_GraphicsEnv.c has two code paths
One for Solaris which uses dlopen, the other for Linux which uses a JDK
internal copy of Xinerama.c.

So the code path we need is already there (the solaris one) - it more or less just needs
to be made the Linux code path too - but pointing at libXibnerama not libXext
and we can delete the libXinerma source.

The principle consequence is that Linux envts which do not support that
lib will no longer have a Xinerama aware JDK. Seems they may be on their
way put anyway.
                                     
2007-08-06
EVALUATION

While using the dynamic library is preferred, can't you also fix it by using a 
version of the static library built with the thread-safe flag (-DXTHREADS)?
                                     
2007-08-06
EVALUATION

We could try do build Xinerama.c with DXTHREADS but it would require
investigation to see if that was going to cause problems too.
Also the preference of Linux distributions (and Sun) is for dynamic linking so that
patches are more easily applied. Think of the static linking to date as a workaround
for the previous lack of dynamic linking as an option.
                                     
2007-08-07
EVALUATION

Requires installing the lib-x11 in the experimental repository.
I've recreated the behavior this way:

	I installed debian 4.0r1
	Changed the sources.list to use "sid" (for unstable)
	did apt-get dist-upgrade
	Those two steps is the standard way to get to "Debian Unstable"
	Installed the sun-java6 packages
	It still didn't crash
	Added to sources.list:  deb http://ftp.us.debian.org/debian/ experimental main
	This accesses the experimental repository
	Ran: apt-get update; apt-get install libxcb1 libxcb-xlib0
	Now jconsole crashes with the reported error message

Announcement of lib-x11 availability in experimental
http://lists.debian.org/debian-devel-announce/2006/11/msg00010.html

http://packages.debian.org/experimental/libs/libx11-6
                                     
2007-08-22
EVALUATION

Forum discussion on SDN
http://forum.java.sun.com/thread.jspa?threadID=782829

Gentoo, sun-java-5
http://bugs.gentoo.org/show_bug.cgi?id=156353
"Fix" was to disable the XCB Xlib

Gentoo, sun-java-6
http://bugs.gentoo.org/show_bug.cgi?id=181617

Gentoo, sun-java-5
http://bugs.gentoo.org/show_bug.cgi?id=181854

An article saying XCB Xlib will not be used for Ubuntu 7.10 (gutsy gibbon).
http://www.desktoplinux.com/news/NS4979518777.html
They cite delays by the XCB team in fixing some bugs.
                                     
2007-08-22
SUGGESTED FIX

here is a preliminary version of the fix:

+++ Makefile        2007-09-25 13:03:02.000000000 +0400
@@ -47,11 +47,10 @@
 AUTO_JAVA_PRUNE = WrapperGenerator.java
 
 LDFLAGS += -L$(OPENWIN_LIB)
 
 ifeq ($(PLATFORM), linux)
-FILES_c += Xinerama.c
 LDFLAGS += -lpthread
 dummy := $(shell $(MKDIR) -p $(LIB_LOCATION))
 endif
 
 # Since this library will be living in a subdirectory below the other libraries
@@ -249,12 +248,10 @@
         fi
         @if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \
             $(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
             $(DIFF) $@ $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
         fi        
-                
-
 
 $(TEMPDIR)/.gen.wrappers: $(SIZES) $(WRAPPER_GENERATOR_CLASS) $(XLIBTYPES)
         $(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \
             $(GEN_DIR) $(XLIBTYPES) "gen" $(WRAPPER_GENERATOR_DIR)/sizes
 
+++ mawt.gmk        2007-09-25 13:03:02.000000000 +0400
@@ -55,13 +55,10 @@
   FILES_c = $(FILES_MOTIF_c) $(FILES_NO_MOTIF_c)
 
   ifeq ($(MOTIF_VERSION), 2)
     FILES_c += awt_motif21.c
     FILES_c += awt_Choice21.c
-    ifeq  ($(PLATFORM), linux)
-        FILES_c += Xinerama.c
-    endif
   endif
 
 endif
 
 ifeq ($(PLATFORM), solaris)

+++ awt_GraphicsEnv.c        2007-09-25 13:06:28.000000000 +0400
@@ -30,10 +30,11 @@
 #include <sun_awt_X11GraphicsEnvironment.h>
 #include <sun_awt_X11GraphicsDevice.h>
 #include <sun_awt_X11GraphicsConfig.h>
 #ifndef HEADLESS
 #include <X11/extensions/Xdbe.h>
+#include <X11/XKBlib.h>
 #include "Xrandr.h"
 #include "GLXGraphicsConfig.h"
 #endif /* !HEADLESS */
 
 #include <jni.h>
@@ -56,11 +57,10 @@
 #endif
 
 #ifndef HEADLESS
 #ifdef __linux__
 #include <X11/XKBlib.h>
-#include "Xinerama.h"
 #endif
 
 int awt_numScreens;     /* Xinerama-aware number of screens */
 
 AwtScreenDataPtr x11Screens;
@@ -123,11 +123,22 @@
  * operation on both OSes.  Until then, some of the Xinerama-related code
  * is ifdef'd appropriately.  -bchristi, 7/12/01
  */
 
 #define MAXFRAMEBUFFERS 16
-#ifndef __linux__ /* SOLARIS */
+#ifdef __linux__
+typedef struct {
+   int   screen_number;
+   short x_org;
+   short y_org;
+   short width;
+   short height;
+} XineramaScreenInfo;
+
+typedef XineramaScreenInfo* XineramaQueryScreensFunc(Display*, int*);
+
+#else /* SOLARIS */
 typedef Status XineramaGetInfoFunc(Display* display, int screen_number,
          XRectangle* framebuffer_rects, unsigned char* framebuffer_hints,
          int* num_framebuffers);
 typedef Status XineramaGetCenterHintFunc(Display* display, int screen_number,
                                          int* x, int* y);
@@ -615,113 +626,128 @@
     if (largestAmtScr != wdata->screenNum) {
         wdata->screenNum = largestAmtScr;
         /* update peer, target Comp */
         (*env)->CallVoidMethod(env, peer,
                                mWindowPeerIDs.draggedToScreenMID, largestAmtScr);
-                               
     }
 #endif /* XAWT */
 }
 #endif /* HEADLESS */
 
-/*
- * Do Xinerama-related initialization such as
- * - check if Xinerama is running
- * - if so, load and run Xinerama query functions from the appropriate library
- */
 #ifndef HEADLESS
-void xineramaInit(void) {
 #ifdef __linux__
-    char* XinExtName = "XINERAMA";
-    int32_t major_opcode, first_event, first_error;
-    Bool gotXinExt = False;
-    unsigned char fbhints[MAXFRAMEBUFFERS];
+static void xinerama_init_linux()
+{
+    void* libHandle = 0;
+    char* XineramaLibName= "libXinerama.so";
     int32_t locNumScr = 0;
-    int32_t idx;
-
     XineramaScreenInfo *xinInfo;
+    char* XineramaQueryScreensName = "XineramaQueryScreens";
+    XineramaQueryScreensFunc* XineramaQueryScreens = NULL;
 
-    gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
-                                &first_event, &first_error);
-
-    if (gotXinExt) {
-        DTRACE_PRINTLN("Xinerama extension available");
-                    DTRACE_PRINTLN("calling XineramaGetInfo func on Linux");
-                    xinInfo = XineramaQueryScreens(awt_display, &locNumScr);
-                    if (xinInfo != NULL) {
-                        DTRACE_PRINTLN("Enabling Xinerama support");
-                        usingXinerama = True;
-                        /* set global number of screens */
-                        DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
-                        awt_numScreens = locNumScr;
-
-                        /* stuff values into fbrects */
-                        for (idx = 0; idx < awt_numScreens; idx++) {
-                            DASSERT(xinInfo[idx].screen_number == idx);
-
-                            fbrects[idx].width = xinInfo[idx].width;
-                            fbrects[idx].height = xinInfo[idx].height;
-                            fbrects[idx].x = xinInfo[idx].x_org;
-                            fbrects[idx].y = xinInfo[idx].y_org;
-                        }
-                    } else {
-                        DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
-                    }
+    /* load library */
+    libHandle = dlopen(XineramaLibName, RTLD_LAZY | RTLD_GLOBAL);
+    if (libHandle != 0) {
+        XineramaQueryScreens = (XineramaQueryScreensFunc*)
+            dlsym(libHandle, XineramaQueryScreensName);
+
+        if (XineramaQueryScreens != NULL) {
+            DTRACE_PRINTLN("calling XineramaGetInfo func on Linux");
+            xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
+            if (xinInfo != NULL) {
+                int32_t idx;
+                DTRACE_PRINTLN("Enabling Xinerama support");
+                usingXinerama = True;
+                /* set global number of screens */
+                DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
+                awt_numScreens = locNumScr;
+
+                /* stuff values into fbrects */
+                for (idx = 0; idx < awt_numScreens; idx++) {
+                    DASSERT(xinInfo[idx].screen_number == idx);
+
+                    fbrects[idx].width = xinInfo[idx].width;
+                    fbrects[idx].height = xinInfo[idx].height;
+                    fbrects[idx].x = xinInfo[idx].x_org;
+                    fbrects[idx].y = xinInfo[idx].y_org;
+                }
+            } else {
+                DTRACE_PRINTLN("calling XineramaQueryScreens didn't work");
+            }
+        } else {
+            DTRACE_PRINTLN("couldn't load XineramaQueryScreens symbol");
+        }
+        dlclose(libHandle);
     } else {
-        DTRACE_PRINTLN("Xinerama not available");
+        DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
     }
-
-#else /* Solaris */
-
-    char* XinExtName = "XINERAMA";
-    int32_t major_opcode, first_event, first_error;
-    Bool gotXinExt = False;
+}
+#endif
+#ifndef __linux__ /* Solaris */
+static void xinerama_init_solaris()
+{
     void* libHandle = 0;
-    unsigned char fbhints[MAXFRAMEBUFFERS];
-    int locNumScr = 0;
-
     char* XineramaLibName= "libXext.so";
+    unsigned char fbhints[MAXFRAMEBUFFERS];
+    int32_t locNumScr = 0;
+    /* load and run XineramaGetInfo */
     char* XineramaGetInfoName = "XineramaGetInfo";
     char* XineramaGetCenterHintName = "XineramaGetCenterHint";
     XineramaGetInfoFunc* XineramaSolarisFunc = NULL;
 
-    gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
-                                &first_event, &first_error);
-
-    if (gotXinExt) {
-        DTRACE_PRINTLN("Xinerama extension available");
-
-        /* load library, load and run XineramaGetInfo */
-        libHandle = dlopen(XineramaLibName, RTLD_LAZY | RTLD_GLOBAL);
-        if (libHandle != 0) {
-            XineramaSolarisFunc = (XineramaGetInfoFunc*)dlsym(libHandle, XineramaGetInfoName);
-            XineramaSolarisCenterFunc =
-             (XineramaGetCenterHintFunc*)dlsym(libHandle,
-                                               XineramaGetCenterHintName);
-            if (XineramaSolarisFunc != NULL) {
-                DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris");
-                if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0],
-                     &fbhints[0], &locNumScr) != 0) {
-
-                    DTRACE_PRINTLN("Enabling Xinerama support");
-                    usingXinerama = True;
-                    /* set global number of screens */
-                    DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
-                    awt_numScreens = locNumScr;
-                } else {
-                    DTRACE_PRINTLN("calling XineramaGetInfo didn't work");
-                }
+    /* load library */
+    libHandle = dlopen(XineramaLibName, RTLD_LAZY | RTLD_GLOBAL);
+    if (libHandle != 0) {
+        XineramaSolarisFunc = (XineramaGetInfoFunc*)dlsym(libHandle, XineramaGetInfoName);
+        XineramaSolarisCenterFunc =
+            (XineramaGetCenterHintFunc*)dlsym(libHandle, XineramaGetCenterHintName);
+
+        if (XineramaSolarisFunc != NULL) {
+            DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris");
+            if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0],
+                                       &fbhints[0], &locNumScr) != 0)
+            {
+                DTRACE_PRINTLN("Enabling Xinerama support");
+                usingXinerama = True;
+                /* set global number of screens */
+                DTRACE_PRINTLN1(" num screens = %i\n", locNumScr);
+                awt_numScreens = locNumScr;
             } else {
-                DTRACE_PRINTLN("couldn't load XineramaGetInfo symbol");
+                DTRACE_PRINTLN("calling XineramaGetInfo didn't work");
             }
-            dlclose(libHandle);
         } else {
-            DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
+            DTRACE_PRINTLN("couldn't load XineramaGetInfo symbol");
         }
+        dlclose(libHandle);
     } else {
-        DTRACE_PRINTLN("Xinerama not available");
+        DTRACE_PRINTLN1("\ncouldn't open shared library: %s\n", dlerror());
     }
+}
+#endif
+
+/*
+ * Checks is Xinerama is running and perform Xinerama-related
+ * platform dependent initialization.
+ */
+static void xineramaInit(void) {
+    char* XinExtName = "XINERAMA";
+    int32_t major_opcode, first_event, first_error;
+    Bool gotXinExt = False;
+
+    gotXinExt = XQueryExtension(awt_display, XinExtName, &major_opcode,
+                                &first_event, &first_error);
+
+    if (!gotXinExt) {
+        DTRACE_PRINTLN("Xinerama is not available");
+        return;
+    }
+
+    DTRACE_PRINTLN("Xinerama extension is available");
+#ifdef __linux__
+    xinerama_init_linux();
+#else /* Solaris */
+    xinerama_init_solaris();
 #endif /* __linux__ */
 }
 #endif /* HEADLESS */
 
 Display *
@@ -920,11 +946,11 @@
 Java_sun_awt_X11GraphicsDevice_getDisplay(JNIEnv *env, jobject this)
 {
 #ifdef HEADLESS
     return NULL;
 #else
-    return (jlong) awt_display;
+    return ptr_to_jlong(awt_display);
 #endif /* !HEADLESS */
 }
 
 #ifdef MITSHM
                                     
2007-09-25
SUGGESTED FIX

the final fix can be found at http://sa.sfbay.sun.com/projects/awt_data/7/6532373.1
and it is attached to the CR.
                                     
2007-10-01
EVALUATION

[SQE]
The fix affects Solaris and Linux.  To verify it run all multiscreen-related tests (test/java/awt/Multiscreen & test/closed/awt/Multiscreen)
[SQE]
                                     
2007-10-01



Hardware and Software, Engineered to Work Together