[erlang-questions] Are binaries relocatable?

Sverker Eriksson sverker.eriksson@REDACTED
Fri Aug 29 15:02:28 CEST 2014


On 08/28/2014 03:09 PM, Hynek Vychodil wrote:
> Hi all,
> I would like to know if binaries are relocatable. If I have binary parameter
>
>      ErlNifBinary bin;
>      if (!enif_inspect_binary(env, argv[0], &bin))
>          return enif_make_badarg(env);
>
> I store binary in mine own environment
>
>      ErlNifEnv *priv_env = enif_alloc_env();
>      enif_make_copy(priv_env, argv[0]);
>
> Can I then rely on bin.data pointing into same memory until I free
> enif_free_env(priv_env) ?
No.
Your bin.data is refering to the original term argv[0] in 'env' which is 
only valid until the NIF returns.
You must do enif_inspect_binary on the copy in order to get a safe 
pointer that is valid until you do enif_free_env(priv_env).


>   I'm asking because I would like to avoid copying
> and share data or even return it using enif_make_resource_binary to catch
> and
> count references.
Whether a copied binary share data with its original is implementation 
dependent. Today big binaries (>64 bytes) are shared
and small binaries are copied between environments.

> I have code which makes copy of binary data but when I switch to reference
> bin.data it hangs whole VM. I would like to know if I make some mistake in
> mine code and it should work or it is wrong idea at all.
>
>
There is a known bug when calling enif_make_copy after enif_inspect_binary
that can cause the binary to get reallocated and thus the bin.data 
pointer to get invalid
before the NIF returns. To detect this bug, you can call 
enif_inspect_binary(env,argv[0],&bin2)
after enif_make_copy and check if bin2.data != bin.data.

This bug has been lingering as I thought it was an exotic scenario 
(apparently not) and I have
been a bit unsure how to fix it without ruin performance.


/Sverker, Erlang/OTP




More information about the erlang-questions mailing list