GHC throws IOError on Win32 when there is no console

Hi, I noticed on Windows that when I use IO functions that write to stdout when the process is lacking a console, those functions throw an IOError. I'm not sure if this also occurs for stderr because I haven't tried it. Some classes of processes are created without a console because they never interact with the user and include System services. Crashing with IOError in this case is difficult to diagnose because because the only symptom is the process crashes with no visible output. I believe the most sensible behaviour should be for those functions to not throw, but instead do nothing. -John

Sorry, I should clarify. I am writing about applications compiled with GHC.
-John
On 2/10/07, John Ky
Hi,
I noticed on Windows that when I use IO functions that write to stdout when the process is lacking a console, those functions throw an IOError. I'm not sure if this also occurs for stderr because I haven't tried it.
Some classes of processes are created without a console because they never interact with the user and include System services. Crashing with IOError in this case is difficult to diagnose because because the only symptom is the process crashes with no visible output.
I believe the most sensible behaviour should be for those functions to not throw, but instead do nothing.
-John

On 09/02/07, John Ky
I noticed on Windows that when I use IO functions that write to stdout when the process is lacking a console, those functions throw an IOError. I'm not sure if this also occurs for stderr because I haven't tried it.
This is Windows standard behaviour. For GUI applications, the handles corresponding to std{in,out,err} are not valid, and attempts to write to them give an error. In general, you shouldn't use these handles in a GUI program. Or if you can't guarantee that the libraries you use won't write to them, redirect them to the null device or a log file. (I'm not saying this is ideal behaviour, but that's how it is...)
I believe the most sensible behaviour should be for those functions to not throw, but instead do nothing.
That's not 100% clear - writing to a log file may be better (I don't like the idea of dropping potentially useful information without any warning - and if the output wasn't useful to *someone*, why was it being written?) Annoyingly, Haskell doesn't seem to provide a way to reopen handles (specifically, the standard ones). You may have to use the FFI and the Windows SetStdHandle API to reset the handles. It probably wouldn't be hard to write a reasonably general wrapper for this, but it's a bit late now so I'll leave that as an exercise :-) Paul. Paul.

On 09/02/07, Paul Moore
It probably wouldn't be hard to write a reasonably general wrapper for this, but it's a bit late now so I'll leave that as an exercise :-)
Sigh. I tried to set this up (using a little external C routine to do the API grunt work) and it doesn't seem to work as I expect. Maybe the C/GHC runtimes do something more complex than just using the API standard handles, maybe I coded something wrong. In theory, this should work. In practice, Haskell may benefit from an equivalent of the C freopen() function (from stdio), which deals correctly with the internals of handles... Paul.

Hi Paul, Can I have your code that doesn't work? I want to fiddle with it a bit. Thanks -John On 2/12/07, Paul Moore
On 09/02/07, Paul Moore
wrote: It probably wouldn't be hard to write a reasonably general wrapper for this, but it's a bit late now so I'll leave that as an exercise :-)
Sigh. I tried to set this up (using a little external C routine to do the API grunt work) and it doesn't seem to work as I expect. Maybe the C/GHC runtimes do something more complex than just using the API standard handles, maybe I coded something wrong.
In theory, this should work. In practice, Haskell may benefit from an equivalent of the C freopen() function (from stdio), which deals correctly with the internals of handles...
Paul.

On Sat, 2007-02-10 at 09:32 +1100, John Ky wrote:
Hi,
I noticed on Windows that when I use IO functions that write to stdout when the process is lacking a console, those functions throw an IOError. I'm not sure if this also occurs for stderr because I haven't tried it.
Some classes of processes are created without a console because they never interact with the user and include System services. Crashing with IOError in this case is difficult to diagnose because because the only symptom is the process crashes with no visible output.
I believe the most sensible behaviour should be for those functions to not throw, but instead do nothing.
I brought this up some time ago with the GHC developers since it is a problem for Windows users who use Gtk2Hs and want to hide the console window. They felt that since this was the default system behaviour that it's best for GHC not to override that. C programs apparently suffer from the same problem (possibly depending on the variant of the C lib). The situation is much improved from when I originally complained about this. It does now at least display an message box with the error rather than silently terminating. If there is a reliable way to 'fix' the standard handles (as Paul Moore suggests) when running without a console then I could include that code into the Gtk2Hs startup and then make -optl-mwindows the default for progs compiled with Gtk2Hs. Duncan

Hi Duncan, Thanks for your comments. In the context of a haskell process running as a Windows service, a message box is useless, because Haskell services do not have a GUI and cannot interact with the desktop. -John

