http://bugs.winehq.org/show_bug.cgi?id=31882
--- Comment #54 from Ken Thomases ken@codeweavers.com 2012-10-28 14:57:35 CDT --- (In reply to comment #48)
I looked at this a bit, and what seems to be happening is that the application ends up calling TerminateThread() -> ... -> pthread_exit() while the thread that gets terminated is inside x11drv_surface_flush() -> XSync() -> ... -> wait_for_reply() -> _xcb_conn_wait(). Then, when a different thread accesses the xcb reader list in _xcb_in_wake_up_next_reader(), the reader entry for the thread that was terminated now points to freed memory, which explains the pthread_cond_signal() call in there either blocking or crashing. There seems to be a somewhat similar issue if a thread gets terminated while holding the "c->iolock" mutex inside libxcb.
Hmm. pthread_exit() is a means for a thread to terminate itself, not some arbitrary thread. So, how can a thread call that if it's blocked inside of libX11 or libxcb? The only mechanism I can see is from the wineserver's kill_thread() sending SIGQUIT, causing (inside of ntdll) quit_handler() -> abort_thread() -> terminate_thread() -> pthread_exit().
Is that what's happening?
I don't blame libxcb for failing to properly handle the case where a thread is unceremoniously terminated while within it. It seems the Wine bug is that it needs to protect the libraries it uses -- at least libX11/libxcb -- from that sort of abrupt termination, I guess using signal handlers. (Although such protection may be both impractical and would prevent proper termination of threads while they're blocked in library calls.)