[PATCH] input: change CHECKEVENT macro to verify_internal_event function

Peter Hutterer peter.hutterer at who-t.net
Wed May 4 15:48:19 PDT 2011


The macro is sufficient if called during a development cycle, but not
sufficient information when triggered by a user (e.g.
https://bugzilla.redhat.com/show_bug.cgi?id=688693).

Expand what this does to print the event content and a backtrace, so at
least we know where we're coming from. Only the first 32 bytes are printed
since if something goes wrong, the event we have is almost certainly an
xEvent or xError, both restricted to 32 bytes.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 Xi/exevents.c        |    3 ++-
 dix/events.c         |    4 ++--
 dix/inpututils.c     |   28 ++++++++++++++++++++++++++++
 include/eventstr.h   |    4 ----
 include/inpututils.h |    2 ++
 mi/mieq.c            |   10 +++++-----
 6 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 76d5c37..d48d397 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -77,6 +77,7 @@ SOFTWARE.
 #include "xiquerydevice.h" /* For List*Info */
 #include "eventconvert.h"
 #include "eventstr.h"
+#include "inpututils.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -920,7 +921,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     DeviceIntPtr mouse = NULL, kbd = NULL;
     DeviceEvent *event = &ev->device_event;
 
-    CHECKEVENT(ev);
+    verify_internal_event(ev);
 
     if (ev->any.type == ET_RawKeyPress ||
         ev->any.type == ET_RawKeyRelease ||
diff --git a/dix/events.c b/dix/events.c
index 3a90c50..feedff5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2375,7 +2375,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     xEvent *xE = NULL, *core = NULL;
     int rc, mask, count = 0;
 
-    CHECKEVENT(event);
+    verify_internal_event(event);
 
     while (pWin)
     {
@@ -2721,7 +2721,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
     WindowPtr prevSpriteWin, newSpriteWin;
     SpritePtr pSprite = pDev->spriteInfo->sprite;
 
-    CHECKEVENT(ev);
+    verify_internal_event(ev);
 
     prevSpriteWin = pSprite->win;
 
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 077ffce..aeace6e 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -36,6 +36,7 @@
 #include "xkbsrv.h"
 #include "xkbstr.h"
 #include "inpututils.h"
+#include "eventstr.h"
 
 /* Check if a button map change is okay with the device.
  * Returns -1 for BadValue, as it collides with MappingBusy. */
@@ -556,3 +557,30 @@ CountBits(const uint8_t *mask, int len)
 
     return ret;
 }
+
+/**
+ * Verifies sanity of the event. If the event is not an internal event,
+ * memdumps the first 32 bytes of event to the log, a backtrace, then kill
+ * the server.
+ */
+void verify_internal_event(const InternalEvent *ev)
+{
+    if (ev && ev->any.header != ET_Internal)
+    {
+        int i;
+        unsigned char *data = (unsigned char*)ev;
+
+        ErrorF("dix: invalid event type %d\n", ev->any.header);
+
+        for (i = 0; i < sizeof(xEvent); i++, data++)
+        {
+            ErrorF("%02hx ", *data);
+
+            if ((i % 8) == 7)
+                ErrorF("\n");
+        }
+
+        xorg_backtrace();
+        FatalError("Wrong event type %d. Aborting server\n", ev->any.header);
+    }
+}
diff --git a/include/eventstr.h b/include/eventstr.h
index 673207c..049688c 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -68,10 +68,6 @@ enum EventType {
     ET_Internal = 0xFF /* First byte */
 };
 
-#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \
-                          FatalError("Wrong event type %d.\n", \
-                                     ((InternalEvent*)(ev))->any.header);
-
 /**
  * Used for ALL input device events internal in the server until
  * copied into the matching protocol event.
diff --git a/include/inpututils.h b/include/inpututils.h
index b8ca6ab..92a7543 100644
--- a/include/inpututils.h
+++ b/include/inpututils.h
@@ -37,4 +37,6 @@ struct _ValuatorMask {
     int         valuators[MAX_VALUATORS]; /* valuator data */
 };
 
+extern void verify_internal_event(const InternalEvent *ev);
+
 #endif
diff --git a/mi/mieq.c b/mi/mieq.c
index 08a0c87..3e6f931 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -156,7 +156,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     pthread_mutex_lock(&miEventQueueMutex);
 #endif
 
-    CHECKEVENT(e);
+    verify_internal_event(e);
 
     /* avoid merging events from different devices */
     if (e->any.type == ET_Motion)
@@ -292,8 +292,8 @@ static void
 FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
                     InternalEvent* original, InternalEvent *master)
 {
-    CHECKEVENT(original);
-    CHECKEVENT(master);
+    verify_internal_event(original);
+    verify_internal_event(master);
     /* Ensure chained button mappings, i.e. that the detail field is the
      * value of the mapped button on the SD, not the physical button */
     if (original->any.type == ET_ButtonPress ||
@@ -323,7 +323,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev,
     int type = original->any.type;
     int mtype; /* which master type? */
 
-    CHECKEVENT(original);
+    verify_internal_event(original);
 
     /* ET_XQuartz has sdev == NULL */
     if (!sdev || IsMaster(sdev) || IsFloating(sdev))
@@ -376,7 +376,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
     DeviceIntPtr master;
     InternalEvent mevent; /* master event */
 
-    CHECKEVENT(event);
+    verify_internal_event(event);
 
     /* Custom event handler */
     handler = miEventQueue.handlers[event->any.type];
-- 
1.7.4.4



More information about the xorg-devel mailing list