On Sat, 2007-02-10 at 23:46 +1100, John Ky wrote:
Hi Duncan,
Thanks for your comments. In the context of a haskell process running as a Windows service, a message box is useless, because Haskell services do not have a GUI and cannot interact with the desktop.
Good point. Perhaps you can persuade the people who look after GHC on win32 to have it use the Windows debug log service for exception messages like that when there's no GUI available. Of course if you can code up and submit such a patch yourself then even better. Duncan

Hi
Good point. Perhaps you can persuade the people who look after GHC on win32 to have it use the Windows debug log service for exception messages like that when there's no GUI available. Of course if you can code up and submit such a patch yourself then even better.
Does anyone read that? Wouldn't a message box be better? Thanks Neil

On Sun, 2007-02-11 at 17:18 +0000, Neil Mitchell wrote:
Hi
Good point. Perhaps you can persuade the people who look after GHC on win32 to have it use the Windows debug log service for exception messages like that when there's no GUI available. Of course if you can code up and submit such a patch yourself then even better.
Does anyone read that? Wouldn't a message box be better?
The point would be only to do that when there is no GUI available, eg when running as a service. Otherwise, the message box is indeed better. Duncan

Duncan Coutts wrote:
On Sat, 2007-02-10 at 23:46 +1100, John Ky wrote:
Hi Duncan,
Thanks for your comments. In the context of a haskell process running as a Windows service, a message box is useless, because Haskell services do not have a GUI and cannot interact with the desktop.
Good point. Perhaps you can persuade the people who look after GHC on win32 to have it use the Windows debug log service for exception messages like that when there's no GUI available. Of course if you can code up and submit such a patch yourself then even better.
Sounds like a good idea. You need to look at rts/RtsMessages.c, in particular rtsErrorMsgFn(), which currently has cases for GUI and non-GUI. I guess it really should have 3 cases: GUI, console, and non-GUI. Cheers, Simon

On 2/13/07, Simon Marlow
Sounds like a good idea. You need to look at rts/RtsMessages.c, in particular rtsErrorMsgFn(), which currently has cases for GUI and non-GUI. I guess it really should have 3 cases: GUI, console, and non-GUI.
The trick here is how to find whether the current application is GUI, console or non-GUI. The distinction between GUI and Console applications is easy because you can check subsystem OS type. This doesn't work with Windows services because they can be either GUI or Console. The OS is preventing them from showing any windows. Cheers, Krasimir

Krasimir Angelov wrote:
On 2/13/07, Simon Marlow
wrote: Sounds like a good idea. You need to look at rts/RtsMessages.c, in particular rtsErrorMsgFn(), which currently has cases for GUI and non-GUI. I guess it really should have 3 cases: GUI, console, and non-GUI.
The trick here is how to find whether the current application is GUI, console or non-GUI. The distinction between GUI and Console applications is easy because you can check subsystem OS type. This doesn't work with Windows services because they can be either GUI or Console. The OS is preventing them from showing any windows.
So then a program which is running as a service should explicitly set a different message handler. Maybe we could provide a handler that sends messages to the system log. Cheers, Simon

Would it be worth opening a Trac bug report or feature request for this? And/or documenting the unexpected behaviour; perhaps here http://haskell.org/haskellwiki/GHC/GUI_programming ? Simon | -----Original Message----- | From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of Duncan | Coutts | Sent: 10 February 2007 11:57 | To: John Ky | Cc: Haskell Cafe | Subject: Re: [Haskell-cafe] GHC throws IOError on Win32 when there is no console | | On Sat, 2007-02-10 at 09:32 +1100, John Ky wrote: | > Hi, | > | > I noticed on Windows that when I use IO functions that write to stdout | > when the process is lacking a console, those functions throw an | > IOError. I'm not sure if this also occurs for stderr because I | > haven't tried it. | > | > Some classes of processes are created without a console because they | > never interact with the user and include System services. Crashing | > with IOError in this case is difficult to diagnose because because the | > only symptom is the process crashes with no visible output. | > | > I believe the most sensible behaviour should be for those functions to | > not throw, but instead do nothing. | | I brought this up some time ago with the GHC developers since it is a | problem for Windows users who use Gtk2Hs and want to hide the console | window. They felt that since this was the default system behaviour that | it's best for GHC not to override that. C programs apparently suffer | from the same problem (possibly depending on the variant of the C lib). | | The situation is much improved from when I originally complained about | this. It does now at least display an message box with the error rather | than silently terminating. | | If there is a reliable way to 'fix' the standard handles (as Paul Moore | suggests) when running without a console then I could include that code | into the Gtk2Hs startup and then make -optl-mwindows the default for | progs compiled with Gtk2Hs. | | Duncan | | _______________________________________________ | Haskell-Cafe mailing list | Haskell-Cafe@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (7)
-
Duncan Coutts
-
John Ky
-
Krasimir Angelov
-
Neil Mitchell
-
Paul Moore
-
Simon Marlow
-
Simon Peyton-Jones