Some Unity games fail assertion on startup in glXCreateContextAttribsARB
Submitted by Nicholas Miell
Assigned to Hal Gentz
Multiple Unity games die during startup due to an assertion failure in glXCreateContextAttribsARB.
The assertion in question is "Unknown sequence number while processing queue" in poll_for_event() in libX11's src/xcb_io.c. I'm blaming Mesa for now because you've got to start somewhere and some of the other potential culprits (Xlib, XCB) also live in this Bugzilla.
Affected games include: Oxenfree, The Fall.
The stack trace looks like:
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:58 #1 0x00007ffff61b051a in __GI_abort () at abort.c:89 #2 0x00007ffff61a6da7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x7ffff72b0778 "!xcb_xlib_threads_sequence_lost", file=file@entry=0x7ffff72b05eb "xcb_io.c", line=line@entry=259, function=function@entry=0x7ffff72b0a28 <__PRETTY_FUNCTION__.14787> "poll_for_event") at assert.c:92 #3 0x00007ffff61a6e52 in __GI___assert_fail (assertion=assertion@entry=0x7ffff72b0778 "!xcb_xlib_threads_sequence_lost", file=file@entry=0x7ffff72b05eb "xcb_io.c", line=line@entry=259, function=function@entry=0x7ffff72b0a28 <__PRETTY_FUNCTION__.14787> "poll_for_event") at assert.c:101 #4 0x00007ffff723e32a in poll_for_event (dpy=dpy@entry=0x21ca160) at xcb_io.c:256 #5 0x00007ffff723e3db in poll_for_response (dpy=dpy@entry=0x21ca160) at xcb_io.c:274 #6 0x00007ffff723e6cd in _XEventsQueued (dpy=0x21ca160, mode=<optimized out>) at xcb_io.c:349 #7 0x00007ffff7241515 in _XGetRequest (dpy=0x21ca160, type=<optimized out>, len=4) at XlibInt.c:1707 #8 0x00007ffff724162f in _XSeqSyncFunction (dpy=0x21ca160) at XlibInt.c:202 #9 0x00007ffff7240df3 in _XError (dpy=dpy@entry=0x21ca160, rep=rep@entry=0x7fffffffd3e0) at XlibInt.c:1436 #10 0x00007ffff75591a2 in __glXSendErrorForXcb (dpy=dpy@entry=0x21ca160, err=err@entry=0x304bd30) at glx_error.c:81 #11 0x00007ffff7555284 in glXCreateContextAttribsARB (dpy=0x21ca160, config=0x22b3a20, share_context=0x220c3c0, direct=<optimized out>, attrib_list=0x7fffffffd4a0) at create_context.c:119 #12 0x0000000000eac13f in ?? () #13 0x0000000000eace22 in ?? () #14 0x00000000004654a4 in ?? () #15 0x00007ffff6199401 in __libc_start_main (main=0x4641e0, argc=1, argv=0x7fffffffdde8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffddd8) at ../csu/libc-start.c:289
This appears to be timing-dependent or a race condition because the games will sometimes successfully start (e.g. the first time run after booting or after dropping the entire VFS cache), and will definitely start if you've set a breakpoint somewhere that triggers at least once per call to glXCreateContextAttribsARB.
As best as I can tell (by setting 4000 breakpoints in gdb using rbreak), Unity does correctly call XInitThreads() before using Xlib or GLX or creating any threads and only ever makes Xlib & GLX calls on thread 1 anyway. Which suggests the race is between the game client and the X server, assuming it is a race. This makes me wonder about the 32/64 sequence number widening in Xlib/XCB which I do not understand at all. When the assertion fails, event_sequence is something like 4294967378 (i.e. 2^32 + 82) while request is 84.
I've written a little LD_PRELOAD shim that calls usleep() in glXCreateContextAttribsARB which makes the games completely playable.