Normally, the GHC runtime system begins things by called an internal function
mainIO :: IO ()
which, in turn, fires up your `Main.main'. The standard definition of `mainIO' looks like this:
mainIO = catch Main.main (\err -> error ("I/O error: " ++ showsPrec 0 err "\n"))
that is, all it does is run `Main.main', catching any I/O errors that occur and displaying them on standard error before exiting the program.
To subvert the above process, you need only provide a `mainIO' of your own (in a module named `GHCmain').
Here's a little example, stolen from Alastair Reid:
module GHCmain ( mainIO ) where import GlaExts mainIO :: IO () mainIO = do sleep 5 _ccall_ printf "%d\n" (14::Int) sleep :: Int -> IO () sleep t = _ccall_ sleep t