
#9817: signal handlers in unix are passed garbage when using the signle threaded rts -------------------------------------+------------------------------------- Reporter: redneb | Owner: simonmar Type: bug | Status: new Priority: normal | Milestone: Component: Runtime System | Version: 7.8.3 Keywords: | Operating System: POSIX Architecture: Unknown/Multiple | Type of failure: Incorrect Difficulty: Unknown | result at runtime Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- When a signal handler (registered with `GHC.Conc.Signal.setHandler`) is called upon the receipt of the relevant signal, it is passed a memory buffer in the form of a `ForeignPtr Word8`. This buffer contains a copy of the `siginfo_t` struct that was originally passed to the underlying os signal handler. Unfortunately, this only seems to work correctly in the threaded rts. In the single-threaded rts, the buffer contains garbage. This can be demonstrated by the following program: {{{#!hs import Control.Concurrent import System.Posix.Signals main :: IO () main = do wait <- newEmptyMVar _ <- flip (installHandler sig) Nothing $ CatchInfo $ \info -> do putStrLn $ "Received a signal " ++ show (siginfoSignal info) putMVar wait () raiseSignal sig putStrLn $ "Sending myself a signal " ++ show sig takeMVar wait where sig = sigUSR2 }}} If you compile the program with the `-threaded` flag then everything works just fine: {{{ Sending myself a signal 12 Received a signal 12 }}} but without it, the signal handler will print a totaly random signal number: {{{ Sending myself a signal 12 Received a signal 138644296 }}} I was able to track this down to the function `startSignalHandlers` in `rts/posix/Signals.c`. This function (which is only used by the single threaded rts) allocates a buffer and copies the `siginfo_t` struct to it and then schedules `GHC.Conc.Signal.runHandlers` to be run in a new thread. The problem is that while `GHC.Conc.Signal.runHandlers` expects a `ForeignPtr Word8`, here it is given a `Ptr Word8`. This has two implications: the signal handler is given invalid data, and nobody is deallocating the buffer so we are leaking memory every time a signal is received that has a custom handler. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9817 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler