Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,926
    • Issues 4,926
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 462
    • Merge requests 462
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #9817
Closed
Open
Created Nov 21, 2014 by redneb@redneb

signal handlers in unix are passed garbage when using the signle threaded rts

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:

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.

Trac metadata
Trac field Value
Version 7.8.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Runtime System
Test case
Differential revisions
BlockedBy
Related
Blocking
CC simonmar
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking