Skip to content

forkIO can trivially defeat bracket

Consider this program,

import Control.Concurrent
import Control.Exception

main = do
    putStrLn "forking"
    forkIO $ bracket (putStrLn "forked") (const $ putStrLn "finalize") (const $ putStrLn "hello" >> threadDelay 100000000)
    threadDelay 10000
    putStrLn "done" 

Would you predict that it would print finalize?

Answer: no. It will print,

forking
forked
hello
done

It would pointed out by an author of a cryptographic library (raaz) that this is quite bad as it means that secure memory could leak out uncleared.

It's not entirely clear how best to deal with this. Perhaps raise a ThreadKilled async exception to all running threads during RTS shutdown, followed by a synchronization?

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information