Случайные зависания libx11

Мое приложение случайно зависает при вызове функций libX11. Например: звонок XGetClassHint, XGetWindowProperty или же XListInputDevices иногда не возвращаются.

Например, вот обратная трассировка при звонке XGetClassHint

#0  0xb70a762c in poll () from /lib/libc.so.6
#1  0xb6f980f0 in _xcb_conn_wait (c=0x9d66a20, cond=0xbf98c600, vector=0x0, count=0x0) at ../../src/xcb_conn.c:316
#2  0xb6f9a7e1 in xcb_wait_for_reply (c=0x9d66a20, request=178, e=0xbf98c68c) at ../../src/xcb_in.c:395
#3  0xb7597746 in _XReply (dpy=0x9d660d8, rep=0xbf98c6f0, extra=0, discard=0) at ../../src/xcb_io.c:462
#4  0xb75750a0 in XGetWindowProperty (dpy=0x9d660d8, w=31457802, property=67, offset=0, length=8192, delete=0, req_type=31, actual_type=0xbf98c78c, actual_format=0xbf98c788, nitems=0xbf98c784, bytesafter=0xbf98c780, prop=0xbf98c77c) at ../../src/GetProp.c:70
#5  0xb7573f51 in XGetClassHint (dpy=0x9d660d8, w=31457802, classhint=0xbf98c83c) at ../../src/GetHints.c:312
#6  0x080ccfac in WindowManager::get_class (this=0x8144460, window=@0xbf98c814, clase=0xbf98c83c) at src/WindowManager.cpp:1334

Я проследил сообщения X11 между моим приложением и сервером, и я получил ответ на запрос GetProperty WM_CLASS:

001:<:00b2: 24: Request(20): GetProperty delete=false(0x00) window=0x01e0020a property=0x43("WM_CLASS") type=0x1f("STRING") long-offset=0x00000000 long-length=0x00002000
001:>:00b2:52: Reply to GetProperty: type=0x1f("STRING") bytes-after=0x00000000 data='Navigator\000Iceweasel\000'

Мое приложение однопоточное, и я вижу, что оно все еще получает и обрабатывает сообщения X11 с сервера, но похоже, что оно никогда не возвращается из XGetClassHint потому что по какой-то причине не обработал ответ GetProperty.

Операционная система, которую я использую, является стандартной версией Debian, и соответствующие пакеты:

ii  libx11-6                                            2:1.3.3-4+squeeze1               X11 client-side library
ii  libx11-6-dbg                                        2:1.3.3-4+squeeze1               X11 client-side library (debug package)
ii  libx11-data                                         2:1.3.3-4+squeeze1               X11 client-side library
ii  libx11-dev                                          2:1.3.3-4+squeeze1               X11 client-side library (development headers)
ii  libx11-xcb1                                         2:1.3.3-4+squeeze1               Xlib/XCB interface library
ii  libx11-xcb1-dbg                                     2:1.3.3-4+squeeze1               Xlib/XCB interface library (debug package)
ii  libxcb1                                             1.6-1+squeeze1                   X C Binding
ii  libxcb1-dbg                                         1.6-1+squeeze1                   X C Binding, debugging symbols
ii  libxcb1-dev                                         1.6-1+squeeze1                   X C Binding, development files

Есть идеи, что может быть причиной этого?

Спасибо!

Обновить

После некоторой дополнительной отладки кажется, что эта проблема возникала, когда программа обрабатывала SIGCHLD. В обработчике сигналов я просто писал в канал, чтобы уведомить основной поток, но не делал никаких операций с libX11. Но в итоге удаление обработчика сигнала заставило проблему исчезнуть. Имеет ли это смысл? или я могу ожидать, что эта проблема появится снова в будущем?

еще раз спасибо

1 ответ

Это может быть либо потому, что вы делаете что-то в SIGCHLD обработчик (или как результат), который вы не должны или менее вероятно, потому что Xcb не обрабатывает EINTR ошибка правильно.

Я думаю, что SIGCHLD доставляется в поток (который я назову потоком жнеца), пока он находится в середине вызова Xcb. Затем обработчик выполняет запись в канал, который блокируется, поскольку буфер канала заполнен. Нить жнеца теперь держит замок Xcb, ожидая, когда труба истечет. Основной поток, который должен читать канал, затем вызывает Xcb, который пытается получить блокировку, которую удерживает поток жнеца. Поскольку нить жнеца заблокирована, ожидая, пока основной поток прочитает трубу, а основная нить заблокирована, ожидая, пока нить жнеца освободит блокировку Xcb, вы получите тупик.

Другие вопросы по тегам