summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsheaf <sam.derbyshire@gmail.com>2023-02-09 13:13:15 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-02-16 14:09:56 -0500
commit681e0e8ce470ec77a0db071f9fc7ec15995a0bb3 (patch)
tree87d24d42c59590d9bfc32bc77121bc9ece03fa9d
parent5b0388880e10ce53565721a9569d009d4534cbc1 (diff)
downloadhaskell-681e0e8ce470ec77a0db071f9fc7ec15995a0bb3.tar.gz
No default finalizer exception handler
Commit cfc8e2e2 introduced a mechanism for handling of exceptions that occur during Handle finalization, and 372cf730 set the default handler to print out the error to stderr. However, #21680 pointed out we might not want to set this by default, as it might pollute users' terminals with unwanted information. So, for the time being, the default handler discards the exception. Fixes #21680
-rw-r--r--docs/users_guide/9.6.1-notes.rst7
-rw-r--r--libraries/base/GHC/TopHandler.hs13
-rw-r--r--libraries/base/changelog.md7
-rw-r--r--libraries/base/tests/IO/T21336/FinalizerExceptionHandler.hs21
-rw-r--r--libraries/base/tests/IO/T21336/T21336a.hs3
-rw-r--r--libraries/base/tests/IO/T21336/T21336a.stderr2
-rw-r--r--libraries/base/tests/IO/T21336/T21336b.hs7
-rw-r--r--libraries/base/tests/IO/T21336/T21336b.stderr2
-rw-r--r--libraries/base/tests/IO/T21336/T21336c.hs7
-rw-r--r--libraries/base/tests/IO/T21336/all.T8
-rw-r--r--libraries/base/tests/T13167.stderr4
11 files changed, 52 insertions, 29 deletions
diff --git a/docs/users_guide/9.6.1-notes.rst b/docs/users_guide/9.6.1-notes.rst
index 256e3f1aca..646ea43c1c 100644
--- a/docs/users_guide/9.6.1-notes.rst
+++ b/docs/users_guide/9.6.1-notes.rst
@@ -191,10 +191,9 @@ Runtime system
``base`` library
~~~~~~~~~~~~~~~~
-- Exceptions thrown by weak pointer finalizers are now caught and reported
- via a global exception handler. By default this handler reports the error
- to ``stderr`` although this can be changed using
- ``GHC.Weak.Finalize.setFinalizerExceptionHandler``.
+- Exceptions thrown by weak pointer finalizers can now be reported by setting
+ a global exception handler, using ``GHC.Weak.Finalize.setFinalizerExceptionHandler``.
+ The default behaviour is unchanged (exceptions are ignored and not reported).
- GHC now provides a set of operations for introspecting on the threads of a
program, ``GHC.Conc.listThreads``, as well as operations for querying a thread's
diff --git a/libraries/base/GHC/TopHandler.hs b/libraries/base/GHC/TopHandler.hs
index 04045dad05..a2354175e4 100644
--- a/libraries/base/GHC/TopHandler.hs
+++ b/libraries/base/GHC/TopHandler.hs
@@ -83,7 +83,11 @@ runMainIO main =
do
main_thread_id <- myThreadId
weak_tid <- mkWeakThreadId main_thread_id
- setFinalizerExceptionHandler handleFinalizerException
+
+ --setFinalizerExceptionHandler printToStderrFinalizerExceptionHandler
+ -- For the time being, we don't install any exception handler for
+ -- Handle finalization. Instead, the user should set one manually.
+
case weak_tid of (Weak w) -> setMainThread w
install_interrupt_handler $ do
m <- deRefWeak weak_tid
@@ -253,13 +257,6 @@ flushStdHandles = do
-- Swallow any exceptions thrown by the finalizer exception handler
handleFinalizerExc se `catchException` (\(SomeException _) -> return ())
--- | See Note [Handling exceptions during Handle finalization] in
--- GHC.IO.Handle.Internals
-handleFinalizerException :: SomeException -> IO ()
-handleFinalizerException se =
- hPutStr stderr msg `catchException` (\(SomeException _) -> return ())
- where
- msg = "Exception during Weak# finalization (ignored): " ++ displayException se ++ "\n"
safeExit, fastExit :: Int -> IO a
safeExit = exitHelper useSafeExit
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 67535438d9..f4b272347b 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -12,10 +12,9 @@
* Add `forall a. Functor (p a)` superclass for `Bifunctor p` ([CLC proposal #91](https://github.com/haskell/core-libraries-committee/issues/91))
* Add Functor instances for `(,,,,) a b c d`, `(,,,,,) a b c d e` and
`(,,,,,) a b c d e f`.
- * Exceptions thrown by weak pointer finalizers are now reported via a global
- exception handler.
- * Add `GHC.Weak.Finalize.{get,set}FinalizerExceptionHandler` which allows the
- user to override the above-mentioned handler.
+ * Exceptions thrown by weak pointer finalizers can now be reported by setting
+ a global exception handler, using `System.Mem.Weak.setFinalizerExceptionHandler`.
+ The default behaviour is unchanged (exceptions are ignored and not reported).
* `Numeric.Natural` re-exports `GHC.Natural.minusNaturalMaybe`
([CLC proposal #45](https://github.com/haskell/core-libraries-committee/issues/45))
* Add `Data.Foldable1` and `Data.Bifoldable1`
diff --git a/libraries/base/tests/IO/T21336/FinalizerExceptionHandler.hs b/libraries/base/tests/IO/T21336/FinalizerExceptionHandler.hs
new file mode 100644
index 0000000000..92ff2d8c86
--- /dev/null
+++ b/libraries/base/tests/IO/T21336/FinalizerExceptionHandler.hs
@@ -0,0 +1,21 @@
+module FinalizerExceptionHandler
+ ( setFinalizerExceptionHandler
+ , getFinalizerExceptionHandler
+ , printToStderrFinalizerExceptionHandler )
+ where
+
+import GHC.Exception ( SomeException(..), displayException )
+import GHC.IO ( catchException )
+import GHC.IO.Handle ( hPutStr )
+import GHC.IO.StdHandles ( stderr )
+import GHC.Weak.Finalize ( setFinalizerExceptionHandler, getFinalizerExceptionHandler )
+
+-- | An exception handler for Handle finalization that prints the error to
+-- stderr, but doesn't rethrow it.
+printToStderrFinalizerExceptionHandler :: SomeException -> IO ()
+-- See Note [Handling exceptions during Handle finalization] in
+-- GHC.IO.Handle.Internals
+printToStderrFinalizerExceptionHandler se =
+ hPutStr stderr msg `catchException` (\(SomeException _) -> return ())
+ where
+ msg = "Exception during weak pointer finalization (ignored): " ++ displayException se ++ "\n"
diff --git a/libraries/base/tests/IO/T21336/T21336a.hs b/libraries/base/tests/IO/T21336/T21336a.hs
index 91c852ce92..80c260e655 100644
--- a/libraries/base/tests/IO/T21336/T21336a.hs
+++ b/libraries/base/tests/IO/T21336/T21336a.hs
@@ -1,9 +1,10 @@
-import GHC.Weak
import System.IO
import System.Mem
+import FinalizerExceptionHandler
main :: IO ()
main = do
+ setFinalizerExceptionHandler printToStderrFinalizerExceptionHandler
f <- openFile "/dev/full" WriteMode
hPutStr f "hello"
-- Ensure that the Handle's finalizer is run
diff --git a/libraries/base/tests/IO/T21336/T21336a.stderr b/libraries/base/tests/IO/T21336/T21336a.stderr
index 059b0e2473..039d26a4af 100644
--- a/libraries/base/tests/IO/T21336/T21336a.stderr
+++ b/libraries/base/tests/IO/T21336/T21336a.stderr
@@ -1 +1 @@
-Exception during Weak# finalization (ignored): GHC.IO.FD.fdWrite: resource exhausted (No space left on device)
+Exception during weak pointer finalization (ignored): GHC.IO.FD.fdWrite: resource exhausted (No space left on device)
diff --git a/libraries/base/tests/IO/T21336/T21336b.hs b/libraries/base/tests/IO/T21336/T21336b.hs
index a8f0329dd0..6d397950e9 100644
--- a/libraries/base/tests/IO/T21336/T21336b.hs
+++ b/libraries/base/tests/IO/T21336/T21336b.hs
@@ -1,6 +1,9 @@
-import GHC.Weak
import System.IO
+import System.Mem
+import FinalizerExceptionHandler
main :: IO ()
-main = hPutStr stdout "hello"
+main = do
+ setFinalizerExceptionHandler printToStderrFinalizerExceptionHandler
+ hPutStr stdout "hello"
diff --git a/libraries/base/tests/IO/T21336/T21336b.stderr b/libraries/base/tests/IO/T21336/T21336b.stderr
index 66a347472a..2e702f81e7 100644
--- a/libraries/base/tests/IO/T21336/T21336b.stderr
+++ b/libraries/base/tests/IO/T21336/T21336b.stderr
@@ -1 +1 @@
-Exception during Weak# finalization (ignored): <stdout>: hFlush: resource exhausted (No space left on device)
+Exception during weak pointer finalization (ignored): <stdout>: hFlush: resource exhausted (No space left on device)
diff --git a/libraries/base/tests/IO/T21336/T21336c.hs b/libraries/base/tests/IO/T21336/T21336c.hs
index a8f0329dd0..6d397950e9 100644
--- a/libraries/base/tests/IO/T21336/T21336c.hs
+++ b/libraries/base/tests/IO/T21336/T21336c.hs
@@ -1,6 +1,9 @@
-import GHC.Weak
import System.IO
+import System.Mem
+import FinalizerExceptionHandler
main :: IO ()
-main = hPutStr stdout "hello"
+main = do
+ setFinalizerExceptionHandler printToStderrFinalizerExceptionHandler
+ hPutStr stdout "hello"
diff --git a/libraries/base/tests/IO/T21336/all.T b/libraries/base/tests/IO/T21336/all.T
index b14e0c771b..e187a54bcd 100644
--- a/libraries/base/tests/IO/T21336/all.T
+++ b/libraries/base/tests/IO/T21336/all.T
@@ -3,14 +3,18 @@ test('T21336a',
[ unless(opsys('linux') or opsys('freebsd'), skip)
, js_broken(22261)
, fragile(22022)
+ , extra_files(['FinalizerExceptionHandler.hs'])
],
compile_and_run, [''])
test('T21336b',
- [unless(opsys('linux') or opsys('freebsd'), skip), js_broken(22352)],
+ [ unless(opsys('linux') or opsys('freebsd'), skip)
+ , js_broken(22352)
+ , extra_files(['FinalizerExceptionHandler.hs'])
+ ],
makefile_test, [])
test('T21336c',
[ unless(opsys('linux') or opsys('freebsd'), skip)
, js_broken(22370)
+ , extra_files(['FinalizerExceptionHandler.hs'])
],
makefile_test, [])
-
diff --git a/libraries/base/tests/T13167.stderr b/libraries/base/tests/T13167.stderr
deleted file mode 100644
index ecb0102c0b..0000000000
--- a/libraries/base/tests/T13167.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-Exception during Weak# finalization (ignored): failed
-Exception during Weak# finalization (ignored): failed
-Exception during Weak# finalization (ignored): failed
-Exception during Weak# finalization (ignored): failed