summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/TopHandler.hs
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2015-05-19 04:56:40 -0500
committerAustin Seipp <austin@well-typed.com>2015-05-28 16:19:35 -0500
commite28462de700240288519a016d0fe44d4360d9ffd (patch)
treec947a4b0ac30e9b16767dad1bb9f14f1effd439e /libraries/base/GHC/TopHandler.hs
parent640fe14255706ab9c6a1fa101d9b05dfabdc6556 (diff)
downloadhaskell-e28462de700240288519a016d0fe44d4360d9ffd.tar.gz
base: fix #10298 & #7695
Summary: This applies a patch from Reid Barton and Sylvain Henry, which fix a disasterous infinite loop when iconv fails to load locale files, as specified in #10298. The fix is a bit of a hack but should be fine - for the actual reasoning behind it, see `Note [Disaster and iconv]` for more info. In addition to this fix, we also patch up the IO Encoding utilities to recognize several variations of the 'ASCII' encoding (including its aliases) directly so that GHC can do conversions without iconv. This allows a static binary to sit in an initramfs. Authored-by: Reid Barton <rwbarton@gmail.com> Authored-by: Sylvain Henry <hsyl20@gmail.com> Signed-off-by: Austin Seipp <austin@well-typed.com> Test Plan: Eyeballed it. Reviewers: rwbarton, hvr Subscribers: bgamari, thomie Differential Revision: https://phabricator.haskell.org/D898 GHC Trac Issues: #10298, #7695
Diffstat (limited to 'libraries/base/GHC/TopHandler.hs')
-rw-r--r--libraries/base/GHC/TopHandler.hs29
1 files changed, 28 insertions, 1 deletions
diff --git a/libraries/base/GHC/TopHandler.hs b/libraries/base/GHC/TopHandler.hs
index d7c00384e4..e725196cdf 100644
--- a/libraries/base/GHC/TopHandler.hs
+++ b/libraries/base/GHC/TopHandler.hs
@@ -157,13 +157,40 @@ real_handler exit se = do
Just (ExitFailure n) -> exit n
-- EPIPE errors received for stdout are ignored (#2699)
- _ -> case fromException se of
+ _ -> catch (case fromException se of
Just IOError{ ioe_type = ResourceVanished,
ioe_errno = Just ioe,
ioe_handle = Just hdl }
| Errno ioe == ePIPE, hdl == stdout -> exit 0
_ -> do reportError se
exit 1
+ ) (disasterHandler exit) -- See Note [Disaster with iconv]
+
+-- don't use errorBelch() directly, because we cannot call varargs functions
+-- using the FFI.
+foreign import ccall unsafe "HsBase.h errorBelch2"
+ errorBelch :: CString -> CString -> IO ()
+
+disasterHandler :: (Int -> IO a) -> IOError -> IO a
+disasterHandler exit _ =
+ withCAString "%s" $ \fmt ->
+ withCAString msgStr $ \msg ->
+ errorBelch fmt msg >> exit 1
+ where msgStr = "encountered an exception while trying to report an exception"
+
+{- Note [Disaster with iconv]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When using iconv, it's possible for things like iconv_open to fail in
+restricted environments (like an initram or restricted container), but
+when this happens the error raised inevitably calls `peekCString`,
+which depends on the users locale, which depends on using
+`iconv_open`... which causes an infinite loop.
+
+This occurrence is also known as tickets #10298 and #7695. So to work
+around it we just set _another_ error handler and bail directly by
+calling the RTS, without iconv at all.
+-}
-- try to flush stdout/stderr, but don't worry if we fail