Hi!

I've noticed that on sparc64 we got the same SIGBUS described here:

http://comments.gmane.org/gmane.comp.freedesktop.xorg/44722

This happens frequently and it's annoying as it renders GTK2
applications unusable on sparc64, since our gtk+2 is being
built using "--with-xinput".

---8<---

GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "sparc64-unknown-openbsd5.0"...(no debugging symbols 
found)

(gdb) run
Starting program: /usr/local/bin/gtk-demo 
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGBUS, Bus error.
0x000000020bd628ac in ParseClassInfo (any=0xfffffffffffcf068, 
Any=0xfffffffffffcf058, num_classes=1) at 
/usr/xenocara/lib/libXi/src/XListDev.c:104
104                         K->class = KeyClass;
(gdb) bt
#0  0x000000020bd628ac in ParseClassInfo (any=0xfffffffffffcf068, 
Any=0xfffffffffffcf058, num_classes=1) at 
/usr/xenocara/lib/libXi/src/XListDev.c:104
#1  0x000000020bd63024 in XListInputDevices (dpy=0x20ca5edb0, 
ndevices=0xfffffffffffcf18c) at /usr/xenocara/lib/libXi/src/XListDev.c:227
#2  0x0000000209b7c518 in gdk_drag_action_get_type () from 
/usr/local/lib/libgdk-x11-2.0.so.2400.0
#3  0x0000000209b53c74 in gdk_drag_action_get_type () from 
/usr/local/lib/libgdk-x11-2.0.so.2400.0
#4  0x0000000209b1c58c in gdk_display_open_default_libgtk_only () from 
/usr/local/lib/libgdk-x11-2.0.so.2400.0
#5  0x00000002008603e4 in gtk_init_check () from 
/usr/local/lib/libgtk-x11-2.0.so.2400.0
#6  0x000000020086041c in gtk_init () from 
/usr/local/lib/libgtk-x11-2.0.so.2400.0
#7  0x0000000000122e5c in main ()
(gdb) bt full
#0  0x000000020bd628ac in ParseClassInfo (any=0xfffffffffffcf068, 
Any=0xfffffffffffcf058, num_classes=1) at 
/usr/xenocara/lib/libXi/src/XListDev.c:104
        K = 0x20785ad44
        k = 0x20c994860
        j = 0
        k = 3
#1  0x000000020bd63024 in XListInputDevices (dpy=0x20ca5edb0, 
ndevices=0xfffffffffffcf18c) at /usr/xenocara/lib/libXi/src/XListDev.c:227
        size = 695
        req = (xListInputDevicesReq *) 0x202248000
        rep = {repType = 1 '\001', RepType = 2 '\002', sequenceNumber = 105, 
length = 87, ndevices = 6 '\006', pad1 = 0 '\0', pad2 = 0 '\0', pad3 = 0 '\0', 
  pad01 = 0, pad02 = 0, pad03 = 0, pad04 = 0, pad05 = 0}
        list = (xDeviceInfo *) 0x20c994808
        slist = (xDeviceInfo *) 0x20c994800
        sclist = (XDeviceInfo *) 0x20785ac00
        clist = (XDeviceInfo *) 0x20785ac28
        any = 0x20c994860
        sav_any = 0x20c994830
        Any = 0x20785ad44
        nptr = 0x20c99495b ""
        Nptr = 0xfffffffffffcf18c ""
        i = 1
        rlen = 348
        info = (XExtDisplayInfo *) 0x20a1b7100

---8<---

So, I've cherrypicked the patch at:
http://patchwork.freedesktop.org/patch/2272/

...And applied it to SizeClassInfo() too as suggested (it won't hurt)

This fixes the issue for me.
Comments or suggestions?

Index: src/XListDev.c
===================================================================
RCS file: /cvs/xenocara/lib/libXi/src/XListDev.c,v
retrieving revision 1.3
diff -u -p -r1.3 XListDev.c
--- src/XListDev.c      11 Nov 2010 10:49:22 -0000      1.3
+++ src/XListDev.c      13 Jan 2012 13:07:33 -0000
@@ -58,6 +58,17 @@ SOFTWARE.
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
 
+/* Calculate length field to a multiples of sizeof(XID). XIDs are typedefs
+ * to ulong and thus may be 8 bytes on some platforms. This can trigger a
+ * SIGBUS if a class ends up not being 8-aligned (e.g. after XAxisInfo).
+ */
+static int pad_to_xid(int base_size)
+{
+    int padsize = sizeof(XID);
+
+    return ((base_size + padsize - 1)/padsize) * padsize;
+}
+
 static int
 SizeClassInfo(xAnyClassPtr *any, int num_classes)
 {
@@ -66,18 +77,18 @@ SizeClassInfo(xAnyClassPtr *any, int num
     for (j = 0; j < num_classes; j++) {
         switch ((*any)->class) {
             case KeyClass:
-                size += sizeof(XKeyInfo);
+                size += pad_to_xid(sizeof(XKeyInfo));
                 break;
             case ButtonClass:
-                size += sizeof(XButtonInfo);
+                size += pad_to_xid(sizeof(XButtonInfo));
                 break;
             case ValuatorClass:
                 {
                     xValuatorInfoPtr v;
 
                     v = (xValuatorInfoPtr) *any;
-                    size += sizeof(XValuatorInfo) +
-                        (v->num_axes * sizeof(XAxisInfo));
+                    size += pad_to_xid(sizeof(XValuatorInfo) +
+                        (v->num_axes * sizeof(XAxisInfo)));
                     break;
                 }
             default:
@@ -102,7 +113,7 @@ ParseClassInfo(xAnyClassPtr *any, XAnyCl
                     xKeyInfoPtr k = (xKeyInfoPtr) *any;
 
                     K->class = KeyClass;
-                    K->length = sizeof(XKeyInfo);
+                    K->length = pad_to_xid(sizeof(XKeyInfo));
                     K->min_keycode = k->min_keycode;
                     K->max_keycode = k->max_keycode;
                     K->num_keys = k->num_keys;
@@ -114,7 +125,7 @@ ParseClassInfo(xAnyClassPtr *any, XAnyCl
                     xButtonInfoPtr b = (xButtonInfoPtr) *any;
 
                     B->class = ButtonClass;
-                    B->length = sizeof(XButtonInfo);
+                    B->length = pad_to_xid(sizeof(XButtonInfo));
                     B->num_buttons = b->num_buttons;
                     break;
                 }
@@ -126,8 +137,8 @@ ParseClassInfo(xAnyClassPtr *any, XAnyCl
                     xAxisInfoPtr a;
 
                     V->class = ValuatorClass;
-                    V->length = sizeof(XValuatorInfo) +
-                        (v->num_axes * sizeof(XAxisInfo));
+                    V->length = pad_to_xid(sizeof(XValuatorInfo) +
+                        (v->num_axes * sizeof(XAxisInfo)));
                     V->num_axes = v->num_axes;
                     V->motion_buffer = v->motion_buffer_size;
                     V->mode = v->mode;

Reply via email to