[commit: packages/base] master: Handle ExitFailure (-sig) by killing process with signal (6b22a6e)

git at git.haskell.org git at git.haskell.org
Thu Nov 14 17:42:00 UTC 2013


Repository : ssh://git@git.haskell.org/base

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/6b22a6ef9e59c6562ef6adfad7cd94e27aedec2c/base

>---------------------------------------------------------------

commit 6b22a6ef9e59c6562ef6adfad7cd94e27aedec2c
Author: Duncan Coutts <duncan at well-typed.com>
Date:   Thu Nov 14 15:15:31 2013 +0000

    Handle ExitFailure (-sig) by killing process with signal
    
    On Unix we now use negative exit codes in ExitFailure to indicate that a
    process exited due to a signal. This patch implements the case for when
    a ExitFailure exception propagates out of the top of main (and is
    handled by the topHandler).
    
    For a negative ExitFailure code, we try to kill the process using that
    signal (the details of that are handled by shutdownHaskellAndSignal from
    the RTS). For an exit code outside the valid ranges, we use 0xff.


>---------------------------------------------------------------

6b22a6ef9e59c6562ef6adfad7cd94e27aedec2c
 GHC/TopHandler.lhs |   40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/GHC/TopHandler.lhs b/GHC/TopHandler.lhs
index 9e4bc07..8e50333 100644
--- a/GHC/TopHandler.lhs
+++ b/GHC/TopHandler.lhs
@@ -177,10 +177,32 @@ flushStdHandles = do
   hFlush stdout `catchAny` \_ -> return ()
   hFlush stderr `catchAny` \_ -> return ()
 
+safeExit, fastExit :: Int -> IO a
+safeExit = exitHelper useSafeExit
+fastExit = exitHelper useFastExit
+
+exitHelper :: CInt -> Int -> IO a
 -- we have to use unsafeCoerce# to get the 'IO a' result type, since the
 -- compiler doesn't let us declare that as the result type of a foreign export.
-safeExit :: Int -> IO a
-safeExit r = unsafeCoerce# (shutdownHaskellAndExit $ fromIntegral r)
+#ifdef mingw32_HOST_OS
+exitHelper exitKind r =
+  unsafeCoerce# (shutdownHaskellAndExit (fromIntegral r) exitKind)
+#else
+-- On Unix we use an encoding for the ExitCode:
+--      0 -- 255  normal exit code
+--   -127 -- -1   exit by signal
+-- For any invalid encoding we just use a replacement (0xff).
+exitHelper exitKind r
+  | r >= 0 && r <= 255
+  = unsafeCoerce# (shutdownHaskellAndExit   (fromIntegral   r)  exitKind)
+  | r >= -127 && r <= -1
+  = unsafeCoerce# (shutdownHaskellAndSignal (fromIntegral (-r)) exitKind)
+  | otherwise
+  = unsafeCoerce# (shutdownHaskellAndExit   0xff                exitKind)
+
+foreign import ccall "shutdownHaskellAndSignal"
+  shutdownHaskellAndSignal :: CInt -> CInt -> IO ()
+#endif
 
 exitInterrupted :: IO a
 exitInterrupted = 
@@ -189,20 +211,16 @@ exitInterrupted =
 #else
   -- we must exit via the default action for SIGINT, so that the
   -- parent of this process can take appropriate action (see #2301)
-  unsafeCoerce# (shutdownHaskellAndSignal CONST_SIGINT)
-
-foreign import ccall "shutdownHaskellAndSignal"
-  shutdownHaskellAndSignal :: CInt -> IO ()
+  safeExit (-CONST_SIGINT)
 #endif
 
 -- NOTE: shutdownHaskellAndExit must be called "safe", because it *can*
 -- re-enter Haskell land through finalizers.
 foreign import ccall "Rts.h shutdownHaskellAndExit"
-  shutdownHaskellAndExit :: CInt -> IO ()
+  shutdownHaskellAndExit :: CInt -> CInt -> IO ()
 
-fastExit :: Int -> IO a
-fastExit r = unsafeCoerce# (stg_exit (fromIntegral r))
+useFastExit, useSafeExit :: CInt
+useFastExit = 1
+useSafeExit = 0
 
-foreign import ccall "Rts.h stg_exit"
-  stg_exit :: CInt -> IO ()
 \end{code}



More information about the ghc-commits mailing list