如果忽略X11 BadWindow错误会怎样?

时间:2014-01-01 17:34:59

标签: linux error-handling x11 aix motif

我有一个20世纪90年代早期写的遗留Motif应用程序(我无法在QT中重写UI,甚至无需经过耗时的安全评估即可广泛修改应用程序)。这个应用程序曾经在AIX上运行,在密集使用下运行了几个星期并且稳定了。我们现在已将其移植到Linux。在长时间持续的Beta测试期间,应用程序每周都会崩溃一次,并发出以下消息。

  

请求失败的错误:BadWindow(Window参数无效)
    失败请求的主要操作码:4(X_DestroyWindow)

我已经了解到可以使用自定义X11错误处理程序(默认的X11错误处理程序只打印错误消息并退出)来忽略这些错误,如下所示:

http://motifdeveloper.com/tips/tip29.html

我已经实现了一个自定义X11错误处理程序,它忽略了该文章中描述的BadWindow错误。所以我的问题是:有关X11开发和X服务器内部工作的人比我更了解BadWindow错误是否真的可以被忽略吗?

P.S。 我将通过在同步模式下运行我们的应用程序来尝试进一步调试,但这很慢,因为我无法按需重现此错误。有关调试BadWindow错误的任何提示也将不胜感激。

3 个答案:

答案 0 :(得分:5)

如果您的程序包含一个进程(单个连接到X显示),则此错误几乎总是反映程序中的错误。

要知道的秘诀是如何调试它。因为Xlib是异步的,XDestroyWindow()会发射并且忘记,窗口上的一些后毁灭操作也可能会发射并且忘记,并且您将来会在某些其他无关的X调用期间收到错误)。这意味着来自X错误的堆栈跟踪毫无意义,并且很难调试。

要解决此问题,请致电XSynchronize(dpy, True)以强制所有来电同步。这将使应用程序变慢,所以不要将它留在生产中。 http://www.x.org/releases/X11R7.6/doc/man/man3/XSynchronize.3.xhtml

但是在同步模式下,如果Xlib调用使用坏窗口,它将立即失败。因此,您可以设置调试断点,例如在错误处理函数上,并获得有意义的回溯。这应该会告诉你哪个Xlib调用会导致问题 - 并且希望它是否是一个小部件的双重删除,使用被破坏的小部件或什么。

如果你的应用确实有多个进程或多个显示连接,例如在窗口管理器中,那么BadWindow可能是不可避免的(如果你试图弄乱另一个应用程序的窗口,那么这是不可避免的比赛,其他应用程序的窗口可能会被销毁)。在这种情况下,忽略BadWindow是正确的解决方案,但最佳做法是仅在已知触发它的那些调用期间忽略它,因此您仍然可以获得可能是错误的错误。一个常见的习惯用法是实现error_trap_push() / error_trap_pop(),只需安装和卸载错误处理程序,忽略错误。当您触摸可以在控件之外删除的外部窗口时按下错误陷阱。

答案 1 :(得分:1)

这看起来像一个按钮(或类似的UI元素)被多次删除。通常,按钮被实现为专用窗口,其中发出按钮图形,这样您就可以简单地将回调处理程序绑定到关联窗口中的单击事件。

该错误表示您的程序已尝试删除不存在的窗口ID,并且发生这种情况的最简单方法确实是它已被删除两次(或者某些内容更改了为某个UI元素记录的ID)。

此时,您不希望忽略该错误,您希望获得足够的日志记录,以确定应用程序的问题所在。

答案 2 :(得分:0)

在这种情况下,错误告诉您程序要求销毁不存在的窗口ID。如果你忽略了它,那么你可能会泄漏任何你想要破坏的窗口;或者你可能只是试图破坏相同的窗口ID两次,没有任何改变。如果不跟踪程序为什么调用带有无效ID的XDestroyWindow的根本原因,就很难说如果你忽略它会发生什么。