<div dir="ltr">Hi Mikael,<div><br></div><div><div>I don't understand your message, so perhaps I'm missing something -- the erl_nif functions have had the ability to throw badarg for quite some time now.</div><div><br></div><div>Here's a PR that I think addresses the issues raised in this thread:</div><div><br></div><div><a href="https://github.com/erlang/otp/pull/632">https://github.com/erlang/otp/pull/632</a></div><div><br></div><div>--steve </div></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Mar 1, 2015 at 12:34 PM, Mikael Pettersson <span dir="ltr"><<a href="mailto:mikpelinux@gmail.com" target="_blank">mikpelinux@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Heinz Nikolaus Gies writes:<br>
 > Hi Mikael,<br>
 > thank for the clarification. That makes sense, I find 2) actually more troublesome since I went to consult the documents to be sure it’s not a defined behavior. What was a bit more concerning was that that it returned a value that breaks transparently breaks other erlang functions.<br>
 ><br>
 > Perhaps simply returning a bad_arg would make a lot more sense?<br>
<br>
</span>Erlang-level exceptions don't exist at this level of the VM.  They have to<br>
be synthesized explicitly, and doing that requires documented protocols<br>
for signalling errors, and code to follow them.<br>
<br>
E.g., the interface to BIFs is such that to signal badarg, the BIF:<br>
1. stores a special flag in the current process struct, and<br>
2. returns THE_NON_VALUE.<br>
<br>
The caller, beam_emu.c or native code wrappers in hipe_${arch}_bifs, checks<br>
for THE_NON_VALUE returns and branches to the exception-raising code.<br>
<br>
The problem here is that we're in even lower-level code, and there is no<br>
documentation that enif_make_*() can fail, how to detect such failures,<br>
or what to do in response.  Once this is in place, the next problem is<br>
to ensure that NIFs are properly updated and not just recompiled.<br>
<span class=""><br>
 > ---<br>
 > Cheers,<br>
 > Heinz Nikolaus Gies<br>
 > <a href="mailto:heinz@licenser.net">heinz@licenser.net</a><br>
 ><br>
 ><br>
 ><br>
 > > On Mar 1, 2015, at 13:02, Mikael Pettersson <<a href="mailto:mikpelinux@gmail.com">mikpelinux@gmail.com</a>> wrote:<br>
 > ><br>
 > > Heinz Nikolaus Gies writes:<br>
 > >> When enif_make_double gets a nan value passed as the double argument it returns a invalid term, this term can neither be printed (via the fmt*) functions nor can it be deserialized by binary_to_term when serializing it the following binary is generated:<br>
 > >><br>
 > >> 6> io:format("~p~n", [term_to_binary(V)]).<br>
 > >> <<131,99,110,97,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>><br>
 > >><br>
 > >> V is the double returned by enif_make_double<br>
 > ><br>
 > > There are two issues here:<br>
 > > 1. the VM disallows INFs and NANs, but NIF authors may not be aware of that<br>
 > > 2. enif_make_double() SHOULD reject non-finite doubles but it doesn't, and<br>
 > >   its documentation doesn't mention any failure modes; returning THE_NON_VALUE<br>
 > >   may not be detected as a failure by the NIF and so this non-value may leak<br>
 > >   into aggregates (lists or tuples) where it will totally break things<br>
 > ><br>
 > > When looking at this I noticed that enif_make_atom() also has problems: it<br>
 > > may fail and return THE_NON_VALUE if the resulting atom would be too long,<br>
 > > but the documentation doesn't mention this possibility so the NIF might<br>
 > > continue and store this non-value in aggregates before returning.<br>
 > ><br>
 > > The OTP folks need to straighten up error handling in the enif_make_*()<br>
 > > functions.<br>
 ><br>
</span> > xapplication/pgp-signature [Click mouse-2 to save to a file]<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
erlang-bugs mailing list<br>
<a href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-bugs" target="_blank">http://erlang.org/mailman/listinfo/erlang-bugs</a><br>
</div></div></blockquote></div><br></div>