[erlang-questions] Unused local function kills the process when the code updates

Ivan Glushkov ivan.glushkov@REDACTED
Wed Jan 9 09:29:31 CET 2013


Hi there.

I do know that using long-lived local function is not a good idea, but
I'm a bit concerned about the following behavior.

I have a small example:
$ cat my.erl
-module(my).
%-export([foo/0]).
-export([ start/0, loop/1 ]).

start() -> register(?MODULE, spawn_link(?MODULE, loop, [fun logger/2])).

%foo() -> apply(fun erlang:now/0, []).

loop(Logger) ->
    receive V ->
            io:format("received ~p~n", [V]),
            ?MODULE:loop(Logger)
    after 100 -> ?MODULE:loop(Logger)
    end.

logger(Msg, Args) -> io:format(Msg, Args).


You see, here I save 'fun logger/2' into a loop state, and I don't use
it anymore.
Then if I do the following steps:
- compile and load the code
- start loop
- uncomment foo
- compile and load the code twice

it kills my process.

I would understand such a behavior if I didn't use fully qualified
name for the 'loop' function. But I do.
Actually, the same thing is happened if I use a gen_server instead of
loop, and save my variable in it's state.

I've done some research and compiled to assembler both versions of the
code (attached).
The only valuable difference (beside adding 'foo' surely) is the labels:

1. where the anonymous function 'fun logger/2' is defined:
-{function, '-start/0-fun-0-', 2, 14}.
-  {label,13}.
+{function, '-start/0-fun-0-', 2, 16}.
+  {label,15}.
     {line,[{location,"my.erl",5}]}.
     {func_info,{atom,my},{atom,'-start/0-fun-0-'},2}.
-  {label,14}.
-    {call_only,2,{f,8}}.
+  {label,16}.
+    {call_only,2,{f,10}}.

2. where it is used to create a 'Logger' variable:
-    {make_fun2,{f,14},0,0,0}.
+    {make_fun2,{f,16},0,0,0}.

3. where the logger function itself is defined:
-{function, logger, 2, 8}.
-  {label,7}.
+{function, logger, 2, 10}.
+  {label,9}.
     {line,[{location,"my.erl",16}]}.
     {func_info,{atom,my},{atom,logger},2}.
-  {label,8}.
+  {label,10}.
     {line,[{location,"my.erl",16}]}.
     {call_ext_only,2,{extfunc,io,format,2}}.

4. and of course the total number of labels:
-{labels, 15}.
+{labels, 17}.

I'm not an expert in the field, but it seems to me that this is not a
great deal. Function signature hasn't been changed, I mean name and
arity. Why does it break my code?

What concerns me is that if for some reason I'm saving some opaque
values (received from the user) in my gen_server state, I can't be
sure that it won't break my code _even if it isn't used_.
I'm almost sure it's a incorrect behavior.

Best,
Ivan.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: files.zip
Type: application/zip
Size: 1901 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130109/27ca9e6b/attachment.zip>


More information about the erlang-questions mailing list