From b45df9292a596b15e4e93857611b8702e54e96b9 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" <ezyang@cs.stanford.edu> Date: Mon, 22 Aug 2016 15:28:20 -0700 Subject: [PATCH] Give an explicit message when SIGSEGV happens. Fixes #767. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> --- .../Distribution/Client/ProjectBuilding.hs | 3 +- .../Client/ProjectOrchestration.hs | 29 +++++++++++++++++-- cabal-install/cabal-install.cabal | 4 +++ .../tests/IntegrationTests/custom/segfault.sh | 10 +++++++ .../IntegrationTests/custom/segfault/Setup.hs | 3 ++ .../custom/segfault/cabal.project | 1 + .../custom/segfault/plain.cabal | 14 +++++++++ 7 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 cabal-install/tests/IntegrationTests/custom/segfault.sh create mode 100644 cabal-install/tests/IntegrationTests/custom/segfault/Setup.hs create mode 100644 cabal-install/tests/IntegrationTests/custom/segfault/cabal.project create mode 100644 cabal-install/tests/IntegrationTests/custom/segfault/plain.cabal diff --git a/cabal-install/Distribution/Client/ProjectBuilding.hs b/cabal-install/Distribution/Client/ProjectBuilding.hs index d2da547998..8ad38b42a0 100644 --- a/cabal-install/Distribution/Client/ProjectBuilding.hs +++ b/cabal-install/Distribution/Client/ProjectBuilding.hs @@ -690,7 +690,8 @@ rebuildTargets verbosity InstallPlan.execute jobControl keepGoing (BuildFailure Nothing . DependentFailed . packageId) installPlan $ \pkg -> - handle (return . Left) $ fmap Right $ --TODO: review exception handling + --TODO: review exception handling + handle (\(e :: BuildFailure) -> return (Left e)) $ fmap Right $ let uid = installedUnitId pkg Just pkgBuildStatus = Map.lookup uid pkgsBuildStatus in diff --git a/cabal-install/Distribution/Client/ProjectOrchestration.hs b/cabal-install/Distribution/Client/ProjectOrchestration.hs index bede782e85..6750e9c50c 100644 --- a/cabal-install/Distribution/Client/ProjectOrchestration.hs +++ b/cabal-install/Distribution/Client/ProjectOrchestration.hs @@ -93,7 +93,7 @@ import Data.Either import Control.Exception (Exception(..)) import System.Exit (ExitCode(..), exitFailure) #ifdef MIN_VERSION_unix -import System.Posix.Signals (sigKILL) +import System.Posix.Signals (sigKILL, sigSEGV) #endif @@ -586,11 +586,14 @@ reportBuildFailures verbosity plan buildOutcomes | otherwise = False + -- NB: if the Setup script segfaulted or was interrupted, + -- we should give more detailed information. So only + -- assume that exit code 1 is "pedestrian failure." isFailureSelfExplanatory (BuildFailed e) - | Just (ExitFailure _) <- fromException e = True + | Just (ExitFailure 1) <- fromException e = True isFailureSelfExplanatory (ConfigureFailed e) - | Just (ExitFailure _) <- fromException e = True + | Just (ExitFailure 1) <- fromException e = True isFailureSelfExplanatory _ = False @@ -651,7 +654,27 @@ reportBuildFailures verbosity plan buildOutcomes Just (ExitFailure 1) -> "" #ifdef MIN_VERSION_unix + -- Note [Positive "signal" exit code] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- What's the business with the test for negative and positive + -- signal values? The API for process specifies that if the + -- process died due to a signal, it returns a *negative* exit + -- code. So that's the negative test. + -- + -- What about the positive test? Well, when we find out that + -- a process died due to a signal, we ourselves exit with that + -- exit code. However, we don't "kill ourselves" with the + -- signal; we just exit with the same code as the signal: thus + -- the caller sees a *positive* exit code. So that's what + -- happens when we get a positive exit code. Just (ExitFailure n) + | -n == fromIntegral sigSEGV -> + " The build process segfaulted (i.e. SIGSEGV)." + + | n == fromIntegral sigSEGV -> + " The build process terminated with exit code " ++ show n + ++ " which may be because some part of it segfaulted. (i.e. SIGSEGV)." + | -n == fromIntegral sigKILL -> " The build process was killed (i.e. SIGKILL). " ++ explanation diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 7cb6c779a2..efe1faa6af 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -35,6 +35,10 @@ Extra-Source-Files: tests/IntegrationTests/custom/plain/A.hs tests/IntegrationTests/custom/plain/Setup.hs tests/IntegrationTests/custom/plain/plain.cabal + tests/IntegrationTests/custom/segfault.sh + tests/IntegrationTests/custom/segfault/Setup.hs + tests/IntegrationTests/custom/segfault/cabal.project + tests/IntegrationTests/custom/segfault/plain.cabal tests/IntegrationTests/exec/Foo.hs tests/IntegrationTests/exec/My.hs tests/IntegrationTests/exec/adds_sandbox_bin_directory_to_path.out diff --git a/cabal-install/tests/IntegrationTests/custom/segfault.sh b/cabal-install/tests/IntegrationTests/custom/segfault.sh new file mode 100644 index 0000000000..a265b579a1 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/custom/segfault.sh @@ -0,0 +1,10 @@ +. ./common.sh +if [ "x$(uname)" != "xLinux" ]; then + exit +fi +# Older GHCs don't report exit via signal adequately +require_ghc_ge 708 +cd segfault +! cabal new-build 2> log +cat log +grep SIGSEGV log diff --git a/cabal-install/tests/IntegrationTests/custom/segfault/Setup.hs b/cabal-install/tests/IntegrationTests/custom/segfault/Setup.hs new file mode 100644 index 0000000000..5ffb268355 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/custom/segfault/Setup.hs @@ -0,0 +1,3 @@ +import System.Posix.Signals + +main = putStrLn "Quitting..." >> raiseSignal sigSEGV diff --git a/cabal-install/tests/IntegrationTests/custom/segfault/cabal.project b/cabal-install/tests/IntegrationTests/custom/segfault/cabal.project new file mode 100644 index 0000000000..e6fdbadb43 --- /dev/null +++ b/cabal-install/tests/IntegrationTests/custom/segfault/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-install/tests/IntegrationTests/custom/segfault/plain.cabal b/cabal-install/tests/IntegrationTests/custom/segfault/plain.cabal new file mode 100644 index 0000000000..24548713cf --- /dev/null +++ b/cabal-install/tests/IntegrationTests/custom/segfault/plain.cabal @@ -0,0 +1,14 @@ +name: plain +version: 0.1.0.0 +license: BSD3 +author: Edward Z. Yang +maintainer: ezyang@cs.stanford.edu +build-type: Custom +cabal-version: >=1.10 + +library + build-depends: base + default-language: Haskell2010 + +custom-setup + setup-depends: base, unix -- GitLab