<html>
    <head>
      <base href="https://bugs.freedesktop.org/">
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Crash in st_renderbuffer_delete()"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=107508#c4">Comment # 4</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Crash in st_renderbuffer_delete()"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=107508">bug 107508</a>
              from <span class="vcard"><a class="email" href="mailto:fourdan@xfce.org" title="Olivier Fourdan <fourdan@xfce.org>"> <span class="fn">Olivier Fourdan</span></a>
</span></b>
        <pre>Humm, back to this...

Some more observations:

1. The issue does not occur with direct context
2. The issue does not occur if the reproducer does _not_ call
`glXMakeCurrent(display, 0, 0)` prior to `glXDestroyContext(display, ctx)`

The reason for #2 is because `ContextGone()` in xserver/glx/glxext.c only call
`__glXFreeContext()` if `cx->currentClient` is true:

```
 76 ContextGone(__GLXcontext * cx, XID id)
 77 {
 78     if (!cx)
 79         return TRUE;
 80 
 81     if (!cx->currentClient)
 82         __glXFreeContext(cx);
 83 
 84     return TRUE;
 85 }
 86 
```

So in gdb I added a breakpoint in `__glXFreeContext()` and ran the reproducer
with a direct and an indirect context, to see the difference, which gives:

A. With a `direct` context:

Thread 1 "Xwayland" hit Breakpoint 1, __glXFreeContext (cx=0x2acf000) at
glxext.c:173
173         if (cx->idExists || cx->currentClient)
(gdb) p *cx
$1 = {destroy = 0x4faf10 <__glXdirectContextDestroy>, makeCurrent = 0x0,
loseCurrent = 0x4faf00 <__glXdirectContextLoseCurrent>, copy = 0x0, 
  wait = 0x0, bindTexImage = 0x0, releaseTexImage = 0x0, next = 0x0, config =
0x2776c90, pGlxScreen = 0x272fb60, currentClient = 0x0, 
  id = 4194308, share_id = 0, idExists = 0 '\000', isDirect = 1 '\001',
renderMode = 7168, resetNotificationStrategy = 33377, 
  releaseBehavior = 0, feedbackBuf = 0x0, feedbackBufSize = 0, selectBuf = 0x0,
selectBufSize = 0, largeCmdBytesSoFar = 0, 
  largeCmdBytesTotal = 0, largeCmdRequestsSoFar = 0, largeCmdRequestsTotal = 0,
largeCmdBuf = 0x0, largeCmdBufSize = 0, drawPriv = 0x0, 
  readPriv = 0x0}


B. With an `indirect` context:

(gdb) p *cx
$2 = {destroy = 0x4f8a60 <__glXDRIcontextDestroy>, makeCurrent = 0x4f8680
<__glXDRIcontextMakeCurrent>, 
  loseCurrent = 0x4f86b0 <__glXDRIcontextLoseCurrent>, copy = 0x4f86d0
<__glXDRIcontextCopy>, wait = 0x0, 
  bindTexImage = 0x4f86f0 <__glXDRIbindTexImage>, releaseTexImage = 0x4f8750
<__glXDRIreleaseTexImage>, next = 0x0, config = 0x2776c90, 
  pGlxScreen = 0x272fb60, currentClient = 0x0, id = 4194308, share_id = 0,
idExists = 0 '\000', isDirect = 0 '\000', renderMode = 7168, 
  resetNotificationStrategy = 33377, releaseBehavior = 0, feedbackBuf = 0x0,
feedbackBufSize = 0, selectBuf = 0x0, selectBufSize = 0, 
  largeCmdBytesSoFar = 0, largeCmdBytesTotal = 0, largeCmdRequestsSoFar = 0,
largeCmdRequestsTotal = 0, largeCmdBuf = 0x0, largeCmdBufSize = 0, 
  drawPriv = 0x0, readPriv = 0x0}

So the indirect context calls __glXDRIcontextDestroy() from swrast:

(gdb) list *cx->destroy
0x4f8a60 is in __glXDRIcontextDestroy (glxdriswrast.c:132).
127     __glXDRIcontextDestroy(__GLXcontext * baseContext)
128     {
129         __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
130         __GLXDRIscreen *screen = (__GLXDRIscreen *)
context->base.pGlxScreen;
131     
132         (*screen->core->destroyContext) (context->driContext);
133         __glXContextDestroy(&context->base);
134         free(context);
135     }
136

The reason for this is `__glXDisp_CreateContextAttribsARB()` from
xserver/glx/createcontext.c which does:

```
317      */
318     if (req->isDirect) {
319         ctx = __glXdirectContextCreate(glxScreen, config, shareCtx);
320         err = BadAlloc;
321     }
322     else {
323         ctx = glxScreen->createContext(glxScreen, config, shareCtx,
324                                        req->numAttribs, (uint32_t *)
attribs,
325                                        &err);
326     }
327 
```</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the assignee for the bug.</li>
          <li>You are the QA Contact for the bug.</li>
      </ul>
    </body>
</html>