2013-09-23 41 views
1

當wxHaskell GUI啓動並關閉,然後再次啓動另一個wxHaskell GUI時,應用程序由於堆棧溢出而出現段錯誤。由於堆棧溢出導致GUI重啓時發生wxHaskell段錯誤

簡單的演示來源:

module Main where 

import Graphics.UI.WX 

main = do 
    start $ frame [] 
    start $ frame [] 

看來,這是一個老的bug,請參閱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修復此bug的行爲,或者至少可以採取某種解決方法嗎?重寫應用程序以使用一個持久的GUI似乎不必要的複雜。

回答

0

可以設計一個bug的解決方法,至少對於wxWidgets-2.8和GTK來說。

看來,不幸的是,wxHaskell開發人員沒有設法將GUI起始界面作爲可重入界面來實現。在每個GUI開始時,wxHaskell調用wxWidgets,調用wxWidgets源文件src/gtk/app.cpp中的wxApp :: Initialize方法。特別是,該方法執行以下兩行初始化GTK事件循環wxWidgets的:

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設置爲wxapp_poll_func - 在第一個GUI啓動時,我們將wxapp_poll_func設置爲GTK輪詢函數,並且當我們在第二個GUI啓動時使用g_main_context_get_poll_func請求它時,我們得到wxapp_poll_func回來。

在執行wxapp_poll_func期間,這阻撓了,據我所知,它應該在通過調用wxgs_poll_func初始化wxWidgets之前調用GTK使用的任何輪詢函數。在第一次GUI啓動時,它實際上調用GTK開始的輪詢函數,但在第二次GUI啓動時它會調用自身,進入無限遞歸併導致堆棧溢出。

相當棘手的解決方法是在每次GUI會話之後手動將g_poll重置爲GTK輪詢功能。這可以使用下面的C函數來完成:

#include <glib.h> 

void reset_g_poll() 
{ 
    g_main_context_set_poll_func(NULL, g_poll); 
} 

編譯爲共享庫,並將其導入爲C外部函數,並適當修改演示作品。修改演示:

module Main where 

import Graphics.UI.WX 

foreign import ccall unsafe "reset_g_poll" 
    reset_g_poll :: IO() 

main = do 

    start $ frame [] 
    reset_g_poll 

    start $ frame [] 
    reset_g_poll