Erlang, Is it possible to reload or upgrade a nif library without restart the shell?
Asked Answered
B

2

7

I have a nif library and every time i recompile it, I must restart the shell to reload or upgrade this library.

Here is my erlang code:

-module(q4).
-export([init/0]).

-on_load(init/0).


init() ->
    erlang:load_nif("./q4_nif", reload).

Every time i compile the erlang module, this error occurs:

`The on_load function for module q4 returned {error,
                                         {upgrade,
                                          "Upgrade not supported by this NIF library."}}`

and when i call init/0 function, this error occurs: {error,{reload,"Reload not supported by this NIF library."}}

Is there anyway to fix this problem and load new nif library without restarting the shell?

Blackett answered 30/10, 2015 at 0:15 Comment(1)
Erlang/OTP 20.0-rc1: "The NIF library reload is not supported anymore." FYI.Lindsay
B
6

As the error message indicates, you need to provide an upgrade function in your NIF, which you specify in your call to ERL_NIF_INIT:

ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)

The upgrade function is documented in the erl_nif man page.

Balladeer answered 30/10, 2015 at 0:36 Comment(2)
I filled this arguments and above errors fixed but still erlang vm not loads new nif version and uses the older version.Blackett
In an Erlang 17 or 18 shell, when I reload an Erlang module, call it foo for example, that uses on_load to load a NIF, the upgrade function in the NIF runs. Type l(foo). or c(foo).` in the shell and the upgrade function is invoked and everything reloads properly, which is exactly what should happen. If you're seeing "reload not supported" errors, this means you're calling a function in your already-loaded Erlang module that is then trying to reload your NIF, and you shouldn't do that. Make sure your NIF has an upgrade function, and use l(your_module). to reload both the module and NIF.Balladeer
R
2

UPDATE Root cause found

It appears delete must called twice before hot-reloading NIFs. This seems like a erlang bug.

force_upgrade_module(Mod) ->
  true == code:purge(Mod),
  true == code:delete(Mod),
  code:purge(Mod),
  code:delete(Mod),
  {module,Mod} == code:load(Mod).

Even with implementing upgrade in ERL_NIF_INIT, there are still some issues that may or may not be platform-specific. For example, on macOS: feel free to delete the priv/{{module}}.so after calling load_nif in the erlang stub module and it will just continue silently succeed and not really reload the NIF .so.

Rydder answered 2/5, 2017 at 5:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.