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:

If you compile the program with the -threaded flag then everything works just fine:

Sending myself a signal 12Received a signal 12

but without it, the signal handler will print a totaly random signal number:

Sending myself a signal 12Received 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.