Before Christmas I reported a (known, I discovered) bug which would
result in the message `fatal error: No threads to run!  Deadlock?'.

Simon Marlow replied then:
> This is due to a locking problem with our I/O library.  Basically, if the
> program calls trace while writing to stdout (eg. using putStr), then a
> deadlock occurs.  The reason is that trace tries to write to stderr, which
> attempts to open stdout (in order to flush it), but stdout is already locked
> because we're in the middle of doing a putStr.
> 
> Workaround: seq stderr before doing anything.  The problem will still occur
> if you attempt to trace while writing to stderr, so "don't do that".  We
> have plans to fix the problem properly, but it involves a partial redesign
> of our I/O library.

That workaround did the trick, but since then I've changed the program
and it doesn't any more.  I tried various things, and ended up with a
program which doesn't use trace, doesn't import IOExts, and has only
Main.main in the IO Monad.  All main does is to print out a [String]
value calculated by the rest of the program, and the rest of the
program doesn't use IO at all.

I'd be grateful for any light you could shed :-).

Manuel M. T. Chakravarty writes:
> PS: I think, it is sufficient to post this to
>     `[EMAIL PROTECTED]'.

Noted.  (Though this time I've CC'd people who helpfully replied to my
previous report.  I hope they don't mind.)

Details:

I've put the program at
   http://www.chiark.greenend.org.uk/~ian/ghc-deadlock/
both as a tarfile and as a collection of .hs files.

main looks like this:

  main = do
          let opl = outputList startGame 0 [(100,startup)]
          let opstr = concat opl
          putStrLn "ready"
          putStrLn (seq opstr "seqd")
          let len = length opstr
          putStrLn ("output length" ++ show len)
          putStrLn "going ..."
          putStrLn opstr
          putStrLn "phew"

outputList is declared
  outputList :: Game -> Timestamp -> [Callback] -> [String]
so opl is of type [String].

I'm using GHC 4.04.19990916 (compiled by me from the Debian source
archive with Debianisation patch revision 2) with Debian's GCC
2.91.66-2.

Here is a transcript:

 -davenant:stalk> make clean
 mkdependHS -f depend -- -syslib posix -syslib exts -syslib misc   -- Main.hs 
NettleAction.hs NettleGame.hs NettleNotify.hs NettleUnit.hs XSM.hs
 rm -f *.o *.hi core *~ ./#*#
 -davenant:stalk> make -j2
 ghc -syslib posix -syslib exts -syslib misc   -c XSM.hs
 ghc -syslib posix -syslib exts -syslib misc   -c NettleGame.hs
 ghc: module version changed to 1; reason: no old .hi file
 /tmp/ghc1537.hc:300: warning: `s1VU_closure' was declared `extern' and later `static'
 ghc: module version changed to 1; reason: no old .hi file
 ghc -syslib posix -syslib exts -syslib misc   -c NettleNotify.hs
 ghc: module version changed to 1; reason: no old .hi file
 ghc -syslib posix -syslib exts -syslib misc   -c NettleAction.hs
 ghc: module version changed to 1; reason: no old .hi file
 ghc -syslib posix -syslib exts -syslib misc   -c NettleUnit.hs
 ghc: module version changed to 1; reason: no old .hi file
 ghc -syslib posix -syslib exts -syslib misc   -c Main.hs
 ghc: module version changed to 1; reason: no old .hi file
 ghc -syslib posix -syslib exts -syslib misc   -o nettlestalk Main.o NettleAction.o 
NettleGame.o NettleNotify.o NettleUnit.o XSM.o
 -davenant:stalk> ./nettlestalk 
 ready
 seqd
 nettlestalk: fatal error: No threads to run!  Deadlock?
 -davenant:stalk> 

This takes 100ms of CPU time on my 380MHz K6-2, which seems excessive,
but this may be a property of my program rather than an effect of the
library bug.

Thanks,
Ian.

Reply via email to