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 |