Subject: Re: Bug#410: Segfault of _X11TransWritev in libNX_X11.so.6 with libQtGui

From: Sven Willenberger <[email-masked]>
Date: Thu, 26 Jun 2014 16:39:24 -0400

So this goes into tracker:

I have isolated the problem to the following change in the nx-libs
Makefile between 3.5.0.21 and 3.5.0.22, which persists through HEAD:

--- nx-libs-3.5.0.21/Makefile   2014-06-14 12:45:27.000000000 -0400
+++ nx-libs-HEAD/Makefile       2014-06-12 16:31:48.000000000 -0400
@@ -3,6 +3,7 @@
 INSTALL_DIR=install -d -m 755
 INSTALL_FILE=install -m 644
 INSTALL_PROGRAM=install -m 755
+INSTALL_SYMLINK=ln -s -f
 COPY_SYMLINK=cp -a
 RM_FILE=rm -f
 RM_DIR=rmdir -p --ignore-fail-on-non-empty
@@ -114,6 +115,13 @@
                                "$$(string_rep "$$dirname" nx-X11/.build-exports/include "$(DESTDIR)$(PREFIX)/include/nx")"/ || true; \
            done; \
 
+       # Provide means for Xinerama support in NX/X2Go sessions. This
+       # This also requires two post-install symlinks:
+       # (DESTDIR)$(NXLIBDIR)/X11/Xinerama/libNX_X11.so.6 -> /usr/<libdir>/libX11.so.6
+       # (DESTDIR)$(NXLIBDIR)/X11/Xinerama/libNX_Xext.so.6 -> /usr/<libdir>/libXext.so.6
+       $(INSTALL_DIR) $(DESTDIR)$(NXLIBDIR)/X11/Xinerama
+       $(INSTALL_SYMLINK) ../libNX_Xinerama.so.1 $(DESTDIR)$(NXLIBDIR)/X11/Xinerama/libXinerama.so.1
+
        $(INSTALL_DIR) $(DESTDIR)$(PREFIX)/include/nx/X11/bitmaps
        $(INSTALL_FILE) nx-X11/.build-exports/include/X11/bitmaps/* \
                        $(DESTDIR)$(PREFIX)/include/nx/X11/bitmaps/

Commenting out the Xinerama lines and rebuilding results in a clean run
of my (and your) python scripts as well as VLC player.

I have attached a diff (excepting whitespace differences (diff -ub) of
my system's Xinerama.c (xorg's libXinerama 1.1.3) and the one provided
in x2go's source (based on XFree86).

-- 
Sven Willenberger
United Pay Systems International
http://www.upsicorp.com

--- /data/Downloads/ABS/libxinerama/libXinerama-1.1.3/src/Xinerama.c	2013-05-30 20:28:02.000000000 -0400
+++ Xinerama.c	2014-06-14 11:29:40.837433407 -0400
@@ -1,3 +1,4 @@
+/* $Xorg: XPanoramiX.c,v 1.4 2000/08/17 19:45:51 cpqbld Exp $ */
 /*****************************************************************
 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,11 +23,10 @@
 dealings in this Software without prior written authorization from Digital
 Equipment Corporation.
 ******************************************************************/
+/* $XFree86: xc/lib/Xinerama/Xinerama.c,v 1.2 2001/07/23 17:20:28 dawes Exp $ */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
+#define NEED_EVENTS
+#define NEED_REPLIES
 #include <X11/Xlibint.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/Xext.h>
@@ -35,31 +35,17 @@
 #include <X11/extensions/panoramiXproto.h>
 #include <X11/extensions/Xinerama.h>
 
-#ifndef HAVE__XEATDATAWORDS
-#include <X11/Xmd.h>  /* for LONG64 on 64-bit platforms */
-#include <limits.h>
-
-static inline void _XEatDataWords(Display *dpy, unsigned long n)
-{
-# ifndef LONG64
-    if (n >= (ULONG_MAX >> 2))
-        _XIOError(dpy);
-# endif
-    _XEatData (dpy, n << 2);
-}
-#endif
 
 static XExtensionInfo _panoramiX_ext_info_data;
 static XExtensionInfo *panoramiX_ext_info = &_panoramiX_ext_info_data;
-static const char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME;
+static /* const */ char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME;
 
 #define PanoramiXCheckExtension(dpy,i,val) \
   XextCheckExtension (dpy, i, panoramiX_extension_name, val)
 #define PanoramiXSimpleCheckExtension(dpy,i) \
   XextSimpleCheckExtension (dpy, i, panoramiX_extension_name)
 
-static int close_display(Display *dpy, XExtCodes *codes);
-
+static int close_display();
 static /* const */ XExtensionHooks panoramiX_extension_hooks = {
     NULL,				/* create_gc */
     NULL,				/* copy_gc */
@@ -91,15 +77,15 @@
 
 Bool XPanoramiXQueryExtension (
     Display *dpy,
-    int *event_base_return,
-    int *error_base_return
+    int *event_basep,
+    int *error_basep
 )
 {
     XExtDisplayInfo *info = find_display (dpy);
 
     if (XextHasExtension(info)) {
-	*event_base_return = info->codes->first_event;
-	*error_base_return = info->codes->first_error;
+	*event_basep = info->codes->first_event;
+	*error_basep = info->codes->first_error;
 	return True;
     } else {
 	return False;
@@ -109,8 +95,8 @@
 
 Status XPanoramiXQueryVersion(
     Display *dpy,
-    int     *major_version_return,
-    int     *minor_version_return
+    int	    *major_versionp, 
+    int *minor_versionp
 )
 {
     XExtDisplayInfo *info = find_display (dpy);
@@ -130,8 +116,8 @@
 	SyncHandle ();
 	return 0;
     }
-    *major_version_return = rep.majorVersion;
-    *minor_version_return = rep.minorVersion;
+    *major_versionp = rep.majorVersion;
+    *minor_versionp = rep.minorVersion;
     UnlockDisplay (dpy);
     SyncHandle ();
     return 1;
@@ -241,11 +227,11 @@
 
 Bool XineramaQueryExtension (
    Display *dpy,
-   int     *event_base_return,
-   int     *error_base_return
+   int     *event_base,
+   int     *error_base
 )
 {
-   return XPanoramiXQueryExtension(dpy, event_base_return, error_base_return);
+   return XPanoramiXQueryExtension(dpy, event_base, error_base);
 }
 
 Status XineramaQueryVersion(
@@ -280,6 +266,8 @@
     return rep.state;
 }
 
+#include <stdio.h>
+
 XineramaScreenInfo *
 XineramaQueryScreens(
    Display *dpy,
@@ -291,7 +279,7 @@
     xXineramaQueryScreensReq	*req;
     XineramaScreenInfo		*scrnInfo = NULL;
 
-    PanoramiXCheckExtension (dpy, info, NULL);
+    PanoramiXCheckExtension (dpy, info, 0);
 
     LockDisplay (dpy);
     GetReq (XineramaQueryScreens, req);
@@ -303,26 +291,13 @@
 	return NULL;
     }
 
-    /*
-     * rep.number is a CARD32 so could be as large as 2^32
-     * The X11 protocol limits the total screen size to 64k x 64k,
-     * and no screen can be smaller than a pixel.  While technically
-     * that means we could theoretically reach 2^32 screens, and that's
-     * not even taking overlap into account, Xorg is currently limited
-     * to 16 screens, and few known servers have a much higher limit,
-     * so 1024 seems more than enough to prevent both integer overflow
-     * and insane X server responses causing massive memory allocation.
-     */
-    if ((rep.number > 0) && (rep.number <= 1024))
-	scrnInfo = Xmalloc(sizeof(XineramaScreenInfo) * rep.number);
-    if (scrnInfo != NULL) {
-	int i;
-
-	for (i = 0; i < rep.number; i++) {
+    if(rep.number) {
+	if((scrnInfo = Xmalloc(sizeof(XineramaScreenInfo) * rep.number))) {
 	    xXineramaScreenInfo scratch;
+	    int i;
 
+	    for(i = 0; i < rep.number; i++) {
 	    _XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo);
-
 	    scrnInfo[i].screen_number = i;
 	    scrnInfo[i].x_org	= scratch.x_org;
 	    scrnInfo[i].y_org	= scratch.y_org;
@@ -331,12 +306,14 @@
 	}
 
 	*number = rep.number;
-    } else {
-	_XEatDataWords(dpy, rep.length);
-	*number = 0;
+	} else
+	    _XEatData(dpy, rep.length << 2);
     }
 
     UnlockDisplay (dpy);
     SyncHandle ();
     return scrnInfo;
 }
+
+
+