C finalizers are reversed during GC
(See also thread starting at http://www.haskell.org/pipermail/libraries/2012-August/018302.html )
The list of finalizers is reversed during GC (cf. rts/sm/MarkWeak.c
), which may cause them to run in the wrong order.
The following program reproduces this behaviour.
{-# LANGUAGE ForeignFunctionInterface, MagicHash #-}
import GHC.ForeignPtr
import GHC.Ptr
import System.Mem
-- one should really use own C function rather than this varargs one to avoid
-- possible ABI issues
foreign import ccall "&debugBelch" fun :: FunPtr (Ptr () -> Ptr () -> IO ())
new name = do
p <- newForeignPtr_ (Ptr name)
addForeignPtrFinalizerEnv fun (Ptr "finalizer 1 (%s)\n"#) p
addForeignPtrFinalizerEnv fun (Ptr "finalizer 2 (%s)\n"#) p
return p
main = do
p <- new "p"#
q <- new "q"#
r <- new "r"#
performGC -- collect p. finalizer order: 2, then 1.
print q
performGC -- collect q. finalizer order: 1, then 2.
-- expected order: 2, then 1.
print r
performGC -- collect r. finalizer order: 2, then 1.
Trac metadata
Trac field | Value |
---|---|
Version | 7.6.1-rc1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |