[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: 4.3.0-0pre1v1 Sig11 crash with Radeon 7500/Quake3



On Thu, Aug 28, 2003 at 10:47:41AM -0400, Brian Almeida wrote:
> On Thursday 28 August 2003 08:07 am, Brian Almeida wrote:
> > [Please CC me as I am not subscribed to debian-x]
> I got some more info by install xserver-xfree86-dbg and getting
> a backtrace:
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x08649121 in __glXCreateDrawablePrivate (pDraw=0x8bd7f80, drawId=2097154,
>     modes=0x0) at glxutil.c:334
> 334     glxutil.c: No such file or directory.
>         in glxutil.c
> (gdb) bt
> #0  0x08649121 in __glXCreateDrawablePrivate (pDraw=0x8bd7f80, drawId=2097154,
>     modes=0x0) at glxutil.c:334
> #1  0x086493c3 in __glXGetDrawablePrivate (pDraw=0x8bd7f80, drawId=2097154,
>     modes=0x0) at glxutil.c:426
> #2  0x0866a032 in __glXMakeCurrent (cl=0x8bcfd50, pc=0x8bd03e0 "\232\005\004")
>     at glxcmds.c:484
> #3  0x08648607 in __glXDispatch (client=0x8bd01a8) at glxext.c:431
> #4  0x0845acc1 in Dispatch () at dispatch.c:450
> #5  0x084708b7 in main (argc=1, argv=0xbffffaf4, envp=0xbffffafc) at main.c:469

Bad client data?  The GLX extension is assuming that this "modes" thing
is a valid pointer.  __glXCreateDrawablePrivate() is fed bullshit which
it gets from __glXGetDrawablePrivate(), which intern gets a pointer to a
structure that should be populated correctly by __glXMakeCurrent().

glxcmds.c:
    360 /*****************************************************************************/
    361 /*
    362 ** Make an OpenGL context and drawable current.
    363 */
    364 int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
    365 {
    366     ClientPtr client = cl->client;
    367     DrawablePtr pDraw;
    368     xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
    369     xGLXMakeCurrentReply reply;
    370     GLXDrawable drawId = req->drawable;
    371     GLXContextID contextId = req->context;
    372     __GLXpixmap *pGlxPixmap = 0;
    373     __GLXcontext *glxc, *prevglxc;
                         ^^^^^ Here's the guy that goes to hell.
    374     __GLinterface *gc, *prevgc;
    375     __GLXdrawablePrivate *glxPriv = NULL;
    376     GLXContextTag tag = req->oldContextTag;
    377     GLint error;
 [...]
    409     /*
    410     ** Lookup new context.  It must not be current for someone else.
    411     */
    412     if (contextId != None) {
    413         glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes);
    414         if (!glxc) {
    415             client->errorValue = contextId;
    416             return __glXBadContext;
    417         }
    418         if ((glxc != prevglxc) && glxc->isCurrent) {
    419             /* Context is current to somebody else */
    420             return BadAccess;
    421         }
    422         gc = glxc->gc;
    423     } else {
    424         /* Switching to no context.  Ignore new drawable. */
    425         glxc = 0;
    426         gc = 0;
    427     }

 The above if block is what initializes glxc.

 The drawable then undergoes some auditing.

    429     if (drawId != None) {
    430         pDraw = (DrawablePtr) LookupDrawable(drawId, client);
    431         if (pDraw) {
    432             if (pDraw->type == DRAWABLE_WINDOW) {
    433                 /*
    434                 ** Drawable is an X Window.
    435                 */
    436                 WindowPtr pWin = (WindowPtr)pDraw;
    437                 VisualID vid = wVisual(pWin);
    438 
    439                 /*
    440                 ** Check if window and context are similar.
    441                 */
    442                 if ((vid != glxc->pVisual->vid) ||
    443                     (pWin->drawable.pScreen != glxc->pScreen)) {
    444                     client->errorValue = drawId;
    445                     return BadMatch;
    446                 }
    447 
    448             } else {
    449                 /*
    450                 ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
    451                 ** is, but it must first be created with glxCreateGLXPixmap).
    452                 */
    453                 client->errorValue = drawId;
    454                 return __glXBadDrawable;
    455             }
    456         } else {
    457             pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
    458                                                         __glXPixmapRes);
    459             if (pGlxPixmap) {
    460                 /*
    461                 ** Check if pixmap and context are similar.
    462                 */
    463                 if (pGlxPixmap->pScreen != glxc->pScreen ||
    464                     pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
    465                     client->errorValue = drawId;
    466                     return BadMatch;
    467                 }
    468                 pDraw = pGlxPixmap->pDraw;
    469 
    470             } else {
    471                 /*
    472                 ** Drawable is neither a Window nor a GLXPixmap.
    473                 */
    474                 client->errorValue = drawId;
    475                 return __glXBadDrawable;
    476             }
    477         }
    478     } else {
    479         pDraw = 0;
    480     }
    481
    482     /* get the drawable private */
    483     if (pDraw) {

 This is our last chance to audit glxc->modes before we pass it along.
 Presumably we should have scrutinized glxc->modes above, but I don't
 know what the spec says we should do for client->errorValue and the
 return value.

    484         glxPriv = __glXGetDrawablePrivate(pDraw, drawId, glxc->modes);
    485         if (glxPriv == NULL) {
    486             return __glXBadDrawable;
    487         }
    488     }

