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

Mikael Pettersson mikpelinux@REDACTED
Sun Mar 1 21:00:22 CET 2015


Steve Vinoski writes:
 > 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.

Yes, at the top-level of a NIF you can indicate that the call to that NIF
should fail with an Erlang-level exception, and the underlying mechanism
is the same as the one for BIF calls.

What I was talking about are the even lower-level enif_make_*() functions
that, if you look at the current documentation, have no defined way of
signalling errors.

 > Here's a PR that I think addresses the issues raised in this thread:
 > 
 > https://github.com/erlang/otp/pull/632

Yes, well here you do introduce that possibility.  Good.

/Mikael

 > 
 > --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
 > >

-- 



More information about the erlang-bugs mailing list