Re: nif reload

Sverker Eriksson <[email protected]>
Newsgroups gmane.comp.lang.erlang.bugs
Message-ID <[email protected]>
On 05/26/2014 01:43 AM, Tony Rogvall wrote:
> Hi!
>
> I have something strange niff stuff going on, I think.
> (tested R17/R16)
>
> I have a very simple demo nif application (attached), one function (not really
> needed) and
> a nif that I want to be able to load/upgrade/unload. I have removed the reload
> callback,
> that according to documentation is deprecated.
>
> Following sequence can be seen, when I repeat the
> > l(niffy).
> from the erlang shell.
>
>
> Eshell V6.1  (abort with ^G)
> 1> niffy:hello().
> Loading: ./niffy/priv/niffy_drv
> c_src/niffy_nif.c:61: niffy_load: *priv_data=0x0 ptr=0x1e1820e8, ptr->n
> c_src/niffy_nif.c:51: niffy_hello: priv_data=0x1e1820e8
> world
> 2> niffy:hello().
> c_src/niffy_nif.c:51: niffy_hello: priv_data=0x1e1820e8
> world
> 3> l(niffy).
> Loading: ./niffy/priv/niffy_drv
> c_src/niffy_nif.c:72: niffy_upgrade: *priv_data=0x0 *old_priv_data=0x1e1820e8
> ptr->n=1
> {module,niffy}
> 4> niffy:hello().
> c_src/niffy_nif.c:51: niffy_hello: priv_data=0x1e1820e8
> world
> 5> l(niffy).
> c_src/niffy_nif.c:81: niffy_unload: priv_data=0x1e1820e8 ptr->n=2
> Loading: ./niffy/priv/niffy_drv
> c_src/niffy_nif.c:72: niffy_upgrade: *priv_data=0x0 *old_priv_data=0x1e1820e8
> ptr->n=504889344
> {module,niffy}
> 6>
> 6> l(niffy).
> c_src/niffy_nif.c:81: niffy_unload: priv_data=0x1e1820e8 ptr->n=504889345
> Loading: ./niffy/priv/niffy_drv
> c_src/niffy_nif.c:72: niffy_upgrade: *priv_data=0x0 *old_priv_data=0x1e1820e8
> ptr->n=504889344
> {module,niffy}
> 7> l(niffy).
> c_src/niffy_nif.c:81: niffy_unload: priv_data=0x1e1820e8 ptr->n=504889345
> Segmentation fault: 11
>
> I can see that the unload is called and I free the priv_data, then upgrade is
> called on that very same memory.
> But why?
>

Your niffy_upgrade-callback does

*priv_data = *old_priv_data;

which means your old and new module instances share the same data.
You then free that data when the old instance is unloaded which leaves 
the new module with a dangling pointer.

Either copy the data in niffy_upgrade or use reference counting in 
niffy_unload:

if (--ptr->n == 0) {
     enif_free(ptr);
}


/Sverker, Erlang/OTP


_______________________________________________
erlang-bugs mailing list
[email protected]
http://erlang.org/mailman/listinfo/erlang-bugs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.