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.