
#7970: Thread GC frees roots before thread actually finishes -----------------------------+---------------------------------------------- Reporter: joeyadams | Owner: Type: bug | Status: new Priority: normal | Component: Runtime System Version: 7.6.3 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Runtime crash | Blockedby: Blocking: | Related: 7170 -----------------------------+---------------------------------------------- In the following program, an IORef is garbage collected after a `NonTermination` exception, but is subsequently accessed: {{{ import Control.Exception as E import Data.IORef import System.Mem.Weak main :: IO () main = do ref <- newIORef 'x' weak <- mkWeakIORef ref $ putStrLn "IORef finalized" let check = deRefWeak weak >>= \m -> case m of Nothing -> putStrLn "IORef was GCed" Just ref' -> do x <- readIORef ref' putStrLn $ "IORef still alive, and contains " ++ show x let loop = loop check loop `catch` \ex -> do putStrLn $ "caught exception: " ++ show (ex :: SomeException) check readIORef ref >>= print }}} Output: {{{ IORef still alive, and contains 'x' IORef finalized caught exception: <<loop>> IORef was GCed 'x' }}} The same happens with other thread deadlocks, such as: * newEmptyMVar >>= takeMVar * atomically retry It does not happen when a `StackOverflow` or `UserInterrupt` exception is caught. This also affects `ForeignPtr`; see the attached "database" example. This is what really triggered #7170. I marked this "Runtime crash" because it can lead to a `ForeignPtr` being accessed after the garbage collector finalized it. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7970 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler