[GHC] #11836: Hello World Bug - silent stdout errors
GHC
ghc-devs at haskell.org
Thu Apr 14 17:36:28 UTC 2016
#11836: Hello World Bug - silent stdout errors
-------------------------------------+-------------------------------------
Reporter: bit | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.3
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
== Background
This entertaining talk explains the issue: https://www.irill.org/events
/ghm-gnu-hackers-meeting/videos/jim-meyering-goodbye-world-the-perils-of-
relying-on-output-streams-in-c
== hello.hs
{{{#!hs
main = putStrLn "Hello world"
}}}
== Run it
{{{
$ runhaskell hello.hs > /dev/full ; echo $?
hello.hs: <stdout>: hPutChar: resource exhausted (No space left on device)
1
}}}
That looks good! We tried to save the output to a file but the disk was
full, so we got an error message, and a process exit code indicating
failure.
== Run it compiled
{{{
$ ghc hello.hs
$ ./hello > /dev/full ; echo $?
0
}}}
Not good! The error was silently ignored, and additionally the process
lied when it reported a successful exit status.
Why did it behave differently when compiled? When `runhaskell` is used,
the buffering of stdout is `NoBuffering` therefore the putStrLn call
fails. But when compiled, stdout is in `LineBuffering` mode and therefore
the putStrLn call succeeds.
The fix:
== hello2.hs
{{{#!hs
import System.IO
main = do
putStrLn "Hello world"
hClose stdout
}}}
== Run it compiled
{{{
$ ghc hello2.hs
$ ./hello2 > /dev/full ; echo $?
hello: <stdout>: hClose: resource exhausted (No space left on device)
1
}}}
Looks good! But there's a catch:
{{{
$ runhaskell hello2.hs ; echo $?
Hello world
ghc: <stdout>: hFlush: illegal operation (handle is closed)
1
}}}
Now our program fails to run correctly with `runhaskell` :(
It seems that `runhaskell` is running some hidden code after main
finished. It is not clear to me how to write a correct "Hello World" that
works both compiled and with `runhaskell`.
== Summary
One of the greatest things about Haskell is that short, clear and concise
programs can also be correct.
It is my opinion that the original "hello.hs" should Just Work™. Haskell
programmers shouldn't have to know that they need to always close stdout
before exiting. Especially since it's not even clear how to do it
properly...
Thank you!
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11836>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list