Package: libghc-missingh-dev Version: 1.1.0.3-6+b3 Severity: normal As described in this thread: http://thread.gmane.org/gmane.comp.lang.haskell.cafe/99334/focus=99338
The attached testcase will hang after a short while once compiled with -threaded. Comment out the "LINE OF DEATH" and it runs as expected. Apparently hPipeFrom etc's use of System.Log.Logger is the culprit. logM uses a MVar, and this is a MVar deadlock. But I don't understand exactly why this happens only with the threaded runtime, or really, why the attempt to use the MVar *before* forkProcess causes problems at all. This also seems disturbingly similar to #624389. In both cases System.Cmd.Utils falls over under heavy load, or is somehow racy. -- System Information: Debian Release: wheezy/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'stable'), (1, 'experimental') Architecture: i386 (x86_64) Kernel: Linux 3.2.0-2-amd64 (SMP w/1 CPU core) Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages libghc-missingh-dev depends on: ii ghc [libghc-unix-dev-2.5.1.0-b1af7] 7.4.1-4 ii libc6 2.13-32 ii libffi5 3.0.10-3 ii libghc-array-dev-0.4.0.0-0b32f <none> ii libghc-base-dev-4.5.0.0-c8e71 <none> ii libghc-containers-dev-0.4.2.1-7c545 <none> ii libghc-directory-dev-1.1.0.2-89575 <none> ii libghc-filepath-dev-1.3.0.0-674b8 <none> ii libghc-hslogger-dev [libghc-hslogger-dev-1.1.4-94350] 1.1.4+dfsg1-2+b3 ii libghc-hunit-dev [libghc-hunit-dev-1.2.4.2-6a847] 1.2.4.2-2+b1 ii libghc-mtl-dev [libghc-mtl-dev-2.1.1-ae9b4] 2.1.1-1 ii libghc-network-dev [libghc-network-dev-2.3.0.13-6b330] 2.3.0.13-1+b2 ii libghc-old-locale-dev-1.0.0.4-29bd5 <none> ii libghc-old-time-dev-1.1.0.0-681e9 <none> ii libghc-parsec3-dev [libghc-parsec-dev-3.1.2-ad4f8] 3.1.2-1+b3 ii libghc-process-dev-1.1.0.1-91185 <none> ii libghc-random-dev [libghc-random-dev-1.0.1.1-3bece] 1.0.1.1-1+b1 ii libghc-regex-compat-dev [libghc-regex-compat-dev-0.95.1-c 0.95.1-2+b1 ii libgmp10 2:5.0.5+dfsg-2 libghc-missingh-dev recommends no packages. Versions of packages libghc-missingh-dev suggests: pn libghc-missingh-doc <none> pn libghc-missingh-prof <none> -- no debconf information -- see shy jo
import System.Cmd import System.IO import System.Posix.Process import Control.Monad import System.Exit import System.Cmd import System.Log.Logger import System.Posix.IO import System.Posix.Process import System.Posix.Signals import System.Posix.Types import System.IO import System.IO.Error import Control.Concurrent(forkIO) import Control.Exception(finally) main :: IO () main = forever $ pipeRead ["hello", "world"] pipeRead :: [String] -> IO () pipeRead params = do print $ "pipeRead in " ++ show (params) (p, h) <- hPipeFrom "echo" params print "pipeRead getcontents" c <- hGetContents h print $ "got: " ++ c _ <- getProcessStatus True False $ processID p print "pipeRead out" data PipeHandle = PipeHandle { processID :: ProcessID, phCommand :: FilePath, phArgs :: [String], phCreator :: String -- ^ Function that created it } deriving (Eq, Show) logRunning :: String -> FilePath -> [String] -> IO () logRunning func fp args = debugM (logbase ++ "." ++ func) (showCmd fp args) logbase :: String logbase = "System.Cmd.Utils" showCmd :: FilePath -> [String] -> String showCmd fp args = fp ++ " " ++ show args warnFail :: [Char] -> FilePath -> [String] -> [Char] -> IO t warnFail funcname fp args msg = let m = showCmd fp args ++ ": " ++ msg in do warningM (logbase ++ "." ++ funcname) m fail m hPipeFrom :: FilePath -> [String] -> IO (PipeHandle, Handle) hPipeFrom fp args = do pipepair <- createPipe logRunning "pipeFrom" fp args --- LINE OF DEATH let childstuff = do dupTo (snd pipepair) stdOutput closeFd (fst pipepair) executeFile fp True args Nothing p <- try (forkProcess childstuff) -- parent pid <- case p of Right x -> return x Left e -> warnFail "pipeFrom" fp args $ "Error in fork: " ++ show e closeFd (snd pipepair) h <- fdToHandle (fst pipepair) return (PipeHandle pid fp args "pipeFrom", h)