【问题标题】:Random libx11 hangs随机 libx11 挂起
【发布时间】:2014-08-06 16:47:20
【问题描述】:

我的应用程序在调用 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 进行任何操作。但最终删除信号处理程序使问题消失了。是否有意义?或者我可以期待这个问题在未来再次出现吗?

再次感谢

【问题讨论】:

  • 你能针对原生 Xlib 而不是 XlibXcb 构建吗?
  • @n.m.我不确定如何使用 debian 软件包来做到这一点。卸载 libx11-xcb 可能会起作用,但我需要对我正在使用的其他东西的依赖
  • 我对 XlibXcb 不够熟悉,但我很确定你不需要卸载任何东西。您只需将您的应用程序与 -lX11 链接,而不是 -lx11-xcb1 或其他任何东西。这不一定有效。好吧,我几乎可以肯定它不会起作用,但它只是可能起作用,这就是我问的原因。

标签: c x11 xcb


【解决方案1】:

这可能是因为您在 SIGCHLD 处理程序中执行了您不应该执行的操作(或结果),或者因为 Xcb 未正确处理 EINTR 错误而不太可能。

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

【讨论】:

  • 感谢您的回答!如果我能很好地理解你在说什么,我认为这不是我遇到的问题。我没有看到主线程被锁定(在试图获取已经被收割线程持有的锁的意义上)。事实上,主线程成功地从管道读取并继续从服务器读取 X11 消息,但它被阻止,因为由于某种原因它错过对请求的正确回复,因此 Xlib 方法永远不会返回
  • 我刚刚注意到您说您的应用程序是单线程的,但在您的更新中您说 SIGCHLD 处理程序通知主线程,表明它正在另一个线程中运行。您是否创建了另一个线程来处理 SIGCHLD(或执行其他任何操作),或者您的应用程序是否真正是单线程的?
  • 是的,抱歉。它是单线程的,并且在 SIGCHLD 处理程序中,我正在写入非阻塞 unix 套接字。稍后当信号处理程序退出时,程序中的选择将“唤醒”并读取从信号处理程序发送的数据。我希望它对你有意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 2017-09-18
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多