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

Patrik Nyblom pan@REDACTED
Mon Jan 14 16:33:55 CET 2013


On 01/09/2013 09:18 PM, Ivan Glushkov wrote:
> Thank you for the answer, Patric.
> You mean there's no way to get the local function saved if it has smth
> like "io:format" call in it?
> It will always kill the process after the second code update, won't it?
> Ivan.
Yes, that's right. The "module-fun" is there to solve exactly that 
problem (among others).

Cheers,
/Patrik
>
> On Wed, Jan 9, 2013 at 3:25 PM, Patrik Nyblom <pan@REDACTED> wrote:
>> 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
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>




More information about the erlang-questions mailing list