[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