[erlang-questions] dirty nif and enif_make_badarg()

Steve Vinoski vinoski@REDACTED
Wed May 28 21:46:57 CEST 2014


On Wed, May 28, 2014 at 3:19 PM, Daniel Goertzen
<daniel.goertzen@REDACTED>wrote:

> I am trying to write a dirty nif and am following the directions from
> http://www.erlang.org/doc/man/erl_nif.html
>
> Exceprt:
> "A dirty NIF may not invoke the enif_make_badarg<http://www.erlang.org/doc/man/erl_nif.html#enif_make_badarg>to raise an exception. If it wishes to return an exception, the dirty NIF
> should pass a regular result indicating the exception details to its
> finalizer, and allow the finalizer to raise the exception on its behalf."
>
> So I am doing this; here is my finalizer....
>
>
> // cached atoms
> ERL_NIF_TERM badarg;
>
> static ERL_NIF_TERM badarg_finalizer(ErlNifEnv* env, ERL_NIF_TERM term)
> {
>     if(term == badarg)
>         return enif_make_badarg(env);
>     else
>         return term;
> }
>
> ... and I end up with the exception context of the finalizer and not the
> nif as desired...
>
>
> 5> generate_rsa:generate_rsa_key(abc, 65537).
> entering generate_rsa_key_nif
>                              entering generate_rsa_key_nif_dirty
>                                                                 entering
> badarg_finalizer
>
> ** exception error: bad argument
>      in function  generate_rsa:generate_rsa_key_nif/2
>         called as
> generate_rsa:generate_rsa_key_nif(badarg,18446744072346624528)   *!!!
> should be (abc,65537)*
>      in call from generate_rsa:generate_rsa_key/2 (src/generate_rsa.erl,
> line 25)
>
>
> The documentation implies I can provide the "exception details", but
> enif_make_badarg() doesn't offer any extra parameters.  Is there some other
> way to set the "exception details"?
>

"Exception details" here is just general, meaning whatever kinds of error
information you want the finalizer to return. A NIF can raise only badarg
via enif_make_badarg(), and there's no way for it to control any parameters
associated with the exception. You might instead consider wrapping the NIF
function with an actual Erlang function in your module, treating the NIF
like an internal (non-exported) function, having the finalizer return an
error tuple containing relevant information, and letting Erlang raise an
exception based on that info.

--steve
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140528/9ae94cfe/attachment.htm>


More information about the erlang-questions mailing list