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

Patrik Nyblom <>
Wed Jan 9 12:25:17 CET 2013


Hi,

As you changed the code and reloaded it, your fun, which is held in the 
process belongs to old code. The function signature has changed when you 
changed and loaded the new version of the module. When you reload again, 
you need to purge the old code, which is referenced by your process and  
the process is killed. The fact that the fun has not changed textually 
is only a guarantee if it does no local calls and has no environment. As 
soon as the code changes the fun's will get new signatures as there is a 
hash of the module included in the fun signature, there is no 
optimization to keep fun signatures for this case.

If you want long living fun's just change the fun to a module fun:

register(?MODULE, spawn_link(?MODULE, loop, [fun ?MODULE:logger/2])).


Cheers,
/Patrik
On 01/09/2013 09:29 AM, Ivan Glushkov wrote:
> 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.
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130109/133984e0/attachment.html>


More information about the erlang-questions mailing list