glxutil.c:
    417 __GLXdrawablePrivate *
    418 __glXGetDrawablePrivate(DrawablePtr pDraw, XID drawId,
    419                         __GLcontextModes *modes)
    420 {
    421     __GLXdrawablePrivate *glxPriv;
    422 
    423     glxPriv = __glXFindDrawablePrivate(drawId);
    424 
    425     if (glxPriv == NULL) {
    426         glxPriv = __glXCreateDrawablePrivate(pDraw, drawId, modes);
    427         if (glxPriv) {
    428             __glXRefDrawablePrivate(glxPriv);
    429         }
    430     }
    431     
    432     return glxPriv;
    433 }

    306 __GLXdrawablePrivate *
    307 __glXCreateDrawablePrivate(DrawablePtr pDraw, XID drawId,
    308                            __GLcontextModes *modes)
    309 {
    310     __GLXdrawablePrivate *glxPriv;
    311     __GLdrawablePrivate *glPriv;
    312     __GLXscreenInfo *pGlxScreen;
    313 
    314     glxPriv = (__GLXdrawablePrivate *) __glXMalloc(sizeof(*glxPriv));
    315     __glXMemset(glxPriv, 0, sizeof(__GLXdrawablePrivate));
    316 
    317     glxPriv->type = pDraw->type;
    318     glxPriv->pDraw = pDraw;
    319     glxPriv->drawId = drawId;
    320 
    321     /* if not a pixmap, lookup will fail, so pGlxPixmap will be NULL */
    322     glxPriv->pGlxPixmap = (__GLXpixmap *)
    323         LookupIDByType(drawId, __glXPixmapRes);
    324     /* since we are creating the drawablePrivate, drawId should be new */
    325     if (!AddResource(drawId, __glXDrawableRes, glxPriv)) {
    326         /* oops! */
    327         __glXFree(glxPriv);
    328         return NULL;
    329     }
    330 
    331     /* fill up glPriv */
    332     glPriv = &glxPriv->glPriv;
    333     glPriv->modes = (__GLcontextModes *) __glXMalloc(sizeof(__GLcontextModes));
    334     *glPriv->modes = *modes;

Boom.  modes is a null pointer.

Someone knowledgeable about GLX know what to do about this?

-- 
G. Branden Robinson                |    The errors of great men are
Debian GNU/Linux                   |    venerable because they are more
branden@debian.org                 |    fruitful than the truths of little
http://people.debian.org/~branden/ |    men.         -- Friedrich Nietzsche

Attachment: pgp6wYcqJjmIR.pgp
Description: PGP signature


Reply to: