随机libx11挂起

时间:2014-08-06 16:47:20

标签: c x11 xcb

在调用 libX11 函数时,我的应用程序随机挂起。例如:调用XGetClassHintXGetWindowPropertyXListInputDevices有时不会返回。

例如,这是调用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消息,并且我收到了请求WM_CLASS的GetProperty的回复:

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 squeeze ,相关的软件包是:

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 个答案:

答案 0 :(得分:0)

可能是因为你在SIGCHLD处理程序(或作为结果)中做了一些你不应该或不太可能的事情,因为Xcb没有处理EINTR错误正确。

我的猜测是SIGCHLD被传递给一个线程(我称之为收割者线程),而它正在调用Xcb。然后处理程序写入管道,管道因为管道缓冲区已满而阻塞。收割者线程现在在等待管道排水时持有Xcb锁。应该读取管道的主线程然后调用Xcb,它试图获取收割者线程持有的锁。由于收割者线程被阻塞,等待主线程读取管道并且主线程被阻塞等待收割者线程释放Xcb锁,你会遇到死锁。