[xulrunner] Fix SIGABRT in X_CloseDevice: XI_BadDevice

Christopher Aillon caillon at fedoraproject.org
Mon Apr 4 08:19:30 UTC 2011


commit 7aeeef53ada05e16e680c807f2779fbc3f9464ad
Author: Christopher Aillon <caillon at redhat.com>
Date:   Sat Apr 2 21:56:35 2011 -0700

    Fix SIGABRT in X_CloseDevice: XI_BadDevice
    
    Fedora bug:  https://bugzilla.redhat.com/543165
    Mozilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=576933

 xulrunner-2.0-baddevice.patch |  185 +++++++++++++++++++++++++++++++++++++++++
 xulrunner.spec                |    2 +
 2 files changed, 187 insertions(+), 0 deletions(-)
---
diff --git a/xulrunner-2.0-baddevice.patch b/xulrunner-2.0-baddevice.patch
new file mode 100644
index 0000000..e37ab9a
--- /dev/null
+++ b/xulrunner-2.0-baddevice.patch
@@ -0,0 +1,185 @@
+# HG changeset patch
+# User Karl Tomlinson <karlt+ at karlt.net>
+# Date 1301024339 -46800
+# Node ID 06ca0535285e66ba87940ff245b78e9c1d14d956
+# Parent  bf6532a3d889bae1d9f21d55c28729f41e69e87c
+b=576933 use a separate display to make protocol requests within X error handler r=roc
+
+diff --git a/toolkit/xre/nsX11ErrorHandler.cpp b/toolkit/xre/nsX11ErrorHandler.cpp
+--- a/toolkit/xre/nsX11ErrorHandler.cpp
++++ b/toolkit/xre/nsX11ErrorHandler.cpp
+@@ -50,56 +50,58 @@ using mozilla::plugins::PluginProcessChi
+ 
+ #include "mozilla/X11Util.h"
+ #include <X11/Xlib.h>
+ 
+ #define BUFSIZE 2048 // What Xlib uses with XGetErrorDatabaseText
+ 
+ extern "C" {
+ static int
+-IgnoreError(Display *display, XErrorEvent *event) {
+-  return 0; // This return value is ignored.
+-}
+-
+-static int
+ X11Error(Display *display, XErrorEvent *event) {
+   nsCAutoString notes;
+   char buffer[BUFSIZE];
+ 
+   // Get an indication of how long ago the request that caused the error was
+-  // made.  Do this before querying extensions etc below.
++  // made.
+   unsigned long age = NextRequest(display) - event->serial;
+ 
+-  // Ignore subsequent errors, which may get processed during the extension
+-  // queries below for example.
+-  XSetErrorHandler(IgnoreError);
+-
+   // Get a string to represent the request that caused the error.
+   nsCAutoString message;
+   if (event->request_code < 128) {
+     // Core protocol request
+     message.AppendInt(event->request_code);
+   } else {
+     // Extension request
+-    int nExts;
+-    char** extNames = XListExtensions(display, &nExts);
+-    if (extNames) {
+-      for (int i = 0; i < nExts; ++i) {
+-        int major_opcode, first_event, first_error;
+-        if (XQueryExtension(display, extNames[i],
+-                            &major_opcode, &first_event, &first_error)
+-            && major_opcode == event->request_code) {
+-          message.Append(extNames[i]);
+-          message.Append('.');
+-          message.AppendInt(event->minor_code);
+-          break;
++
++    // man XSetErrorHandler says "the error handler should not call any
++    // functions (directly or indirectly) on the display that will generate
++    // protocol requests or that will look for input events" so we use another
++    // temporary Display to request extension information.  This assumes on
++    // the DISPLAY environment variable has been set and matches what was used
++    // to open |display|.
++    Display *tmpDisplay = XOpenDisplay(NULL);
++    if (tmpDisplay) {
++      int nExts;
++      char** extNames = XListExtensions(tmpDisplay, &nExts);
++      if (extNames) {
++        for (int i = 0; i < nExts; ++i) {
++          int major_opcode, first_event, first_error;
++          if (XQueryExtension(tmpDisplay, extNames[i],
++                              &major_opcode, &first_event, &first_error)
++              && major_opcode == event->request_code) {
++            message.Append(extNames[i]);
++            message.Append('.');
++            message.AppendInt(event->minor_code);
++            break;
++          }
+         }
++
++        XFreeExtensionList(extNames);
+       }
+-
+-      XFreeExtensionList(extNames);
++      XCloseDisplay(tmpDisplay);
+     }
+   }
+ 
+   if (message.IsEmpty()) {
+     buffer[0] = '\0';
+   } else {
+     XGetErrorDatabaseText(display, "XRequest", message.get(), "",
+                           buffer, sizeof(buffer));
+
+
+# HG changeset patch
+# User Karl Tomlinson <karlt+ at karlt.net>
+# Date 1301024339 -46800
+# Node ID 286410eeba47b4b9a8ec8e18779ee10a7b312f1e
+# Parent  06ca0535285e66ba87940ff245b78e9c1d14d956
+b=576933 ignore BadDevice errors from XCloseDevice (for GDK2) r=roc
+
+diff --git a/toolkit/xre/nsX11ErrorHandler.cpp b/toolkit/xre/nsX11ErrorHandler.cpp
+--- a/toolkit/xre/nsX11ErrorHandler.cpp
++++ b/toolkit/xre/nsX11ErrorHandler.cpp
+@@ -51,19 +51,16 @@ using mozilla::plugins::PluginProcessChi
+ #include "mozilla/X11Util.h"
+ #include <X11/Xlib.h>
+ 
+ #define BUFSIZE 2048 // What Xlib uses with XGetErrorDatabaseText
+ 
+ extern "C" {
+ static int
+ X11Error(Display *display, XErrorEvent *event) {
+-  nsCAutoString notes;
+-  char buffer[BUFSIZE];
+-
+   // Get an indication of how long ago the request that caused the error was
+   // made.
+   unsigned long age = NextRequest(display) - event->serial;
+ 
+   // Get a string to represent the request that caused the error.
+   nsCAutoString message;
+   if (event->request_code < 128) {
+     // Core protocol request
+@@ -76,42 +73,56 @@ X11Error(Display *display, XErrorEvent *
+     // protocol requests or that will look for input events" so we use another
+     // temporary Display to request extension information.  This assumes on
+     // the DISPLAY environment variable has been set and matches what was used
+     // to open |display|.
+     Display *tmpDisplay = XOpenDisplay(NULL);
+     if (tmpDisplay) {
+       int nExts;
+       char** extNames = XListExtensions(tmpDisplay, &nExts);
++      int first_error;
+       if (extNames) {
+         for (int i = 0; i < nExts; ++i) {
+-          int major_opcode, first_event, first_error;
++          int major_opcode, first_event;
+           if (XQueryExtension(tmpDisplay, extNames[i],
+                               &major_opcode, &first_event, &first_error)
+               && major_opcode == event->request_code) {
+             message.Append(extNames[i]);
+             message.Append('.');
+             message.AppendInt(event->minor_code);
+             break;
+           }
+         }
+ 
+         XFreeExtensionList(extNames);
+       }
+       XCloseDisplay(tmpDisplay);
++
++#ifdef MOZ_WIDGET_GTK2
++      // GDK2 calls XCloseDevice the devices that it opened on startup, but
++      // the XI protocol no longer ensures that the devices will still exist.
++      // If they have been removed, then a BadDevice error results.  Ignore
++      // this error.
++      if (message.EqualsLiteral("XInputExtension.4") &&
++          event->error_code == first_error + 0) {
++        return 0;
++      }
++#endif
+     }
+   }
+ 
++  char buffer[BUFSIZE];
+   if (message.IsEmpty()) {
+     buffer[0] = '\0';
+   } else {
+     XGetErrorDatabaseText(display, "XRequest", message.get(), "",
+                           buffer, sizeof(buffer));
+   }
+ 
++  nsCAutoString notes;
+   if (buffer[0]) {
+     notes.Append(buffer);
+   } else {
+     notes.Append("Request ");
+     notes.AppendInt(event->request_code);
+     notes.Append('.');
+     notes.AppendInt(event->minor_code);
+   }
+
+
diff --git a/xulrunner.spec b/xulrunner.spec
index 3169d0e..80ede9e 100644
--- a/xulrunner.spec
+++ b/xulrunner.spec
@@ -87,6 +87,7 @@ Patch24:        crashreporter-remove-static.patch
 
 # Upstream patches
 Patch30:        xulrunner-omnijar.patch
+Patch31:        xulrunner-2.0-baddevice.patch
 
 # ---------------------------------------------------
 
@@ -188,6 +189,7 @@ sed -e 's/__RPM_VERSION_INTERNAL__/%{gecko_dir_ver}/' %{P:%%PATCH0} \
 %patch24 -p1 -b .static
 
 %patch30 -p1 -b .omnijar
+%patch31 -p1 -b .baddevice
 
 %{__rm} -f .mozconfig
 %{__cp} %{SOURCE10} .mozconfig


More information about the scm-commits mailing list