GC and weak reference finalizers and exceptions
When GC runs a number of finalizers in a row, and the first of them throws an exception, then other finalizers are ignored. The relevant piece of code is here.
The following program reproduces the issue:
import Data.IORef
import Control.Monad
import Control.Exception
import System.Mem
main :: IO ()
main = do
run
run
run
run
performMajorGC
performMajorGC
run :: IO ()
run = do
ref <- newIORef ()
void $ mkWeakIORef ref $ do
putStr "."
throwIO $ ErrorCall "failed"
I expect it to output "....", but I get only "."
The issue makes it unsafe to rely on finalizer for resource cleanup because unrelated finalizer (e.g. from some other library) may prevent your finalizer from running.
Actually I was sure the issue is known, but today I tried to find a reference to it, and failed.
If it is by design, then it should be documented somewhere.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |