[Haskell-cafe] Re: A GHC error message puzzle

Simon Marlow marlowsd at gmail.com
Sat Aug 14 16:13:04 EDT 2010

On 14/08/10 02:30, Lennart Augustsson wrote:
> So it's a bug in the garbage collector.  It's closing a handle that
> clearly is still reachable, otherwise this would not have happened.

The handle is in fact not reachable from the roots, because the thread 
that points to it is also not reachable.

More about it in this ticket:

Some rationale from that ticket:

"You may argue that a reference from a thread, even an unreachable one, 
should keep a ForeignPtr alive. But it's equally valid to argue the 
reverse: a reference from a finalizer should keep a thread alive - you 
don't want a thread to be considered deadlocked if it can be unblocked 
by a finalizer. We can't have both, because then a cycle between a 
finalizer and a thread would never be collected even when both were 

So while we can flip this decision, it would have other undesirable 
consequences.  I suppose I don't really have a good handle on how often 
you want one behaviour vs. the other - feedback welcome.  Either way the 
GC has to do two extra phases after tracing from the roots: trace from 
the finalizers and then the unreachable threads, or vice versa.


> On Fri, Aug 13, 2010 at 10:53 AM, Simon Marlow<marlowsd at gmail.com>  wrote:
>> On 12/08/2010 21:59, Yitzchak Gale wrote:
>>> Wei Hu wrote:
>>>> nonTermination _ = blackhole where blackhole = blackhole
>>> My original example was actually:
>>> process :: String ->    String
>>> process = let x = x in x
>> Ah yes, that works too.  But other similar versions don't, like this one:
>> process :: String ->    String
>> process _ = let x = x in x
>> Hence why I added the "tail" in my version.
>> So what happens is this:
>>   - the recursive definition causes the main thread to block on itself
>>    (known as a "black hole")
>>   - the program is deadlocked (no threads to run), so the runtime
>>    invokes the GC to see if any threads are unreachable
>>   - the GC finds that
>>    (a) the main thread is unreachable and blocked on a blackhole, so it
>>        gets a NonTermination exception
>>    (b) the Handle is unreachable, so its finalizer is started
>>   - the finalizer runs first, and closes the Handle
>>   - the main thread runs next, and the exception handler for writeFile
>>    tries to close the Handle, which has already been finalized
>> Really hClose shouldn't complain about a finalized handle, I'll see if I can
>> fix that.
>> Cheers,
>>         Simon
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list