undefined_lambda hack

Tony Rogvall tony@REDACTED
Fri Nov 13 16:00:06 CET 2009


I sat next to Björn Gustavsson yesterday at the EUC when Guy Wiener talked about Anonymity in Erlang.
A bit embarrassing that the module loading of functions has been left out all this time ;-)

Here is an attempt to temporarily fix this (by using hints from Björn). I am nearly 100% sure it will NOT handle
all of the cases. But it is a simple start. For some reason code:get_object_code(Module) will not work after
calling code:load_binary(Module,Filename,Binary). I guess it is a feature? Since there
is no file storage for it? The better solution includes some kind of module version handling, cache with ttl etc.

(R13B02-1 or later)

/Tony


In kernel/src/error_handler.erl replace undefined_lambda/3 with:

undefined_lambda(Module, Fun, Args) ->
    case ensure_loaded(Module) of
	{module, Module} ->
	    %% There is no need (and no way) to test if the fun is present.
	    %% apply/2 will not call us again if the fun is missing.
	    apply(Fun, Args);
	{module, _} ->
	    crash(Fun, Args);
	_Other ->
	    {pid,Pid} = erlang:fun_info(Fun,pid),
	    case try_load_remote_code(Pid,Module) of
		ok ->
		    case ensure_loaded(Module) of
			{module, Module} ->
			    apply(Fun, Args);
			_ ->
			    crash(Fun, Args)
		    end;
		_ ->
		    crash(Fun, Args)
	    end
    end.

%% add this function to error_handler.erl

try_load_remote_code(Pid,Module) ->
    if node() =:= node(Pid) ->
	    ok;  %% no need to load
       true ->
	    case rpc:call(node(Pid),code,get_object_code,[Module]) of
		{Module, Binary, Filename} ->
		    case code:load_binary(Module,Filename,Binary) of
			{module,Module} -> ok;
			_ -> error
		    end;
		error -> error
	    end
    end.





More information about the erlang-questions mailing list