| Summary: | Crash in st_renderbuffer_delete() | ||
|---|---|---|---|
| Product: | Mesa | Reporter: | Olivier Fourdan <fourdan> |
| Component: | Mesa core | Assignee: | mesa-dev |
| Status: | RESOLVED NOTOURBUG | QA Contact: | mesa-dev |
| Severity: | normal | ||
| Priority: | medium | ||
| Version: | unspecified | ||
| Hardware: | Other | ||
| OS: | All | ||
| Whiteboard: | |||
| i915 platform: | i915 features: | ||
| Attachments: |
Simple reproducer program
Simple reproducer program |
||
|
Description
Olivier Fourdan
2018-08-07 08:38:03 UTC
Note that I checked with both gdb/breakpoints and valgrind as well, it is not a double free or memory corruption. Important (sorry I forgot), to reproduce, it requires Ajax' patch: https://patchwork.freedesktop.org/series/47686/ (Otherwise the reproducer dies with a [xcb] “Unknown sequence number while processing queue”) Created attachment 141001 [details]
Simple reproducer program
Simpler version of the reproducer which doesn't need any patch in Mesa.
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
```
And now I suspect this might be an xserver issue, crating indirect context should fail unless enableIndirectGLX is true... `DoCreateContext()` does that but `__glXDisp_CreateContextAttribsARB()` doesn't So for the Xserver part, I posted https://patchwork.freedesktop.org/series/49182/ which will avoid the issue by not allowing the indirect conext creation, but chances are this particular issue/crash would still occur in Mesa if indirect contexts are re-enabled in the Xserver some day. Fixed accepted in xserver. Closing. |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.