Xlib のエラー処理
Xプログラムが、20回前の呼び出しで送ったリクエストのエラーで突然死する理由と、XSetErrorHandler や -sync が果たす役割。
Xlib はリクエストをバッファに溜め、必要がない限り応答を待たない。そのためサーバーがリクエストを拒否したとき(すでに破棄されたウィンドウへの BadWindow、深さの違うピクスマップへの BadMatch、ほかに BadAccess、BadAlloc、BadValue など)、エラーは原因の呼び出しからかなり遅れてイベントとして届く。既定のハンドラは「X Error of failed request」の行にエラーコード、オペコード(Major opcode 20 (X_GetProperty) など)、リソースID、二つのシリアル番号を表示してプログラムを終了させる。手がかりはシリアル番号で、失敗したリクエストの番号と現在の番号の差を見れば、どれだけ遅れているかが分かる。
XSetErrorHandler を使えば独自のハンドラに差し替えられる。ほぼすべてのウィンドウマネージャがそうしているのは、クライアントがウィンドウの存在を知らせてから、マネージャが操作するまでの間にそのウィンドウを破棄しうるからだ。この競合には勝てず、無視するしかない。接続断のような別のケースは XSetIOErrorHandler が受け持つ。デバッグ時は XSynchronize か -sync で同期モードにすると、エラーが原因の呼び出しの直後に報告される。