same Problem here with version 2:1.10.1-2 of xserver-xorg-core. Looking at the code:
The routine DRI2DrawablePtr is obviously designed to return NULL in certain cases (At least if type is UNDRAWABLE_WINDOW). If this is supposed to be valid, it should be handled gracefully in DRI2WaitSwap, maybe like in the previous post. If not, it should error out right there and make the Application fail instead of crashing the xserver. Looking at the coredump: Since the 'hot' Varible pDrawable is optimized out, I tried to reconstruct it from the underlying stack frames: From __glXForceCurrent I got (gdb) p *(cx->drawPriv->pDraw) $9 = {type = 0 '\000', class = 1 '\001', depth = 24 '\030', bitsPerPixel = 32 ' ', id = 181, x = 0, y = 0, width = 1920, height = 1080, pScreen = 0xf61370, serialNumber = 15909060} and (gdb) p *((WindowPtr)cx->drawPriv->pDraw) $10 = {drawable = {type = 0 '\000', class = 1 '\001', depth = 24 '\030', bitsPerPixel = 32 ' ', id = 181, x = 0, y = 0, width = 1920, height = 1080, pScreen = 0xf61370, serialNumber = 15909060}, devPrivates = 0x12943f0, parent = 0x0, nextSib = 0x0, prevSib = 0x0, firstChild = 0x5e97a70, lastChild = 0x3dff8e0, clipList = {extents = {x1 = 0, y1 = 0, x2 = 0, y2 = 0}, data = 0x7e1a80}, borderClip = {extents = {x1 = 0, y1 = 0, x2 = 1920, y2 = 1080}, data = 0x0}, valdata = 0x0, winSize = {extents = {x1 = 0, y1 = 0, x2 = 1920, y2 = 1080}, data = 0x0}, borderSize = {extents = {x1 = 0, y1 = 0, x2 = 1920, y2 = 1080}, data = 0x0}, origin = {x = 0, y = 0}, borderWidth = 0, deliverableEvents = 49201, eventMask = 0, background = {pixmap = 0x0, pixel = 0}, border = {pixmap = 0x0, pixel = 0}, backStorage = 0x0, optional = 0x1294440, backgroundState = 2, borderIsPixel = 1, cursorIsNone = 0, backingStore = 0, saveUnder = 0, DIXsaveUnder = 0, bitGravity = 1, winGravity = 1, overrideRedirect = 0, visibility = 3, mapped = 1, realized = 1, viewable = 1, dontPropagate = 0, forcedBS = 0, redirectDraw = 0, forcedBG = 0, damagedDescendants = 0} This brings me to the conclusion, that pDrawable is of type DRAWABLE_WINDOW and the NULL-pointer is in fact passed on from dixLookupPrivate to DRI2WaitSwap. This in turn may have something to do with dri2WindowPrivateKey (gdb) p dri2WindowPrivateKeyRec $18 = {offset = 0, size = 0, initialized = 1, allocated = 0, type = PRIVATE_WINDOW, next = 0x0} which looks like an empty list to me. The deeply nestet logic of dixLookupPrivate shows that in this case dixGetPrivate dereferences the privates pointer before returning which seems to be the origin of the NULL-pointer: (gdb) x/16a (*((WindowPtr)cx->drawPriv->pDraw))->devPrivates 0x12943f0: 0x0 0x1292b60 0x1294400: 0x4342920 0x0 0x1294410: 0x0 0x0 0x1294420: 0x0 0x5a7bf30 0x1294430: 0x0 0x71 0x1294440: 0x2733240 0x2000000021 0x1294450: 0xfac03100000000 0x3b75c00 0x1294460: 0x43fefa0 0x42f9840 By the way, at offset 1 there seems to be a valid address (might be a coincidence). Anyone out there who can make sense out of this? Kind regards, Matthias Below is a summary of the routines i talked about: static DRI2DrawablePtr DRI2GetDrawable(DrawablePtr pDraw) { WindowPtr pWin; PixmapPtr pPixmap; switch (pDraw->type) { case DRAWABLE_WINDOW: pWin = (WindowPtr) pDraw; return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); case DRAWABLE_PIXMAP: pPixmap = (PixmapPtr) pDraw; return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); default: return NULL; } } Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) { DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); /* If we're currently waiting for a swap on this drawable, reset * the request and suspend the client. We only support one * blocked client per drawable. */ if ((pPriv->swapsPending) && pPriv->blockedClient == NULL) { ResetCurrentRequest(client); client->sequence--; __DRI2BlockClient(client, pPriv); return TRUE; } return FALSE; } static inline pointer dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key) { if (key->size) return dixGetPrivateAddr(privates, key); else return dixGetPrivate(privates, key); } static inline void * dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key) { assert(key->initialized); return (char *) (*privates) + key->offset; } static inline void * dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key) { assert (key->size == 0); return *(void **) dixGetPrivateAddr(privates, key); } -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org