Wrong implementations of system_code_change/4 in gen_server and gen_fsm

Romain Lenglet rlenglet@REDACTED
Fri Jan 6 13:32:53 CET 2006


Implementations of system_code_change/4 in gen_server and gen_fsm 
always call code_change on the module implementing the 
behaviour, ignoring which module is upgraded.
This can lead to unexpected bugs.

For instance, the following code is accepted by gen_server (resp. 
by gen_fsm), although it is wrong:

{ok, Pid} = gen_server:start_link(ModA, [], []).
sys:change_code(Pid, ModB, OldVsn, Extra).

ModA:code_change/3 is called by gen_server:system_code_change/4 
although it is ModB that is upgraded. This is wrong.


I propose the following modification, to call the generic 
module's code_change/3 only if the module given to 
sys:change_code/4-5 is this module. It is sufficient to change 
the definition of gen_server:system_code_change/4 from:

system_code_change([Name, State, Mod, Time], _Module, OldVsn, 
Extra) ->
...

to:

system_code_change([Name, State, Mod, Time], Module, OldVsn, 
Extra) when Mod == Module ->
...

If the guard does not hold an exception is raised, which is 
catched by sys:change_code. Everything's safe.


I also propose a similar change in gen_fsm:

system_code_change([Name, StateName, StateData, Mod, Time],
                   _Module, OldVsn, Extra) ->

should become:

system_code_change([Name, StateName, StateData, Mod, Time],
                   Module, OldVsn, Extra) when Mod == Module ->



gen_event is already compliant with the semantics of 
sys:change_code/4 -5 and system_code_change/4.
Nothing to change here.

-- 
Romain LENGLET
Pr. Chiba Shigeru Group
Dept. of Mathematical and Computing Sciences
Tokyo Institute of Technology



More information about the erlang-bugs mailing list