Infinite loop in the toplevel handler

Nicolas Bertolotti <[email protected]>
Newsgroups gmane.comp.lang.ml.mlton.devel
Message-ID <8320D98DA9A5C54C926D397795FE7CEA845A36EEEC@EXCHANGE-UK.ad.mathworks.com>
Hello,

In some cases, the toplevel handler may enter an infinite loop. This can be highlighted using the following sample code :
structure Main =
struct
    fun main() =
        let
            val _ = MLton.Signal.setHandler(Posix.Signal.pipe, MLton.Signal.Handler.ignore);
            fun loop(i) =
                (TextIO.output(TextIO.stdErr, (Int.toString(i)) ^ "\n");
                 if i <= 0 then
                     ()
                 else
                     (Posix.Process.sleep(Time.fromSeconds(1));
                      loop(i - 1)));
        in
            loop(10);
            OS.Process.success
        end
        handle _ => (TextIO.output(TextIO.stdErr, "Exception raised\n");
                     OS.Process.failure)

    val _ = OS.Process.exit(main());
end;

If you do the following (linux platform):
$ mlton -output test test.sml
$ ./test 2>&1 | tee log.txt
And, in another console (within 10 seconds) :
$ strace -p `ps -auxwww | grep test | grep -v grep | awk '{ print $2 }'` > toto.log 2>&1 & kill `ps -auxwww | grep tee | grep log | awk '{ print $2 }'`
(in order to log a "strace" of the process in "toto.log" and kill the "tee" process so that the standard error of the process becomes unaccessible)
the process then enters an infinite loop.

The "strace" log shows the following messages:
"
Process 27026 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
write(2, "8\n"..., 2)                   = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(2, "Exception raised\n"..., 17)   = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(2, "unhandled exception: Io: outp"..., 86) = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(2, "unhandled exception: Io: outp"..., 86) = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(2, "unhandled exception: Io: outp"..., 86) = -1 EPIPE (Broken pipe)
...
"

I have managed to fix this in my code (simply catch the exception when writing "Exception raised" in the "main" function's exception handler).
Anyway, it is still an issue that I may have on other binaries and some other users may also face.

It appears that, when stderr is not accessible, the toplevel handler which attempts to write its own message generates an exception that causes the infinite loop.

I tried to fix the issue in basis-library/mlton/exn.sml but I could not manage to eliminate the issue:

-          The exceptions that may occur in the call to "message" seem to be properly handled

-          If I add a global ref that I set to true the first time I enter the function and that prevents it from running again, it has no effect.

Any thought?

Thanks in advance

Nicolas


[cid:[email protected]]<http://www.mathworks.fr/>



Accelerating the pace of  engineering and science<http://www.mathworks.fr/>


Nicolas Bertolotti
Senior Development Engineer


2 Rue de Paris
92196 Meudon Cedex
France


[email protected]<mailto:[email protected]>


tel:
fax:

+33.1.41.14.88.55
+33.1.55.64.06.64

_______________________________________________
MLton mailing list
[email protected]
http://mlton.org/mailman/listinfo/mlton
image001.gif (image/gif, 4.4 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.