C finalizer of a finalized ForeignPtr may be called again when RTS shuts down
The C finalizer of a ForeignPtr that was explicitly finalized (finalizeForeignPtr) is sometimes called again when the RTS shuts down.
Expected behaviour:
- The test script (./test.sh) below never stops
Observed behaviour:
- After a while, the test script stops with an error message indicating double free or memory corruption
$ ./test.sh
[1 of 1] Compiling Main ( finalizer_hs.hs, finalizer_hs.o )
Linking finalizer_hs ...
*** Error in `./finalizer_hs': double free or corruption (!prev): 0x00000000010b85e0 ***
./test.sh: line 3: 20482 Aborted (core dumped) ./finalizer_hs +RTS -N
178
File finalizer_hs.hs
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign (Ptr, FunPtr, malloc)
import Foreign.ForeignPtr (newForeignPtr, finalizeForeignPtr)
import Control.Monad (forM, forM_)
foreign import ccall "stdlib.h &free" p_free :: FunPtr (Ptr a -> IO ())
main :: IO ()
main = do
fps <- forM [1 .. 10000] $ \_ -> do
p <- malloc
newForeignPtr p_free (p :: Ptr Int)
forM_ fps finalizeForeignPtr
File test.sh:
ghc finalizer_hs.hs -threaded
CNT=0
while ./finalizer_hs +RTS -N; do CNT=$((CNT+1)); done
echo $CNT
Note: running several instances of ./test.sh concurrently triggers the problem faster
Issue detected on following tested setups:
- Linux 32bit GHC 7.10.2
- Linux 64bit GHC 7.8.3
- Linux 64bit GHC 7.8.4
Trac metadata
Trac field | Value |
---|---|
Version | 7.8.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | simonmar |
Operating system | |
Architecture |