[erlang-questions] funs versus code loading

Sam Bobroff sam@REDACTED
Fri May 13 04:16:09 CEST 2011


Hi all,

I've encountered a situation that makes my brain hurt and I was wondering if
anyone could help me understand it. It's so strange that it may be a bug, if
so please let me know and I'll do whatever groundwork is necessary to get it
tracked down. Anyway on to the situation:

It appears that when:
* Executing a Fun,
* that contains a local function call,
* in a process running in the old code of a module that has both current and
old versions loaded,
* the local function call will sometimes go to the current code and
sometimes go to the old code.

It appears that the decision is based somehow on the content of the code in
the current version.

Obviously an example is in order:

--- begin foo.erl ---
-module(foo).
-ifdef(BODY).
-export([start/0, loop/0]).
start() ->
        register(?MODULE, spawn(?MODULE, loop, [])).
loop() ->
        io:fwrite("loop version ~p\n", [?V]),
        receive
                _ ->
                        F = fun () -> loop() end,
                        F()
        end.
-endif.
--- end foo.erl ---

Armed with this file, we can do this:

$ erl
Erlang R14B02 (erts-5.8.3) [source] [smp:4:4] [rq:4] [async-threads:0]
[hipe] [kernel-poll:false]

Eshell V5.8.3  (abort with ^G)
1> compile:file("foo", [{d,'BODY'}, {d,'V',1}]).
{ok,foo,[]}
2> foo:start().
loop version 1
true
3> compile:file("foo", [{d,'BODY'}, {d,'V',2}]).
{ok,foo,[]}
4> code:load_file(foo).
{module,foo}
5> foo ! x.
loop version 2
x

The local function call in the Fun has called from the old version into the
current version of the module (not what I expected).
Run the same sequence again but this time load a module that is empty:

$ erl
Erlang R14B02 (erts-5.8.3) [source] [smp:4:4] [rq:4] [async-threads:0]
[hipe] [kernel-poll:false]

Eshell V5.8.3  (abort with ^G)
1> compile:file("foo", [{d,'BODY'}, {d,'V',1}]).
{ok,foo,[]}
2> foo:start().
loop version 1
true
3> compile:file("foo", [{d,'V',2}]).
{ok,foo,[]}
4> code:load_file(foo).
{module,foo}
5> foo ! x.
loop version 1
x

The local function call in the Fun has stayed in the old version of the
module (actually what I expected).

Some changes other than emptying the body of the module seem to have a
similar effect but I haven't tracked down exactly what the trigger is.

My system is Ubuntu 11.04 running Erlang R14B02 and I haven't yet checked
older versions of Erlang for the same behaviour.

Thanks,
Sam.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110513/5284610d/attachment.htm>


More information about the erlang-questions mailing list