[erlang-bugs] enif_make_double returns invalid term for 'nan'

Steve Vinoski vinoski@REDACTED
Sun Mar 1 19:38:19 CET 2015


Hi Mikael,

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.

Here's a PR that I think addresses the issues raised in this thread:

https://github.com/erlang/otp/pull/632

--steve


On Sun, Mar 1, 2015 at 12:34 PM, Mikael Pettersson <mikpelinux@REDACTED>
wrote:

> Heinz Nikolaus Gies writes:
>  > Hi Mikael,
>  > 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.
>  >
>  > Perhaps simply returning a bad_arg would make a lot more sense?
>
> Erlang-level exceptions don't exist at this level of the VM.  They have to
> be synthesized explicitly, and doing that requires documented protocols
> for signalling errors, and code to follow them.
>
> E.g., the interface to BIFs is such that to signal badarg, the BIF:
> 1. stores a special flag in the current process struct, and
> 2. returns THE_NON_VALUE.
>
> The caller, beam_emu.c or native code wrappers in hipe_${arch}_bifs, checks
> for THE_NON_VALUE returns and branches to the exception-raising code.
>
> The problem here is that we're in even lower-level code, and there is no
> documentation that enif_make_*() can fail, how to detect such failures,
> or what to do in response.  Once this is in place, the next problem is
> to ensure that NIFs are properly updated and not just recompiled.
>
>  > ---
>  > Cheers,
>  > Heinz Nikolaus Gies
>  > heinz@REDACTED
>  >
>  >
>  >
>  > > On Mar 1, 2015, at 13:02, Mikael Pettersson <mikpelinux@REDACTED>
> wrote:
>  > >
>  > > Heinz Nikolaus Gies writes:
>  > >> 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:
>  > >>
>  > >> 6> io:format("~p~n", [term_to_binary(V)]).
>  > >>
> <<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>>
>  > >>
>  > >> V is the double returned by enif_make_double
>  > >
>  > > There are two issues here:
>  > > 1. the VM disallows INFs and NANs, but NIF authors may not be aware
> of that
>  > > 2. enif_make_double() SHOULD reject non-finite doubles but it
> doesn't, and
>  > >   its documentation doesn't mention any failure modes; returning
> THE_NON_VALUE
>  > >   may not be detected as a failure by the NIF and so this non-value
> may leak
>  > >   into aggregates (lists or tuples) where it will totally break things
>  > >
>  > > When looking at this I noticed that enif_make_atom() also has
> problems: it
>  > > may fail and return THE_NON_VALUE if the resulting atom would be too
> long,
>  > > but the documentation doesn't mention this possibility so the NIF
> might
>  > > continue and store this non-value in aggregates before returning.
>  > >
>  > > The OTP folks need to straighten up error handling in the
> enif_make_*()
>  > > functions.
>  >
>  > xapplication/pgp-signature [Click mouse-2 to save to a file]
>
> --
> _______________________________________________
> erlang-bugs mailing list
> erlang-bugs@REDACTED
> http://erlang.org/mailman/listinfo/erlang-bugs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20150301/47a33d28/attachment.htm>


More information about the erlang-bugs mailing list