<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>