Eric Y. Kow wrote:
> I have honestly no idea what's going on here.

I've worked it out. With a little help from malcolmw on #ghc.

1    image <- imageCreateSized (WX.Size 256 256)
2    pixels <- imageGetData image
3    bytes <- peekArray (256*256*3) (castPtr pixels)


After line 2 is executed, there is no remaining reference to 'image' in 
the program. 'image' is dead, and can be garbage collected. (Although it 
may not be at any particular time). If 'image' gets GC'ed, because there 
is a ForeignPtr inside, that calls the C++ destructor. The wxImage C++ 
destructor believes it owns the data block, so it free()s it, and 
'pixels' is left pointing to a free()ed block.

This is why it is inconsistent. It depends if image happens to get GC'ed 
before the peekArray completes running.

As to how we fix it? Well as a proof of concept, adding:

     putStrLn $ "Keep image alive with this reference " ++ (show image)

as the last line of createAndGetPixels will prevent the GC and stop the 
segfault.

The right fix tho? I'm not sure. It seems like 'imageGetData' is 
fundamentally broken (and thus anything that depends on it, like 
getPixels). Is there some way imageGetData could return a Ptr and 
simultaneously keep the 'image' alive for as long as the Ptr is alive?

Should imageGetData be turned into a 'with-style' function

Image a -> (Ptr () -> IO b) -> IO b

which protects the image?

Is there a workaround I can use in my code like touchPtr? A version of 
touchPtr which works on WXObjects?

Jules


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
wxhaskell-users mailing list
wxhaskell-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wxhaskell-users

Reply via email to