当启动并关闭wxHaskell GUI,然后再次启动另一个wxHaskell GUI时,应用程序会因堆栈溢出而出现分段错误。
简单的演示来源:
module Main where
import Graphics.UI.WX
main = do
start $ frame []
start $ frame []
这似乎是一个旧的错误,请参阅http://permalink.gmane.org/gmane.comp.lang.haskell.wxhaskell.general/789。这条消息链接到wxHaskell的SourceForge存储库中的一个问题,并且更新的评论提到了一个版本的wxHaskell(wxWidgets 2.9的开发分支,似乎)没有错误。
我正在使用带有wxWidgets 2.8的Ubuntu 12.04,因此我必须使用wxHaskell 0.13。我试图通过查看所谓的工作开发版本的更改日志找到有关此错误的任何信息,但找不到任何内容。
wxHaskell 0.13可以解决这个有问题的行为,或者至少可以做出某种解决方法吗?重写应用程序以使用一个持久GUI似乎不必要复杂。
答案 0 :(得分:0)
可以设计出错误的解决方法,至少对于wxWidgets-2.8和GTK。
不幸的是,似乎wxHaskell开发人员没有设法将GUI启动接口实现为可重入的接口。在每个GUI启动时,wxHaskell以调用wxWidgets源文件src / gtk / app.cpp的方法wxApp :: Initialize的方式调用wxWidgets。特别是,此方法执行以下两行来初始化wxWidgets的GTK事件循环:
wxgs_poll_func = g_main_context_get_poll_func(NULL);
g_main_context_set_poll_func(NULL, wxapp_poll_func);
问题是,在第一次GUI启动wxgs_poll_func
设置为GTK开始的任何轮询功能(似乎是g_poll
)时,在第二个GUI启动wxgs_poll_func
设置为{ {1}} - 在第一次GUI启动时,我们将wxapp_poll_func
设置为GTK轮询功能,当我们在第二个GUI上使用wxapp_poll_func
开始请求时,我们返回g_main_context_get_poll_func
。
这在执行wxapp_poll_func
期间会发生逆火,据我所知,在调用wxapp_poll_func
初始化wxWidgets之前,应该调用GTK使用的任何轮询函数。在第一个GUI启动它实际上调用GTK开始的轮询函数,但在第二个GUI启动时它调用自身,进入无限递归并导致堆栈溢出。
相当糟糕的解决方法是在每次GUI会话后手动将wxgs_poll_func
重置为GTK轮询功能。这可以使用以下C函数来完成:
g_poll
将其编译为共享库并将其作为C外部函数导入,并正确修改演示工作。修改过的演示:
#include <glib.h>
void reset_g_poll()
{
g_main_context_set_poll_func(NULL, g_poll);
}