Opened 9 years ago

Closed 9 years ago

#4221 closed bug (fixed)

Calling freeHaskellFunctionPtr from C finalizer leads to crashes

Reported by: ravi_n Owned by:
Priority: normal Milestone: 7.0.1
Component: Runtime System Version: 6.12.3
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime crash Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


I recently discovered that calling freeHaskellFunctionPtr from a C finalizer (as seems natural to do if the object you're cleaning up on the C side is holding on to a Haskell function wrapper) leads to strange crashes.

The attached program (which is a stress-test loop of allocating function wrappers, using them and then freeing them) illustrates the problem.

You can compile it with:

ghc --make !WrapperTest2.hs HsFunction.c -o !WrapperTest2 -main-is !WrapperTest2

Depending on the platform and compilation flags I've noticed different results. Compiled as above (on Windows) I get: !WrapperTest2.exe: internal error: stg_ap_p_ret

Compiled with -debug I get: !WrapperTest2.exe: internal error: ASSERTION FAILED: file rts\Stable.c, line 224

On Windows, these results do not change if I compile with -threaded.

On Linux, without -threaded, I get the same results as Windows.

However, with -threaded I get different behavior.

With -threaded and without -debug the program eventually deadlocks.

With -threaded and -debug I get the following message: !WrapperTest2: internal error: multiple ACQUIRE_LOCK: rts/Stable.c 284

I'm currently working around the issue by using Haskell finalizers (which don't seem to have this problem), but I thought I should report the bug. I'd also appreciate feedback on whether using Haskell finalizers is actually a safe workaround for this issue or if I've just been lucky so far.

Attachments (2)

WrapperTest2.hs (1.3 KB) - added by ravi_n 9 years ago.
HsFunction.c (552 bytes) - added by ravi_n 9 years ago.

Download all attachments as: .zip

Change History (5)

Changed 9 years ago by ravi_n

Attachment: WrapperTest2.hs added

Changed 9 years ago by ravi_n

Attachment: HsFunction.c added

comment:1 Changed 9 years ago by igloo

Milestone: 6.14.1

comment:2 Changed 9 years ago by simonmar

I found and fixed the bug, but I was confused for a while that the program was still crashing after I'd fixed the bug. Then I noticed the program has a pretty serious bug in it:

callFnBlob :: ForeignPtr FnBlob -> CDouble -> IO (CDouble)
callFnBlob fnblob d = withForeignPtr fnblob $ 
                        \ptrblob -> return(call_fn_blob ptrblob d) 

this is an invalid use of withForeignPtr, because the pointer escapes from the context (in the closure call_fn_blob ptrblob d). Hence the finalizer runs before the call, and you get a crash.

comment:3 Changed 9 years ago by simonmar

Resolution: fixed
Status: newclosed


Tue Aug 10 06:37:39 PDT 2010  Simon Marlow <>
  * Run finalizers *after* updating the stable pointer table (#4221)
  Silly bug really, we were running the C finalizers while the StablePtr
  table was still in a partially-updated state during GC, but finalizers
  are allowed to call freeStablePtr() (via hs_free_fun_ptr(), for
  example), and chaos ensues.
Note: See TracTickets for help on using tickets.