3

libX11関数を呼び出すと、アプリケーションがランダムにハングします。例: を呼び出したりXGetClassHint、返さないことがあります。XGetWindowPropertyXListInputDevices

たとえば、これは呼び出し時のバックトレースです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 応答を処理しなかったため、サーバーから返されないようです。

私が使用している OS は標準の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 で操作を行っていませんでした。しかし、最終的にシグナルハンドラを削除すると、問題は解消されました。それは理にかなっていますか?または、この問題が今後再び発生する可能性はありますか?

再度、感謝します

4

1 に答える 1

0

これは、SIGCHLDハンドラーで (またはその結果として) 想定されていないことを行っているか、Xcb がEINTRエラーを正しく処理していない可能性が低いためです。

私の推測では、SIGCHLDXcb への呼び出しの最中にスレッド (リーパー スレッドと呼びます) に配信されます。次に、ハンドラーはパイプに書き込みますが、パイプ バッファーがいっぱいであるため、パイプはブロックされます。リーパー スレッドは、パイプが排出されるのを待っている間、Xcb ロックを保持しています。次に、パイプを読み取るはずのメイン スレッドが Xcb を呼び出し、リーパー スレッドが保持しているロックを取得しようとします。メイン スレッドがパイプを読み取るのを待ってリーパー スレッドがブロックされ、リーパー スレッドが Xcb ロックを解放するのを待ってメイン スレッドがブロックされるため、デッドロックが発生します。

于 2014-08-12T16:48:22.283 に答える