Re: enif_make_double returns invalid term for 'nan'
Steve Vinoski <[email protected]>
| Newsgroups | gmane.comp.lang.erlang.bugs |
|---|---|
| Message-ID | <CAO+zUOVpAqveP4kRgKizVc-=Q3WaR9bVcExS05whHvfaBpCpjA@mail.gmail.com> |
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 <[email protected]> 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 > > [email protected] > > > > > > > > > On Mar 1, 2015, at 13:02, Mikael Pettersson <[email protected]> > 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 > [email protected] > http://erlang.org/mailman/listinfo/erlang-bugs > _______________________________________________ erlang-bugs mailing list [email protected] http://erlang.org/mailman/listinfo/erlang-bugs