Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,262
    • Issues 4,262
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 419
    • Merge Requests 419
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #7170

Closed
Open
Opened Aug 21, 2012 by joeyadams@trac-joeyadams

Foreign.Concurrent finalizer called twice in some cases

When Foreign.Concurrent.newForeignPtr is used, here's a case where the finalizer is called twice:

{-# LANGUAGE ForeignFunctionInterface #-}
import Control.Concurrent
import Control.Exception    (bracket)
import Foreign.Ptr          (Ptr, intPtrToPtr)
import Foreign.ForeignPtr   (ForeignPtr)
import qualified Foreign.Concurrent as FC
import qualified Foreign.ForeignPtr as FP

testForeignPtr_Concurrent :: Ptr a -> IO (ForeignPtr a)
testForeignPtr_Concurrent ptr = FC.newForeignPtr ptr (fin ptr)

fin :: Ptr a -> IO ()
fin ptr = putStrLn $ "finalizing " ++ show ptr

main :: IO ()
main = do
    mv <- newEmptyMVar
    bracket (testForeignPtr_Concurrent $ intPtrToPtr 1)
            FP.finalizeForeignPtr $ \_ ->
        -- hang, so the thread and foreign pointer get GCed
        takeMVar mv

This produces the following output:

finalizing 0x0000000000000001
finalizing 0x0000000000000001
foreignptr: thread blocked indefinitely in an MVar operation

This happens on GHC 7.4.2 and 7.6.0.20120810, with and without -threaded.

This can easily lead to segfaults when you have an FFI library that does this:

create :: IO Object
create = do
    ptr <- c_create
    CObject <$> newForeignPtr ptr (finalize ptr)

finalize :: Ptr CObject -> IO ()
finalize ptr = do
    ...

destroy :: Object -> IO ()
destroy (Object fptr) =
    finalizeForeignPtr fptr

And application code does this:

bracket create destroy $ \obj -> do
    ...
Trac metadata
Trac field Value
Version 7.4.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Runtime System
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Assignee
Assign to
7.6.1
Milestone
7.6.1
Assign milestone
Time tracking
None
Due date
None
Reference: ghc/ghc#7170