[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:
http://hackage.haskell.org/trac/ghc/ticket/2161
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
unreachable."
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.
Cheers,
Simon
> 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