在自定义GTK / Haskell TreeStore上调用treeModelGetRow时出现意外中止

时间:2014-03-13 23:09:18

标签: haskell gtk

我正在处理一个应用程序,在该应用程序中,我将在TreeView中显示应用程序的一些数据。很标准。我打算让显示器显示应用程序主要状态的数据,存储在TVar中的变量以及跨多个进程共享的变量。所以,我正在构建一个CustomView(并且几乎不能理解所有东西是如何组合在一起的),它可以看到那个TVar。

此时我完全在ghci内进行测试。

我对treeViewGetIter的呼叫正常。我在treeViewIfaceGetIter中有一些打印信息可以在TVar中打印信息,一切看起来都不错。如果提供的路径有效,我会返回一个合理的迭代器,如果没有,则返回Nothing。

但是,当我将该迭代器传递给treeViewGetRow时,应用程序将中止。没有错误消息,我刚刚回到命令行。我的ulimit设置为无限制,但没有核心转储。

所以,这是设置代码:

data FileList rowtype = FileList (CustomStore (TVar (Map FilePath (LoadStatus Image))) rowtype)

instance GObjectClass (FileList (LoadStatus Image)) where
    toGObject (FileList cm) = toGObject cm
    unsafeCastGObject = FileList . unsafeCastGObject

instance TypedTreeModelClass FileList
instance TreeModelClass (FileList (LoadStatus Image))

makeStore :: TVar (Map FilePath (LoadStatus Image)) -> IO (FileList (LoadStatus Image))
makeStore tvLst =
    customStoreNew
        tvLst
        FileList
        TreeModelIface {
              treeModelIfaceGetFlags = return [TreeModelListOnly]
            , treeModelIfaceGetIter = \[n] ->
                atomically $ do
                    unsafeIOToSTM $ putStrLn $ "Seeking element " ++ show n
                    var <- readTVar tvLst
                    unsafeIOToSTM $ putStrLn $ "tvar info: " ++ (show $ M.size var)
                    if M.null var || M.size var < n
                        then return Nothing
                        else return $ Just $ TreeIter 0 (fromIntegral n) 0 0
            , treeModelIfaceGetPath = \(TreeIter _ n _ _) -> return [fromIntegral n]
            , treeModelIfaceGetRow = \(TreeIter _ n _ _) ->
                atomically $ do
                    unsafeIOToSTM $ putStrLn $ "Looking up row at " ++ show n
                    var <- readTVar tvLst
                    return (M.elems var !! fromIntegral n)
            , treeModelIfaceIterNext = \a -> do
                putStrLn "treeModelIFaceIterNext"
                return Nothing
            , treeModelIfaceIterChildren = \a -> do
                putStrLn "treeModelIfaceIterChildren"
                return Nothing
            , treeModelIfaceIterHasChild = \a -> do
                putStrLn "treeModelIfaceIterHasChild"
                return False
            , treeModelIfaceIterNChildren = \a -> do
                putStrLn "treeModelIfaceIterNChildren"
                return 0
            , treeModelIfaceIterNthChild = \a b -> do
                putStrLn "treeModelIfaceIterNthChild"
                return Nothing
            , treeModelIfaceIterParent = \a -> do
                putStrLn "treeModelIfaceIterParent"
                return Nothing
            , treeModelIfaceRefNode = \a -> do
                putStrLn "treeModelIfaceRefNode"
                return ()
            , treeModelIfaceUnrefNode = \a -> do
                putStrLn "treeModelIfaceUnrefNode"
                return ()
            }
        Nothing
        Nothing

然后,这是一个互动。 tv初始化为三个条目,st通过makeStore tv初始化:

*Main FileListModel Control.Concurrent.STM Control.Monad> :t tv
tv
  :: TVar
       (containers-0.5.0.0:Data.Map.Base.Map
          FilePath (LoadStatus Alyra.Photos.Image.Image))
*Main FileListModel Control.Concurrent.STM Control.Monad> :t st
st :: FileList (LoadStatus Alyra.Photos.Image.Image)
*Main FileListModel Control.Concurrent.STM Control.Monad> atomically (Data.Map.size `liftM` readTVar tv)
3
*Main FileListModel Control.Concurrent.STM Control.Monad> Just iter <- treeModelGetIter st [0]
Seeking element 0
tvar info: 3
*Main FileListModel Control.Concurrent.STM Control.Monad> iter
TreeIter (-288664969) 0 0 0
*Main FileListModel Control.Concurrent.STM Control.Monad> v <- treeModelGetRow st iter

在最后一个命令之后,我重新使用bash而没有任何错误,也没有指示程序崩溃的原因。

我没有详尽地检查它们,但其他功能似乎都有效。

我对上面的声明做了一个额外的更改:

        , treeModelIfaceGetRow = \n -> do
            putStrLn $ "treeModelGetRow " ++ show n
            return Loading

即使是现在,当与底层tvar没有交互时,我也会遇到同样的崩溃。

那么,我该如何诊断这种错误呢?我实际上不知道如何开始,因为它是C和Haskell之间的互动。而且,就此而言,GTK所要求的是否有任何明显的错误?

(为了记录,我在设置TreeStore之前调用了initGUI,但这部分并未包括在内)

0 个答案:

没有答案