
On Thu, Feb 16, 2012 at 02:55:13PM -0600, Austin Seipp wrote:
64-bit GHC on OS X gives me this:
$ ghc -fforce-recomp -threaded finalizer [1 of 1] Compiling Main ( finalizer.hs, finalizer.o ) Linking finalizer ... $ ./finalizer waiting ... done! waiting ... running finalizer done!
However, it's a different story when `-O2` is specified:
$ ghc -O2 -fforce-recomp -threaded finalizer [1 of 1] Compiling Main ( finalizer.hs, finalizer.o ) Linking finalizer ... $ ./finalizer waiting ... running finalizer done! waiting ... done!
This smells like a bug. The stranger thing is that the GC will run the finalizer, but it doesn't reclaim the object? I'd think `readIORef` going after an invalidated pointer the GC reclaimed would almost certainly crash.
The finalizer is attached to the Thing, not the IORef. I haven't checked, but I assume that ioref gets inlined, so effectively (ioref x) is evaluated early. If you change it to readIORef (ioref' x) >>= \ix -> ix `seq` return () and define {-# NOINLINE ioref' #-} ioref' :: Thing -> IORef Bool ioref' = ioref then you'll get the sort of output you expect. Finalizers are tricky things, especially when combined with some of GHC's optimisations. Thanks Ian