XIO:由 32 位 libxcb 引起的致命 IO 错误 11
Posted
技术标签:
【中文标题】XIO:由 32 位 libxcb 引起的致命 IO 错误 11【英文标题】:XIO: fatal IO error 11 caused by 32-bit libxcb 【发布时间】:2014-11-05 14:32:27 【问题描述】:是的,这个问题以前有人问过,但是看了答案并没有给我太多启发。
我写了一个使用几天后崩溃的 C 程序。重要的一点是它不会生成核心文件,即使一切都已设置好(core_pattern、ulimit -c 无限制等。我可以使用 kill -SIGQUIT 触发核心转储)。
这些程序会广泛记录它所做的事情,但日志中没有关于崩溃的提示。 崩溃时(或之前?)显示的唯一消息是:
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 2322 requests (2322 known processed) with 0 events remaining.
所以有两个问题: - 如果没有核心转储,程序怎么可能崩溃(返回 $?=1)。 - 这个错误信息是关于什么的,我该怎么办?
系统是 RedHat Enterprise 6.4
编辑: 我设法通过在 atexit() 回调中调用 abort() 来强制执行核心转储:
(gdb) bt
#0 0x00bc8424 in __kernel_vsyscall ()
#1 0x0085a861 in raise () from /lib/libc.so.6
#2 0x0085c13a in abort () from /lib/libc.so.6
#3 0x0808f5cf in Unexpected () at MyCode.c:1378
#4 0x0085de9f in exit () from /lib/libc.so.6
#5 0x00c85701 in _XDefaultIOError () from /usr/lib/libX11.so.6
#6 0x00c85797 in _XIOError () from /usr/lib/libX11.so.6
#7 0x00c84055 in _XReply () from /usr/lib/libX11.so.6
#8 0x00c68b8f in XGetImage () from /usr/lib/libX11.so.6
#9 0x004fd6a7 in ?? () from /usr/local/lib/libcvi.so
#10 0x00478ad5 in ?? () from /usr/local/lib/libcvi.so
...
#29 0x001eed9d in ?? () from /usr/local/lib/libcvi.so
#30 0x001eee41 in RunUserInterface () from /usr/local/lib/libcvi.so
#31 0x0808fab4 in main (argc=2, argv=0xbfbdc984) at MyCode.c:1540
任何人都可以告诉我这个 X11 问题吗? libcvi.so 不是我的,只有 MyCode.c (LabWindows/CVI)。
编辑 2014-12-05: 这是一个更精确的回溯。事情肯定发生在 X11 中,但我不是 X11 程序员,所以从提供的行中查看 X 的源代码只告诉我 X 服务器(?)暂时不可用。如果它只是暂时的,有什么方法可以简单地告诉它忽略这个错误?
#4 0x00965eaf in __run_exit_handlers (status=1) at exit.c:78
#5 exit (status=1) at exit.c:100
#6 0x00c356b1 in _XDefaultIOError (dpy=0x88aeb80) at XlibInt.c:1292
#7 0x00c35747 in _XIOError (dpy=0x88aeb80) at XlibInt.c:1498
#8 0x00c340a6 in _XReply (dpy=0x88aeb80, rep=0xbf82fa90, extra=0, discard=0) at xcb_io.c:708
#9 0x00c18c0f in XGetImage (dpy=0x88aeb80, d=27263845, x=0, y=0, width=60, height=20, plane_mask=4294967295, format=2) at GetImage.c:75
#10 0x005f46a7 in ?? () from /usr/local/lib/libcvi.so
对应行:
XlibInt.c: _XDefaultIOError()
1292: exit(1);
XlibInt.c: _XIOError
1498: _XDefaultIOError(dpy);
xcb_io.c: _XReply()
708: if(!reply) _XIOError(dpy);
GetImage.c: XGetImage()
74: if (_XReply (dpy, (xReply *) &rep, 0, xFalse) == 0 || ...
【问题讨论】:
您的程序可能会泄漏描述符。运行一段时间后查看其/proc/<pid>/fd
目录;你看到那里的链接数量增加了吗?
它通常需要几天才能崩溃,但我会监控情况。一些谷歌搜索让我相信这是与我的应用程序无关的 Xinerama/NVidia 多显示器问题。
删除 Xinerama 没有帮助。如果没有核心转储,我仍然会遇到那些崩溃。我可以用什么工具来追踪它?
我刚刚在原帖中添加了回溯
不,还没有解决方案。您是否在 CVI 或其他系统中遇到此问题?我想知道更多。
【参考方案1】:
好的,我终于找到了原因(感谢 National Instruments 的某个人)、更好的诊断方法和解决方法。
该错误存在于许多版本的 libxcb 中,并且是已知数年的 32 位计数器翻转问题:https://bugs.freedesktop.org/show_bug.cgi?id=71338
并非所有版本的 libxcb 都会受到影响,libxcb-1.9-5 有,libxcb-1.5-1 没有。从 bug 列表来看,64 位操作系统应该不会受到影响,但我设法在至少一个版本上触发了它。
这让我得到了更好的诊断。以下程序将在 15 分钟内在受影响的库上崩溃(比之前花费的整整一周时间要好):
// Compile with: gcc test.c -lX11 && time ./a.out
#include <X11/Xlib.h>
void main(void)
Display *d = XOpenDisplay(NULL);
if (d)
for(;;)
XNoOp(d);
最后一件事,上面的 prog 在 64 位系统上编译和运行可以正常工作,在旧的 32 位系统上编译和运行也可以正常工作,但是如果我将 32 位版本转移到 64-位系统,几分钟后崩溃。
【讨论】:
【参考方案2】:我刚刚有一个程序与此完全一样,并带有完全相同的错误消息。我希望计数器错误在崩溃之前处理 2^32 个事件。
程序的结构使得工作线程与 X 线程有一个单独的 X 连接,以便它可以向 X 线程发送消息以更新窗口。
最后,我将问题追溯到一个地方,其中将事件发送到窗口以重绘它的函数被多个线程调用,没有互斥体,并且由于 X 到同一个 X 连接不会重新进入者,因这个确切的错误而崩溃。在该函数上放置一个互斥体,此后没有问题。
【讨论】:
以上是关于XIO:由 32 位 libxcb 引起的致命 IO 错误 11的主要内容,如果未能解决你的问题,请参考以下文章
此错误是由运行在 32 位 JVM 中的 Java 程序访问的 64 位库引起的吗?
AppCertDlls:由病毒引起的 Win32 上的进程创建速度减慢
解决在linux下编译32程序出现“/usr/include/gnu/stubs.h:7:27: 致命错误:gnu/stubs-32.h:没有那个文件或目录问题”