Skip to content

Commit

Permalink
Regression test for references with erroring finalisers
Browse files Browse the repository at this point in the history
In debug mode if the finaliser of a reference counted object throws an error,
then the `RefTracker` is never released. `checkForgottenRefs` will then report
the reference as forgotten, even though the finaliser ran, though not
successfully. The test that is added in this commit indeed shows this is the
case. The next commit fixes the issue, which should improve the experience of
debugging finalisers that fail.
  • Loading branch information
jorisdral committed Dec 30, 2024
1 parent 3ac3bfa commit e80f7f2
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions test-control/Test/Control/RefCount.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ tests = testGroup "Control.RefCount" [
, testProperty "prop_ref_never_released0" prop_ref_never_released0
, testProperty "prop_ref_never_released1" prop_ref_never_released1
, testProperty "prop_ref_never_released2" prop_ref_never_released2
, testProperty "prop_release_ref_exception" prop_release_ref_exception
#endif
]

Expand Down Expand Up @@ -176,5 +177,13 @@ expectRefNeverReleased :: RefException -> IO Property
expectRefNeverReleased RefNeverReleased{} = return (property True)
expectRefNeverReleased e =
return (counterexample (displayException e) $ property False)

-- | If a finaliser throws an exception, then the 'RefTracker' is still released
prop_release_ref_exception :: Property
prop_release_ref_exception = once $ ioProperty $ do
finalised <- newIORef False
ref <- newRef (writeIORef finalised True >> error "oops") TestObject
_ <- try @SomeException (releaseRef ref)
checkForgottenRefs
#endif

0 comments on commit e80f7f2

Please sign in to comment.