X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Futils%2FPanic.lhs;h=e11b28faefe5078bf77752c8cb446c82833a72bc;hb=5a185e27def3ee8ace1704235eb277bc60c38618;hp=e6c385c7d20620f46c5e4acedd699918175f2c48;hpb=1f3a7730cd7f831344d2a3b74a0ce700c382e858;p=ghc-hetmet.git diff --git a/compiler/utils/Panic.lhs b/compiler/utils/Panic.lhs index e6c385c..e11b28f 100644 --- a/compiler/utils/Panic.lhs +++ b/compiler/utils/Panic.lhs @@ -17,7 +17,7 @@ module Panic panic, panicFastInt, assertPanic, trace, - Exception.Exception(..), showException, try, tryMost, tryUser, throwTo, + Exception.Exception(..), showException, try, tryMost, throwTo, installSignalHandlers, interruptTargetThread ) where @@ -36,11 +36,11 @@ import GHC.ConsoleHandler #endif import Exception -import Control.Concurrent ( MVar, ThreadId, withMVar, newMVar ) +import Control.Concurrent ( MVar, ThreadId, withMVar, newMVar, modifyMVar_, + myThreadId ) import Data.Dynamic import Debug.Trace ( trace ) import System.IO.Unsafe ( unsafePerformIO ) -import System.IO.Error hiding ( try ) import System.Exit import System.Environment \end{code} @@ -63,7 +63,7 @@ ghcError e = Exception.throw e data GhcException = PhaseFailed String -- name of phase ExitCode -- an external phase (eg. cpp) failed - | Interrupted -- someone pressed ^C + | Signal Int -- some other fatal signal (SIGHUP,SIGTERM) | UsageError String -- prints the short usage msg after the error | CmdLineError String -- cmdline prob, but doesn't print usage | Panic String -- the `impossible' happened @@ -106,8 +106,8 @@ showGhcException (ProgramError str) = showString str showGhcException (InstallationError str) = showString str -showGhcException (Interrupted) - = showString "interrupted" +showGhcException (Signal n) + = showString "signal: " . shows n showGhcException (Panic s) = showString ("panic! (the 'impossible' happened)\n" ++ " (GHC version " ++ cProjectVersion ++ " for " ++ TargetPlatform_NAME ++ "):\n\t" @@ -148,7 +148,7 @@ assertPanic file line = \end{code} \begin{code} --- | tryMost is like try, but passes through Interrupted and Panic +-- | tryMost is like try, but passes through UserInterrupt and Panic -- exceptions. Used when we want soft failures when reading interface -- files, for example. @@ -159,7 +159,7 @@ tryMost action = do r <- try action Left se -> case fromException se of -- Some GhcException's we rethrow, - Just Interrupted -> throwIO se + Just (Signal _) -> throwIO se Just (Panic _) -> throwIO se -- others we return Just _ -> return (Left se) @@ -171,21 +171,6 @@ tryMost action = do r <- try action -- Anything else is rethrown Nothing -> throwIO se Right v -> return (Right v) - --- | tryUser is like try, but catches only UserErrors. --- These are the ones that are thrown by the TcRn monad --- to signal an error in the program being compiled -tryUser :: IO a -> IO (Either IOException a) -tryUser io = - do ei <- try io - case ei of - Right v -> return (Right v) - Left se -> - case fromException se of - Just ioe - | isUserError ioe -> - return (Left ioe) - _ -> throw se \end{code} Standard signal handlers for catching ^C, which just throw an @@ -196,18 +181,27 @@ installSignalHandlers. \begin{code} installSignalHandlers :: IO () installSignalHandlers = do + main_thread <- myThreadId + modifyMVar_ interruptTargetThread (return . (main_thread :)) + let - interrupt_exn = (toException Interrupted) + interrupt_exn = (toException UserInterrupt) interrupt = do withMVar interruptTargetThread $ \targets -> case targets of [] -> return () (thread:_) -> throwTo thread interrupt_exn + -- #if !defined(mingw32_HOST_OS) - installHandler sigQUIT (Catch interrupt) Nothing - installHandler sigINT (Catch interrupt) Nothing + _ <- installHandler sigQUIT (Catch interrupt) Nothing + _ <- installHandler sigINT (Catch interrupt) Nothing + -- see #3656; in the future we should install these automatically for + -- all Haskell programs in the same way that we install a ^C handler. + let fatal_signal n = throwTo main_thread (Signal (fromIntegral n)) + _ <- installHandler sigHUP (Catch (fatal_signal sigHUP)) Nothing + _ <- installHandler sigTERM (Catch (fatal_signal sigTERM)) Nothing return () #else -- GHC 6.3+ has support for console events on Windows @@ -219,7 +213,7 @@ installSignalHandlers = do sig_handler Break = interrupt sig_handler _ = return () - installHandler (Catch sig_handler) + _ <- installHandler (Catch sig_handler) return () #endif