C finalizer may be called on re-used memory
It seems that the runtime system sometimes reuses memory referred to by
ForeignPtr
values before the associated C finalizers have been run. At
that's what it looks like to me. Maybe I'm interpreting the behavior of
GHC's runtime system incorrectly, or it's a defect in my test program.
To reproduce the defect, compile finalizertest.hs
and finalizerlib.c
,
e.g. with
ghc finalizertest.hs finalizerlib.c -threaded
Run the resulting program as
./finalizertest +RTS -N2
After a while it prints a message like
finalize_value: 80f69dc != 11223344 after 47393 calls
Aborted
The C code prints this if the pointer passed to the finalizer does not point to the expected value.
It's not necessary to link with the threaded runtime, nor is it necessary to run with more than one CPU. Doing so increases the likelihood of the defect to occur substantially, though.
I've observed this with several different combinations of GHC and host-systems:
-
GHC 7.10.2 on a 64 bit Linux (Debian jessie)
-
GHC 7.10.1 on a 32 bit Linux (Debian wheezy)
-
GHC 7.4.1 on a 32 bit Linux (Debian wheezy)
This GHC is the one packaged by Debian
It's crucial for the defect that the memory is allocated with
mallocForeignPtrBytes
. Using mallocBytes
instead and building a
ForeignPtr
with finalizerFree
avoids the defect.
I came across this defect while trying to debug a segmentation fault in
the zlib
package. This defect was reported on the libraries mailing list
https://mail.haskell.org/pipermail/libraries/2015-June/025829.html
(corresponding Agda ticket: https://github.com/agda/agda/issues/1518). I came across it in one of my own projects last week.
My test program basically does what zlib
does when allocating
and initializing the z_stream
value: it allocates memory with
mallocForeignPtrBytes
and later adds a finalizer with
addForeignPtrFinalizer
.
Trac metadata
Trac field | Value |
---|---|
Version | 7.4.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | simonmar |
Operating system | |
Architecture |