[erlang-bugs] Undetected undefined remote function calls

Kostis Sagonas kostis@REDACTED
Mon Dec 17 18:37:14 CET 2012


On 12/17/2012 12:42 PM, Ulf Wiger wrote:
>
> Well, in the context of code loading, it is certainly possible, although more than a little weird. :)
>
> The function sys:do_change_code/5 in OTP stdlib specifically relies on calling a function in the newly loaded version of a module, with data from the old version. It is of course calling a function that is well understood in advance, but this is only by convention, and not easily checkable*.

The function in sys is a different case than the one in my mail.  It 
takes Mod an argument and issues a Mod:system_code_change(...) call.
Moreover, it protects this call with a catch. The intention of that code 
is clear -- at least to me.

What the case I sent does is to issue a remote call to a function in a 
module with the same name as the one being compiled whose code is 
nowhere to be found (let alone being listed among the exported 
functions). The only conceivable reason to do this call is that this 
function may possibly exist in some future version of this module. I 
think this may be used to support some cool feature like the ones shown 
in episodes of the Twilight Zone (and thus increase the perceived 
"coolness level" of Erlang in some discriminating hackers community :), 
but apart from that I claim that it most will likely confuse the 
majority of programmers out there and give them more reasons to think 
that "Erlang is weird".

> Let's say the presence of the exported function bar() indicates that a certain feature is supported, and the function looks like this:
>
> test() ->
>     case erlang:function_exported(foo, bar, 0) of
>        true ->  foo:bar();
>        false ->  ok
>     end.
>
> Should the compiler still warn?

I would definitely say yes. I would even go as far as considering this a 
reason for the compiler to refuse to compile this code if this is part 
of the code of module foo. I see very little reason to place such code 
together with the *current* version of foo's code. If _really_ needed, 
one can place such code in some testing or code-updating module, which 
is compiled/analyzed separately/specially from the core of the application.

More generally, while it's true that "dynamic" languages have aspects 
and features that give quite a bit of freedom to the programmer, there 
is a fine line between using this freedom for good reason(s) and simply 
abusing it and ending up with code idioms that are difficult for tools 
and programmers to reason about. Calling future versions of the code of 
a module from the module itself is an idea which may seem "cool" the 
first five minutes you hear/think about it but I think is a feature that 
Erlang does not need in the long run.

Kostis

> (I'm open to the answer "yes". I don't think the above is a good solution).
>
> BR,
> Ulf W
>
> * It's of course easy if both versions of the module are available for analysis, but they seldom are in practice.
>
> On 17 Dec 2012, at 11:48, Kostis Sagonas wrote:
>
>> Shouldn't the compiler be complaining that the module below contains an undefined function?  (*)
>>
>> %%===================
>> -module(foo).
>> -export([test/0]).
>>
>> test() ->
>>   foo:bar().
>> %%===================
>>
>> Kostis
>>
>> (*) Or is this treated as a call to a "future" version of the module? :P
>> _______________________________________________
>> erlang-bugs mailing list
>> erlang-bugs@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-bugs
>
> Ulf Wiger, Co-founder&  Developer Advocate, Feuerlabs Inc.
> http://feuerlabs.com
>
>




More information about the erlang-bugs mailing list