The Revenge of Finalizers

Malcolm Wallace Malcolm.Wallace at
Fri Oct 18 12:09:54 EDT 2002

> > SimonM:
> > > I can get it to fail another way too:
> > 
> > >   main = do
> > >     p <- mallocBytes 64
> > >     newForeignPtr p (print x)
> > >     print x
> > >    where
> > >     x = sum [1..10000]

FWIW, both GHC and nhc98 seem to have similar problems with this code.

In nhc98, depending on heapsize, you either get the normal output
(and the finaliser does not run), or the finaliser runs giving its
output, and the main thread crashes immediately afterwards.

In GHC, no matter the heapsize, you only ever get one output.
Either the finaliser is not run, or it runs after stdout has already
been closed, or it does run and the main thread does not complete.
(I can't immediately tell which case pertains.)

In nhc98 at least, I am certain that the problem is as you say:

> My impression is that the problem is more fundamental: the thunk for x
> is under evaluation when the finalizer begins to run, so it already has
> a bunch of stuff on the stack.  The finalizer starts to run, and demands
> the value of x - probably we shouldn't get a crash, but a blackhole
> instead.

Since for us the finaliser does actually evaluate correctly, I suspect
that after the closure for x is updated with its value, control
returns to the main thread, which still has a bunch of intermediate
values on the stack that are now invalid.

Do we /want/ a blackhole?  If so, then I can fix nhc98.  If not,
then I can't immediately see a good solution.


More information about the FFI mailing list