[Haskell-cafe] Threads not running under GHC 6.10?

Gwern Branwen gwern0 at gmail.com
Sat Dec 6 15:26:10 EST 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

So, the Hint library was recently updated and I was editing Mueval to
run with (i386) 6.10, when I discovered that for some reason, DoS'ing
expressions were succeeding in rendering my machine unusable.
Eventually, I discovered that my watchdog thread didn't seem to be
running. But with +RTS -N2 -RTS all my tests did pass!

Here's a simple example of what I mean; the following is basically a
very lightly adapted version of the actual Mueval code:

- ----------------
import Control.Concurrent   (forkIO, killThread, myThreadId,
threadDelay, throwTo, yield, ThreadId)
import System.Posix.Signals (sigXCPU, installHandler, Handler(CatchOnce))
import Control.OldException (Exception(ErrorCall))

main :: IO ()
main = do tid  ThreadId -> IO ()
watchDog tout tid = do installHandler sigXCPU
                                          (CatchOnce
                                           $ throwTo tid $ ErrorCall
"Time limit exceeded.") Nothing
                       forkIO $ do threadDelay (tout * 100000)
                                   -- Time's up. It's a good day to die.
                                   throwTo tid (ErrorCall "Time limit exceeded")
                                   yield -- give the other thread a chance
                                   killThread tid -- Die now, srsly.
                                   error "Time expired"
                       return () -- Never reached. Either we error out in
                                 -- watchDog, or the evaluation thread finishes.
- --------------

Now, from the looks of it, this should always error out with "Time
limit exceeded." And the threading is done via forkIO, so it shouldn't
matter how it's compiled (be it threaded or no) or run; nor do we need
to worry about optimizations, since x has no sensible value for any
input - it's always bottom.

But the results are very different:

gwern at craft:31542~>=ghc -fforce-recomp -O0 example.hs && ./a.out
^C^C
gwern at craft:31532~>=ghc -fforce-recomp -O0 -threaded example.hs && ./a.out
^C^C
gwern at craft:31536~>=ghc -threaded -fforce-recomp -O0 -threaded
example.hs && ./a.out +RTS -N1 -RTS
[a minute later] ^C^C^C^C^C^C
gwern at craft:31540~>=ghc -threaded -fforce-recomp -O0 -threaded
example.hs && ./a.out +RTS -N2 -RTS
a.out: Time limit exceeded
gwern at craft:31543~>=ghc -fforce-recomp -O2 example.hs && ./a.out
a.out: Time limit exceeded
gwern at craft:31544~>=ghc -threaded -fforce-recomp -O2 example.hs && ./a.out
a.out: Time limit exceeded
gwern at craft:31545~>=ghc -threaded -fforce-recomp -O2 example.hs &&
./a.out +RTS -N1 -RTS
a.out: Time limit exceeded
gwern at craft:31546~>=ghc -threaded -fforce-recomp -O2 example.hs &&
./a.out +RTS -N2 -RTS
a.out: Time limit exceeded

So it seems that without optimizations, or without explicit/multiple
OS threads, the watchdog thread never gets called! I'm not any sort of
expert on parallelism or GHC, but this seems like a bad thing to me.
One final note: I suspect there are further ways this can manifest.
When compiled with -O2, example.hs terminates (as it should). But
Mueval does in fact set -O2 as a ghc-option:, and yet I still found it
looping.

So, does anyone know whether this is an already known bug or whether
it's something else?

- --
gwern
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEAREKAAYFAkk63+EACgkQvpDo5Pfl1oITZgCdG2p4VcB6m5IhfqzOT0fi5qrI
VagAnRILZSxBzadSj2wlzoOWfBuwdbJo
=X61b
-----END PGP SIGNATURE-----
-------------- next part --------------
A non-text attachment was scrubbed...
Name: example.hs
Type: text/x-haskell
Size: 1196 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20081206/f97811b4/example.bin


More information about the Haskell-Cafe mailing list