Re: Infinite loop in the toplevel handler
Matthew Fluet <[email protected]>
| Newsgroups | gmane.comp.lang.ml.mlton.devel |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Sep 14, 2010 at 5:45 AM, Nicolas Bertolotti < [email protected]> wrote: > 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? > Turns out the issue is quite simple. In <src>/basis-library/mlton/exn.sml, we have the default top-level handler: val message = PrimitiveFFI.Stdio.print val defaultHandler = fn exn => (message (concat ["unhandled exception: ", exnMessage exn, "\n"]) ; (case history exn of [] => () | l => (message "with history:\n" ; List.app (fn s => message (concat ["\t", s, "\n"])) l)) ; Exit.exit Exit.Status.failure) The PrimitiveFFI.Stdio.print function comes from <src>/runtime/basis/Stdio.c: void Stdio_printStderr (String8_t s) { uintmax_t size = GC_getArrayLength ((pointer)s); if (0 == size) return; while (1 != fwrite ((const void*)s, (size_t)size, 1, stderr)) /* nothing */; } void Stdio_print (String8_t s) { Stdio_printStderr (s); } So, the infinite loop is just the while loop that tries to print out the message, but keeps getting back -1 (with errno == EPIPE). It seems reasonable to repeat the write if 0 is returned (a "short" write), but we should only repeat the write if errno == EINTR. And, even then, the only time we use the Stdio_print function is at times of last resort, so it isn't clear that other errors are likely to be recoverable. _______________________________________________ MLton mailing list [email protected] http://mlton.org/mailman/listinfo/mlton