[GHC] #10298: Infinite loop when shared libraries are unavailable
GHC
ghc-devs at haskell.org
Sun Apr 19 23:54:49 UTC 2015
#10298: Infinite loop when shared libraries are unavailable
-------------------------------------+-------------------------------------
Reporter: snoyberg | Owner: simonmar
Type: bug | Status: new
Priority: normal | Milestone:
Component: Runtime System | Version: 7.10.1
Resolution: | Keywords:
Operating System: Linux | Architecture: x86_64
Type of failure: Runtime crash | (amd64)
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by rwbarton):
Actually there are more hidden traps. The `IOError` that is raised from
the failure of `iconv_open` is produced by `errnoToIOError`, which is
defined as
{{{
errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
str <- strerror errno >>= peekCString
return (IOError maybeHdl errType loc str (Just errno') maybeName)
where -- ...
}}}
This means that matching on the `IOError` constructor will recursively
raise another exception, since `peekCString` uses the user's locale.
In `GHC.TopHandler`, `real_handler` matches on the `IOError` constructor
to decide how to exit. So a possible fix is
{{{
diff --git a/libraries/base/GHC/TopHandler.hs
b/libraries/base/GHC/TopHandler.hs
index d7c0038..5d4094a 100644
--- a/libraries/base/GHC/TopHandler.hs
+++ b/libraries/base/GHC/TopHandler.hs
@@ -157,14 +157,25 @@ 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)
+
+-- 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 "encountered an exception while trying to report an
exception" $ \msg ->
+ errorBelch fmt msg >> exit 1
-- try to flush stdout/stderr, but don't worry if we fail
-- (these handles might have errors, and we don't want to go into
}}}
though it feels a bit artificial.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10298#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list