input: change CHECKEVENT macro to verify_internal_event function

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@who-t.net>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
This commit is contained in:
Peter Hutterer 2011-05-05 08:48:19 +10:00
parent bf2059b07a
commit 5690199802
6 changed files with 39 additions and 12 deletions

View File

@ -77,6 +77,7 @@ SOFTWARE.
#include "xiquerydevice.h" /* For List*Info */ #include "xiquerydevice.h" /* For List*Info */
#include "eventconvert.h" #include "eventconvert.h"
#include "eventstr.h" #include "eventstr.h"
#include "inpututils.h"
#include <X11/extensions/XKBproto.h> #include <X11/extensions/XKBproto.h>
#include "xkbsrv.h" #include "xkbsrv.h"
@ -920,7 +921,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
DeviceIntPtr mouse = NULL, kbd = NULL; DeviceIntPtr mouse = NULL, kbd = NULL;
DeviceEvent *event = &ev->device_event; DeviceEvent *event = &ev->device_event;
CHECKEVENT(ev); verify_internal_event(ev);
if (ev->any.type == ET_RawKeyPress || if (ev->any.type == ET_RawKeyPress ||
ev->any.type == ET_RawKeyRelease || ev->any.type == ET_RawKeyRelease ||

View File

@ -2377,7 +2377,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
xEvent *xE = NULL, *core = NULL; xEvent *xE = NULL, *core = NULL;
int rc, mask, count = 0; int rc, mask, count = 0;
CHECKEVENT(event); verify_internal_event(event);
while (pWin) while (pWin)
{ {
@ -2723,7 +2723,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
WindowPtr prevSpriteWin, newSpriteWin; WindowPtr prevSpriteWin, newSpriteWin;
SpritePtr pSprite = pDev->spriteInfo->sprite; SpritePtr pSprite = pDev->spriteInfo->sprite;
CHECKEVENT(ev); verify_internal_event(ev);
prevSpriteWin = pSprite->win; prevSpriteWin = pSprite->win;

View File

@ -36,6 +36,7 @@
#include "xkbsrv.h" #include "xkbsrv.h"
#include "xkbstr.h" #include "xkbstr.h"
#include "inpututils.h" #include "inpututils.h"
#include "eventstr.h"
/* Check if a button map change is okay with the device. /* Check if a button map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy. */ * Returns -1 for BadValue, as it collides with MappingBusy. */
@ -556,3 +557,30 @@ CountBits(const uint8_t *mask, int len)
return ret; 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);
}
}

View File

@ -68,10 +68,6 @@ enum EventType {
ET_Internal = 0xFF /* First byte */ 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 * Used for ALL input device events internal in the server until
* copied into the matching protocol event. * copied into the matching protocol event.

View File

@ -37,4 +37,6 @@ struct _ValuatorMask {
int valuators[MAX_VALUATORS]; /* valuator data */ int valuators[MAX_VALUATORS]; /* valuator data */
}; };
extern void verify_internal_event(const InternalEvent *ev);
#endif #endif

View File

@ -156,7 +156,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
pthread_mutex_lock(&miEventQueueMutex); pthread_mutex_lock(&miEventQueueMutex);
#endif #endif
CHECKEVENT(e); verify_internal_event(e);
/* avoid merging events from different devices */ /* avoid merging events from different devices */
if (e->any.type == ET_Motion) if (e->any.type == ET_Motion)
@ -292,8 +292,8 @@ static void
FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
InternalEvent* original, InternalEvent *master) InternalEvent* original, InternalEvent *master)
{ {
CHECKEVENT(original); verify_internal_event(original);
CHECKEVENT(master); verify_internal_event(master);
/* Ensure chained button mappings, i.e. that the detail field is the /* Ensure chained button mappings, i.e. that the detail field is the
* value of the mapped button on the SD, not the physical button */ * value of the mapped button on the SD, not the physical button */
if (original->any.type == ET_ButtonPress || if (original->any.type == ET_ButtonPress ||
@ -323,7 +323,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev,
int type = original->any.type; int type = original->any.type;
int mtype; /* which master type? */ int mtype; /* which master type? */
CHECKEVENT(original); verify_internal_event(original);
/* ET_XQuartz has sdev == NULL */ /* ET_XQuartz has sdev == NULL */
if (!sdev || IsMaster(sdev) || IsFloating(sdev)) if (!sdev || IsMaster(sdev) || IsFloating(sdev))
@ -376,7 +376,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
DeviceIntPtr master; DeviceIntPtr master;
InternalEvent mevent; /* master event */ InternalEvent mevent; /* master event */
CHECKEVENT(event); verify_internal_event(event);
/* Custom event handler */ /* Custom event handler */
handler = miEventQueue.handlers[event->any.type]; handler = miEventQueue.handlers[event->any.type];