[GHC] #9817: signal handlers in unix are passed garbage when using the signle threaded rts
GHC
ghc-devs at haskell.org
Fri Nov 21 05:48:13 UTC 2014
#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
More information about the ghc-tickets
mailing list