SQLserverにADO 接続をして検索するアプリを作ろうとしているのだけど、Segmentation fault/access violation in generated code が起きてしまう。
1回目はたいてい大丈夫で、2回は問題が発生しないこともあるけれど、3回、4回となるとSegmentation fault/access violation in generated codeで死ぬ。
- 実行したものはVBの【SELECT SQL実行 サンプルリスト】とほぼ同じもの。VBのソースを見ると明示的に開放している。
Set rs = Nothing Set cn = Nothing
- 「“助けて!プログラムがクラッシュした!”(つまり、「セグメンテーション違反」や「core dumped」) 」によると、「プログラムで他言語呼び出しを行っておらず安全でないと分かっている関数(unsafePerformIOなど)も使っていないなら一つの例外をのぞいて、これは常にGHCシステムのバグである」ってあるけれど、COM がプログラムで他言語呼び出しを行っている…Orz
- 本物のプログラマはHaskellを使う / 第23回 外部環境のメモリーとHaskellの間の整合性を取るには「例えばCOMオブジェクトのように,同一のメモリーを参照カウント(reference counting)を使って共有している場合,GCによって勝手にメモリーが解放されては困ります。この場合,メモリーを解放する代わりに参照カウントを減らす専用の解放関数を使用する必要があります」…。
FFI の勉強をしないと駄目だ…。
{-# LANGUAGE ForeignFunctionInterface #-} module ForeignPtrExample where import Foreign.ForeignPtr import Foreign.Marshal.Alloc import Foreign.Marshal.Utils import Foreign.Ptr import Foreign.Storable testForeignPtr :: Int -> IO (ForeignPtr Int) testForeignPtr val = do p <- new val print $ show p ++ " is allocated." func <- gcFunc $ \ptr -> do free ptr print $ show ptr ++ " is deallocated." newForeignPtr func p foreign import ccall "wrapper" gcFunc :: (Ptr a -> IO ()) -> IO (FunPtr (Ptr a -> IO ()))
PS C:\card\ffi> ghci TestForeignPtr.hs GHCi, version 6.10.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling ForeignPtrExample ( TestForeignPtr.hs, interpreted ) Ok, modules loaded: ForeignPtrExample. *ForeignPtrExample> testForeignPtr 365 "0x025136c0 is allocated." 0x025136c0 *ForeignPtrExample> testForeignPtr 366 "0x025136e0 is allocated." 0x025136e0 *ForeignPtrExample> :r Ok, modules loaded: ForeignPtrExample. *ForeignPtrExample> print "force GC." "force GC." *ForeignPtrExample> -- ここから先へ進まない…。メモリを開放できない?
Windows 6.10.2, Linux 6.10.3 どちらも同じ。
●2010/05/25 追記
Linux 版 6.12.1 で実行してみたところ、以下のメッセージが表示された。
$ ghci TestForeignPtr.hs GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling ForeignPtrExample ( TestForeignPtr.hs, interpreted ) Ok, modules loaded: ForeignPtrExample. ghci> testForeignPtr 365 "0x0a3e4d40 is allocated." 0x0a3e4d40 ghci> testForeignPtr 366 "0x0a3aa710 is allocated." 0x0a3aa710 ghci> :r Ok, modules loaded: ForeignPtrExample. ghci> print "force GC." "force GC." ghci> ghc: error: a C finalizer called back into Haskell. This was previously allowed, but is disallowed in GHC 6.10.2 and later. To create finalizers that may call back into Haskll, use Foreign.Concurrent.newForeignPtr instead of Foreign.newForeignPtr.
Foreign.Concurrent をインポートして、newForeignPtr を Foreign.Concurrent.newForeignPtrに置き換えても同じ。