On Tue, Sep 14, 2010 at 5:45 AM, Nicolas Bertolotti <span dir="ltr">&lt;<a href="mailto:Nicolas.Bertolotti@mathworks.fr">Nicolas.Bertolotti@mathworks.fr</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div link="blue" vlink="purple" lang="FR"><div>











<span lang="EN-US">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.</span>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">I tried to fix the issue in
basis-library/mlton/exn.sml but I could not manage to eliminate the issue:</span></p>

<p><span lang="EN-US"><span>-<span style="font: 7pt &quot;Times New Roman&quot;;">         
</span></span></span><span lang="EN-US">The exceptions that may occur
in the call to “message” seem to be properly handled</span></p>

<p><span lang="EN-US"><span>-<span style="font: 7pt &quot;Times New Roman&quot;;">         
</span></span></span><span lang="EN-US">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.</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">Any thought?</span></p></div></div></blockquote><div><br>Turns out the issue is quite simple.  In &lt;src&gt;/basis-library/mlton/exn.sml, we have the default top-level handler:<br>
<br>         val message = PrimitiveFFI.Stdio.print<br>         val defaultHandler = fn exn =&gt;<br>            (message (concat [&quot;unhandled exception: &quot;, exnMessage exn, &quot;\n&quot;])<br>             ; (case history exn of<br>
                   [] =&gt; ()<br>                 | l =&gt;<br>                      (message &quot;with history:\n&quot;<br>                       ; List.app (fn s =&gt; message (concat [&quot;\t&quot;, s, &quot;\n&quot;])) l))<br>
             ; Exit.exit Exit.Status.failure)<br> <br>The PrimitiveFFI.Stdio.print function comes from &lt;src&gt;/runtime/basis/Stdio.c:<br><br>void Stdio_printStderr (String8_t s) {<br>  uintmax_t size = GC_getArrayLength ((pointer)s);<br>
  if (0 == size)<br>    return;<br>  while (1 != fwrite ((const void*)s, (size_t)size, 1, stderr))<br>    /* nothing */;<br>}<br><br>void Stdio_print (String8_t s) {<br>  Stdio_printStderr (s);<br>}<br><br>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 &quot;short&quot; 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&#39;t clear that other errors are likely to be recoverable.<br>
<br></div></div>