Subject: _SP_ueber, *terminal-io* and bad situations

From: [email-masked] (Joerg-Cyril Hoehle)
Date: Wed, 1 Feb 95 11:13:57 +0100

Hi,

Tonight I investigated the bug that makes CLISP go into an endless loop
when I use kill-process in EMACS on the Amiga. What EMACS does is to send
the process a ctrl-c and to close the pipe through which it communicates
with the inferior process. Clausing the pipe makes its readers get EOF and
writers get an error.

When I traced CLISP, it managed to reach the quit() function (1). There it
unwind()s all frames and finally wants to do a fresh_line() (and print the
exit message). Printing a newline (or if no newline is printed, printing
O(bye_string)) causes an error in wr_ch_handle(), fehler_unwritable(),
that CLISP wants to write to *terminal-io*, which will again give an
error.

I didn't trace all what happens from there on, but after _some_ time,
CLISP enters reset() in a bad state: Namely SP is below SP_bound, so that
SP_ueber() is called which will in turn call reset() which will call
unwind(). However, the SP retrieved in unwind() is itself below SP_bound
so that it doesn't help and we come to the situation where CLISP is in the
infinite loop.

I think several things are involved here. First the fact that CLISP
happens to go through fehler() in quit() after all the frames have been
disestablished and is about to go, second the fact that it's possible to
have unwind() go somewhere that remains below SP_bound. I don't know if
the latter is triggered by the former. Third that there's a possibility to
get into an endless {write/error}*/reset loop.

I believe that this could happen on any system that is flexible enough for
a continuous write error to happen on stdout. E.g. send output to a file
and then chmod it to read-only. In this case I get an OS_error() instead
of fehler_unwritable() and CLISP enters an infinite OS_error()/
write_char() loop until SP_ueber() is called. Then reset() jumps to the
top-level driver and the write/error/write loop starts once again.

Maybe a first fix would be to make the final fresh_line and bye_string in
CLISP dependent on final_exitcode. However SYS::%EXIT allows one to set
that code (although undocumented).

(1) I believe this was the case because I was at top-level. Otherwise,
CLISP would have printed the prompt for the next lower level and entered
the write/error loop. The above fix would be of no help.

 	Joerg Hoehle.
[email-masked]