Friedhelm Wrensch <fwr@softi> writes:
> I really enjoy the new release. But there are some minor problems
> regarding the handling of SIGINT (Control-C).
>
> "runhugs" does not react to SIGINT. "hugs" restarts "Main.main", which makes
> no sense to me.
>
> Platform: Linux 2.0.0
> Compiler: gcc 2.7.2
> Libraries:
> libm.so.5 => /lib/libm.so.5.0.5
> libdl.so.1 => /lib/libdl.so.1.7.14
> libc.so.5 => /lib/libc.so.5.2.18
Whilst I never saw this behaviour while I was working on Hugs,
interrupts have been a problem on Linux for some time. That is,
hitting ctrl-C once would stop a Haskell evaluation but restarting (or
running something else) and hitting ctrl-C again would not stop it.
I believe the problem is that Hugs relies on a property of signal
handling that is not required by POSIX or ANSI C and does not hold on
some platforms. Windows {3.1,95,NT} are three such platforms and
Linux is perhaps another. The question is:
Is it safe to longjmp out of a signal handler?
On some platforms, it is not safe because signal handlers are run in a
separate thread from normal evaluation. Longjmping from one thread's
stack to another is dubious at best.
On POSIX platforms, it is dubious because POSIX requires some signals
to be disabled while handling a signal and reenabled when the signal
handler returns. If the handler never returns, it's not clear when
the signal can be reenabled.
It is possible to test this theory by editing hugs/src/prelude.h.
Just replace "IS_WIN32" with "1", recompile and see if things get
better. If they do, the current Hugs maintainers can probably fix it
by replacing "IS_WIN32" with something like "(IS_WIN32 | __POSIX__)"
or, if they feel energetic, produce an autoconf test to detect these
problems.
/* On Unix (and almost every other system), the interrupt handlers perform
* a longjmp to break out of the current computation.
* On Win32 this does not work because the interrupt handler is run in
* a separate thread from the main computation. Instead we set a
* flag (the global variable "broken") to request an interrupt and
* all potentially infinite loops of the evaluator check the flag using
* the "allowBreak" call.
*/
#define HANDLERS_CANT_LONGJMP IS_WIN32
Another possible solution would be to build Hugs using the BSD signal
library which has a simpler semantics and, perhaps, a simpler
implementation. However, I don't know how to do this.
Oh yes, one other related fact: I have a vague memory that the GNU
readline library doesn't handle interrupts too well (or it doesn't
like the way we react). If you configured Hugs --with-readline, you
might try reconfiguring without just to see if it is a factor.
Alastair
ps Julian: this shouldn't be a problem for the Hugs-STG system since it
does not longjmp out of signal handlers during Haskell evaluation or
(I think) out of Haskell compilation.