[erlang-questions] Loading Object Code Contained in a Binary

54 views
Skip to first unread message

Vance Shipley

unread,
Jul 23, 2012, 1:40:14 AM7/23/12
to erlang-q...@erlang.org
I am dynamically contructing abstract forms representing modules
and loading them into the code server using code:load_binary/3.

I find that if I load a new version of the module multiple times
code:load_binary/3 does not complain about previous versions not
being purged. If I use erlang:load_module/2 it does complain.
The documentation warns that this BIF is intended for the code
servers and should not be used elsewhere.

What kind of trouble am I likely to get into doing this?

Should I use erlang:load_module/2 instead of code:load_binary/3?

--
-Vance
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Samuel

unread,
Jul 23, 2012, 3:09:21 AM7/23/12
to Vance Shipley, erlang-q...@erlang.org
> I find that if I load a new version of the module multiple times
> code:load_binary/3 does not complain about previous versions not
> being purged. If I use erlang:load_module/2 it does complain.
> The documentation warns that this BIF is intended for the code
> servers and should not be used elsewhere.
>
> What kind of trouble am I likely to get into doing this?

The usual problem of getting processes killed if a new version of the
code is loaded when they are running old code. Suppose I write a
module lopp (I mistyped the name and was too lazy to correct it :) )

-module(lopp).
-compile(export_all).

start_link() ->
spawn_link(fun() -> loop() end).

loop() ->
timer:sleep(1000),
io:format("."),
loop().

foo() -> bar.

And then start the shell and read the beam into Lopp:

9> lopp:start_link().
<0.101.0>
.......40> code:load_binary(lopp, "no_file", Lopp).
{module,lopp}
..41> code:load_binary(lopp, "no_file", Lopp).
** exception exit: killed


You can be a bit more careful and purge the code yourself before
attempting to load the new version:

42> lopp:start_link().
<0.106.0>
......43> code:soft_purge(lopp).
true
.....44> code:delete(lopp).
true
.....45> code:load_binary(lopp, "no_file", Lopp).
{module,lopp}
...46> code:soft_purge(lopp).
false %% Here we know there is old code that cannot be replaced
.....47> code:delete(lopp).

=ERROR REPORT==== 23-Jul-2012::08:53:27 ===
Module lopp must be purged before loading

false


If you use code:soft_purge you should never kill processes that are
running old code. But if you want to, you can then use code:purge.

A small caveat is that the code can be reloaded between your call to
code:delete and code:load_binary, which can be a problem if you are
not running in embedded mode:


65> lopp:start_link().
<0.145.0>
.....66> code:soft_purge(lopp).
true
......67> code:delete(lopp).
true
...68> lopp:foo().
bar
..........69> code:load_binary(lopp, "no_file", Lopp).
** exception exit: killed


I don't know a way of doing that atomically, I would like a version of
code:load_binary that refuses to load when there is code already
running in the system.

Best
--
Samuel
Reply all
Reply to author
Forward
0 new messages