aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src/code_server.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-09-05 16:16:23 +0200
committerBjörn Gustavsson <[email protected]>2016-09-14 12:54:54 +0200
commitc70ca686fe269db6079a2ca1c7e09cdfc0cfa903 (patch)
treefa9d97ff6a1f50a7532f4ebe38f70937bc035359 /lib/kernel/src/code_server.erl
parent176b7c94e4146a65ccd2bd729d58487098dddd9c (diff)
downloadotp-c70ca686fe269db6079a2ca1c7e09cdfc0cfa903.tar.gz
otp-c70ca686fe269db6079a2ca1c7e09cdfc0cfa903.tar.bz2
otp-c70ca686fe269db6079a2ca1c7e09cdfc0cfa903.zip
Don't leak old code when loading a modules with an on_load function
Normally, calling code:delete/1 before re-loading the code for a module is unnecessary but causes no problem. But there will be be problems if the new code has an on_load function. Code with an on_load function will always be loaded as old code to allowed it to be easily purged if the on_load function would fail. If the on_load function succeeds, the old and current code will be swapped. So in the scenario where code:delete/1 has been called explicitly, there is old code but no current code. Loading code with an on_load function will cause the reference to the old code to be overwritten. That will at best cause a memory leak, and at worst an emulator crash (especially if NIFs are involved). To avoid that situation, we will put the code with the on_load function in a special, third slot in Module. ERL-240
Diffstat (limited to 'lib/kernel/src/code_server.erl')
-rw-r--r--lib/kernel/src/code_server.erl3
1 files changed, 1 insertions, 2 deletions
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 48541ec500..38c1169308 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1382,11 +1382,10 @@ finish_on_load(PidRef, OnLoadRes, #state{on_load=OnLoad0}=St0) ->
finish_on_load_1(Mod, OnLoadRes, Waiting, St) ->
Keep = OnLoadRes =:= ok,
- erlang:finish_after_on_load(Mod, Keep),
+ erts_code_purger:finish_after_on_load(Mod, Keep),
Res = case Keep of
false ->
_ = finish_on_load_report(Mod, OnLoadRes),
- _ = erts_code_purger:purge(Mod),
{error,on_load_failure};
true ->
{module,Mod}